mirror of
https://github.com/esphome/esphome.git
synced 2026-02-18 15:35:59 -07:00
enforce buffer size safety at compile time
This commit is contained in:
@@ -28,8 +28,8 @@ class SunTextSensor : public text_sensor::TextSensor, public PollingComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[128];
|
||||
size_t len = res->strftime(buf, sizeof(buf), this->format_.c_str());
|
||||
char buf[ESPTime::STRFTIME_BUFFER_SIZE];
|
||||
size_t len = res->strftime_to(buf, this->format_.c_str());
|
||||
if (len > 0) {
|
||||
this->publish_state(buf, len);
|
||||
} else {
|
||||
|
||||
@@ -17,6 +17,11 @@ size_t ESPTime::strftime(char *buffer, size_t buffer_len, const char *format) {
|
||||
return ::strftime(buffer, buffer_len, format, &c_tm);
|
||||
}
|
||||
|
||||
size_t ESPTime::strftime_to(std::span<char, STRFTIME_BUFFER_SIZE> buffer, const char *format) {
|
||||
struct tm c_tm = this->to_c_tm();
|
||||
return ::strftime(buffer.data(), buffer.size(), format, &c_tm);
|
||||
}
|
||||
|
||||
ESPTime ESPTime::from_c_tm(struct tm *c_tm, time_t c_time) {
|
||||
ESPTime res{};
|
||||
res.second = uint8_t(c_tm->tm_sec);
|
||||
@@ -47,9 +52,8 @@ struct tm ESPTime::to_c_tm() {
|
||||
}
|
||||
|
||||
std::string ESPTime::strftime(const char *format) {
|
||||
struct tm c_tm = this->to_c_tm();
|
||||
char buf[128];
|
||||
size_t len = ::strftime(buf, sizeof(buf), format, &c_tm);
|
||||
char buf[STRFTIME_BUFFER_SIZE];
|
||||
size_t len = this->strftime_to(buf, format);
|
||||
if (len > 0) {
|
||||
return std::string(buf, len);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <span>
|
||||
#include <string>
|
||||
|
||||
namespace esphome {
|
||||
@@ -13,6 +14,9 @@ uint8_t days_in_month(uint8_t month, uint16_t year);
|
||||
|
||||
/// A more user-friendly version of struct tm from time.h
|
||||
struct ESPTime {
|
||||
/// Buffer size required for strftime output
|
||||
static constexpr size_t STRFTIME_BUFFER_SIZE = 128;
|
||||
|
||||
/** seconds after the minute [0-60]
|
||||
* @note second is generally 0-59; the extra range is to accommodate leap seconds.
|
||||
*/
|
||||
@@ -43,14 +47,21 @@ struct ESPTime {
|
||||
*/
|
||||
size_t strftime(char *buffer, size_t buffer_len, const char *format);
|
||||
|
||||
/** Format time into a fixed-size buffer, returns length written (0 on error).
|
||||
*
|
||||
* This is the preferred method for avoiding heap allocations. The buffer size is enforced at compile-time.
|
||||
* @see https://www.gnu.org/software/libc/manual/html_node/Formatting-Calendar-Time.html#index-strftime
|
||||
*/
|
||||
size_t strftime_to(std::span<char, STRFTIME_BUFFER_SIZE> buffer, const char *format);
|
||||
|
||||
/** Convert this ESPTime struct to a string as specified by the format argument.
|
||||
* @see https://en.cppreference.com/w/c/chrono/strftime
|
||||
*
|
||||
* @warning This method returns a dynamically allocated string which can cause heap fragmentation with some
|
||||
* microcontrollers.
|
||||
* microcontrollers. Prefer strftime_to() for heap-free formatting.
|
||||
*
|
||||
* @warning This method can return "ERROR" when the underlying strftime() call fails or when the
|
||||
* output exceeds 128 bytes.
|
||||
* output exceeds STRFTIME_BUFFER_SIZE bytes.
|
||||
*/
|
||||
std::string strftime(const std::string &format);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user