From deb34c947314b27c9db4f49cd8771fa5c76eaf00 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Mon, 11 Sep 2023 16:02:07 -0400 Subject: [PATCH] time: Make std::string version of strftime() avoid runaway memory allocations (#5348) --- esphome/core/time.cpp | 5 +++++ esphome/core/time.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/esphome/core/time.cpp b/esphome/core/time.cpp index bc5bfa173e..751b2a2703 100644 --- a/esphome/core/time.cpp +++ b/esphome/core/time.cpp @@ -49,6 +49,11 @@ std::string ESPTime::strftime(const std::string &format) { struct tm c_tm = this->to_c_tm(); size_t len = ::strftime(×tr[0], timestr.size(), format.c_str(), &c_tm); 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); len = ::strftime(×tr[0], timestr.size(), format.c_str(), &c_tm); } diff --git a/esphome/core/time.h b/esphome/core/time.h index e16e449f0b..14c36311e0 100644 --- a/esphome/core/time.h +++ b/esphome/core/time.h @@ -45,6 +45,10 @@ struct ESPTime { * * @warning This method uses dynamically allocated strings which can cause heap fragmentation with some * 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);