diff --git a/esphome/components/modbus_controller/modbus_controller.h b/esphome/components/modbus_controller/modbus_controller.h index 6ed05715cb..fca2926568 100644 --- a/esphome/components/modbus_controller/modbus_controller.h +++ b/esphome/components/modbus_controller/modbus_controller.h @@ -271,24 +271,31 @@ class ServerRegister { // Formats a raw value into a string representation based on the value type for debugging std::string format_value(int64_t value) const { + // max 44: float with %.1f can be up to 42 chars (3.4e38 → 39 integer digits + sign + decimal + 1 digit) + // plus null terminator = 43, rounded to 44 for 4-byte alignment + char buf[44]; switch (this->value_type) { case SensorValueType::U_WORD: case SensorValueType::U_DWORD: case SensorValueType::U_DWORD_R: case SensorValueType::U_QWORD: case SensorValueType::U_QWORD_R: - return std::to_string(static_cast(value)); + buf_append_printf(buf, sizeof(buf), 0, "%" PRIu64, static_cast(value)); + return buf; case SensorValueType::S_WORD: case SensorValueType::S_DWORD: case SensorValueType::S_DWORD_R: case SensorValueType::S_QWORD: case SensorValueType::S_QWORD_R: - return std::to_string(value); + buf_append_printf(buf, sizeof(buf), 0, "%" PRId64, value); + return buf; case SensorValueType::FP32_R: case SensorValueType::FP32: - return str_sprintf("%.1f", bit_cast(static_cast(value))); + buf_append_printf(buf, sizeof(buf), 0, "%.1f", bit_cast(static_cast(value))); + return buf; default: - return std::to_string(value); + buf_append_printf(buf, sizeof(buf), 0, "%" PRId64, value); + return buf; } } diff --git a/esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp b/esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp index 89e86741b0..b26411b72e 100644 --- a/esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +++ b/esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp @@ -16,12 +16,20 @@ void ModbusTextSensor::parse_and_publish(const std::vector &data) { while ((items_left > 0) && index < data.size()) { uint8_t b = data[index]; switch (this->encode_) { - case RawEncoding::HEXBYTES: - output_str += str_snprintf("%02x", 2, b); + case RawEncoding::HEXBYTES: { + // max 3: 2 hex digits + null + char hex_buf[3]; + snprintf(hex_buf, sizeof(hex_buf), "%02x", b); + output_str += hex_buf; break; - case RawEncoding::COMMA: - output_str += str_sprintf(index != this->offset ? ",%d" : "%d", b); + } + case RawEncoding::COMMA: { + // max 5: optional ','(1) + uint8(3) + null, for both ",%d" and "%d" + char dec_buf[5]; + snprintf(dec_buf, sizeof(dec_buf), index != this->offset ? ",%d" : "%d", b); + output_str += dec_buf; break; + } case RawEncoding::ANSI: if (b < 0x20) break;