time: Make std::string version of strftime() avoid runaway memory allocations (#5348)

This commit is contained in:
Kevin P. Fleming 2023-09-11 16:02:07 -04:00 committed by GitHub
parent 892d2ce34f
commit deb34c9473
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 0 deletions

View file

@ -49,6 +49,11 @@ std::string ESPTime::strftime(const std::string &format) {
struct tm c_tm = this->to_c_tm(); struct tm c_tm = this->to_c_tm();
size_t len = ::strftime(&timestr[0], timestr.size(), format.c_str(), &c_tm); size_t len = ::strftime(&timestr[0], timestr.size(), format.c_str(), &c_tm);
while (len == 0) { while (len == 0) {
if (timestr.size() >= 128) {
// strftime has failed for reasons unrelated to the size of the buffer
// so return a formatting error
return "ERROR";
}
timestr.resize(timestr.size() * 2); timestr.resize(timestr.size() * 2);
len = ::strftime(&timestr[0], timestr.size(), format.c_str(), &c_tm); len = ::strftime(&timestr[0], timestr.size(), format.c_str(), &c_tm);
} }

View file

@ -45,6 +45,10 @@ struct ESPTime {
* *
* @warning This method uses dynamically allocated strings which can cause heap fragmentation with some * @warning This method uses dynamically allocated strings which can cause heap fragmentation with some
* microcontrollers. * microcontrollers.
*
* @warning This method can return "ERROR" when the underlying strftime() call fails, e.g. when the
* format string contains unsupported specifiers or when the format string doesn't produce any
* output.
*/ */
std::string strftime(const std::string &format); std::string strftime(const std::string &format);