Skip to content

Commit c497770

Browse files
committed
[Bugfix] Fix possible crash when printing floating point values
As implemented for ESP32, but not (yet) for ESP8266. See: espressif/arduino-esp32#6138
1 parent 46f2d20 commit c497770

34 files changed

+120
-77
lines changed

src/_C018.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String&
677677
addHtml(C018_data->sysver());
678678

679679
addRowLabel(F("Voltage"));
680-
addHtml(String(static_cast<float>(C018_data->getVbat()) / 1000.0f, 3));
680+
addHtml(toString(static_cast<float>(C018_data->getVbat()) / 1000.0f, 3));
681681

682682
addRowLabel(F("Dev Addr"));
683683
addHtml(C018_data->getDevaddr());
@@ -942,7 +942,7 @@ bool do_process_c018_delay_queue(int controller_number, const C018_queue_element
942942
String log = F("LoRaWAN : Payload Length: ");
943943
log += pl + 13; // We have a LoRaWAN header of 13 bytes.
944944
log += F(" Air Time: ");
945-
log += String(airtime_ms, 3);
945+
log += toString(airtime_ms, 3);
946946
log += F(" ms");
947947
addLog(LOG_LEVEL_INFO, log);
948948
}

src/_P002_ADC.ino

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@ boolean Plugin_002(uint8_t function, struct EventStruct *event, String& string)
142142

143143
addFormNumericBox(F("Point 1"), F("p002_adc1"), P002_CALIBRATION_POINT1, 0, P002_MAX_ADC_VALUE);
144144
html_add_estimate_symbol();
145-
addTextBox(F("p002_out1"), String(P002_CALIBRATION_VALUE1, 3), 10);
145+
addTextBox(F("p002_out1"), toString(P002_CALIBRATION_VALUE1, 3), 10);
146146

147147
addFormNumericBox(F("Point 2"), F("p002_adc2"), P002_CALIBRATION_POINT2, 0, P002_MAX_ADC_VALUE);
148148
html_add_estimate_symbol();
149-
addTextBox(F("p002_out2"), String(P002_CALIBRATION_VALUE2, 3), 10);
149+
addTextBox(F("p002_out2"), toString(P002_CALIBRATION_VALUE2, 3), 10);
150150

151151
{
152152
// Output the statistics for the current settings.
@@ -302,7 +302,7 @@ void P002_formatStatistics(const __FlashStringHelper * label, int raw, float flo
302302
addRowLabel(label);
303303
addHtmlInt(raw);
304304
html_add_estimate_symbol();
305-
addHtml(String(float_value, 3));
305+
addHtml(toString(float_value, 3));
306306
}
307307

308308
#endif // USES_P002

src/_P021_Level.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ boolean Plugin_021(uint8_t function, struct EventStruct *event, String& string)
7676
addRowLabel(F("Check Value"));
7777
addTaskValueSelect(F("p021_value"), PCONFIG(1), PCONFIG(0));
7878

79-
addFormTextBox(F("Set Level"), F("p021_setvalue"), String(PCONFIG_FLOAT(0)), 8);
79+
addFormTextBox(F("Set Level"), F("p021_setvalue"), toString(PCONFIG_FLOAT(0)), 8);
8080

81-
addFormTextBox(F("Hysteresis"), F("p021_hyst"), String(PCONFIG_FLOAT(1)), 8);
81+
addFormTextBox(F("Hysteresis"), F("p021_hyst"), toString(PCONFIG_FLOAT(1)), 8);
8282

8383
addFormCheckBox(F("Save 'Set Level' after change via <tt>config</tt> command"), F("p021_save_always"), PCONFIG(2) == 0); // inverted
8484
// flag!

src/_P025_ADS1115.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ boolean Plugin_025(uint8_t function, struct EventStruct *event, String& string)
112112

113113
addFormNumericBox(F("Point 1"), F("p025_adc1"), PCONFIG_LONG(0), -32768, 32767);
114114
html_add_estimate_symbol();
115-
addTextBox(F("p025_out1"), String(PCONFIG_FLOAT(0), 3), 10);
115+
addTextBox(F("p025_out1"), toString(PCONFIG_FLOAT(0), 3), 10);
116116

117117
addFormNumericBox(F("Point 2"), F("p025_adc2"), PCONFIG_LONG(1), -32768, 32767);
118118
html_add_estimate_symbol();
119-
addTextBox(F("p025_out2"), String(PCONFIG_FLOAT(1), 3), 10);
119+
addTextBox(F("p025_out2"), toString(PCONFIG_FLOAT(1), 3), 10);
120120

121121
success = true;
122122
break;

src/_P050_TCS34725.ino

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,11 @@ boolean Plugin_050(uint8_t function, struct EventStruct *event, String& string)
408408
nb = static_cast<float>(b) / t * sRGBFactor;
409409
P050_data->applyTransformation(nr, ng, nb, &tr, &tg, &tb);
410410
}
411-
RuleEvent += String(tr, 4);
411+
RuleEvent += toString(tr, 4);
412412
RuleEvent += ',';
413-
RuleEvent += String(tg, 4);
413+
RuleEvent += toString(tg, 4);
414414
RuleEvent += ',';
415-
RuleEvent += String(tb, 4);
415+
RuleEvent += toString(tb, 4);
416416
break;
417417
case 2:
418418
sRGBFactor = 255.0f;
@@ -423,11 +423,11 @@ boolean Plugin_050(uint8_t function, struct EventStruct *event, String& string)
423423
} else {
424424
RuleEvent += F("NormSRGB=");
425425
}
426-
RuleEvent += String(static_cast<float>(r) / t * sRGBFactor, 4);
426+
RuleEvent += toString(static_cast<float>(r) / t * sRGBFactor, 4);
427427
RuleEvent += ',';
428-
RuleEvent += String(static_cast<float>(g) / t * sRGBFactor, 4);
428+
RuleEvent += toString(static_cast<float>(g) / t * sRGBFactor, 4);
429429
RuleEvent += ',';
430-
RuleEvent += String(static_cast<float>(b) / t * sRGBFactor, 4);
430+
RuleEvent += toString(static_cast<float>(b) / t * sRGBFactor, 4);
431431
break;
432432
default:
433433
RuleEvent = EMPTY_STRING;

src/_P060_MCP3221.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ boolean Plugin_060(uint8_t function, struct EventStruct *event, String& string)
7373

7474
addFormNumericBox(F("Point 1"), F("p060_adc1"), PCONFIG_LONG(0), 0, 4095);
7575
html_add_estimate_symbol();
76-
addTextBox(F("p060_out1"), String(PCONFIG_FLOAT(0), 3), 10);
76+
addTextBox(F("p060_out1"), toString(PCONFIG_FLOAT(0), 3), 10);
7777

7878
addFormNumericBox(F("Point 2"), F("p060_adc2"), PCONFIG_LONG(1), 0, 4095);
7979
html_add_estimate_symbol();
80-
addTextBox(F("p060_out2"), String(PCONFIG_FLOAT(1), 3), 10);
80+
addTextBox(F("p060_out2"), toString(PCONFIG_FLOAT(1), 3), 10);
8181

8282
success = true;
8383
break;

src/_P067_HX711_Load_Cell.ino

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ boolean Plugin_067(uint8_t function, struct EventStruct *event, String& string)
197197
}
198198

199199
int2float(PCONFIG(1), PCONFIG(2), &valFloat);
200-
addFormTextBox(F("Offset"), F("p067_offset_chanA"), String(valFloat, 3), 25);
200+
addFormTextBox(F("Offset"), F("p067_offset_chanA"), toString(valFloat, 3), 25);
201201
addHtml(F(" &nbsp; &nbsp; &#8617; Tare: "));
202202
addCheckBox(F("tareChanA"), 0); //always off
203203

@@ -212,7 +212,7 @@ boolean Plugin_067(uint8_t function, struct EventStruct *event, String& string)
212212
}
213213

214214
int2float(PCONFIG(3), PCONFIG(4), &valFloat);
215-
addFormTextBox(F("Offset"), F("p067_offset_chanB"), String(valFloat, 3), 25);
215+
addFormTextBox(F("Offset"), F("p067_offset_chanB"), toString(valFloat, 3), 25);
216216
addHtml(F(" &nbsp; &nbsp; &#8617; Tare: "));
217217
addCheckBox(F("tareChanB"), 0); //always off
218218

@@ -222,11 +222,11 @@ boolean Plugin_067(uint8_t function, struct EventStruct *event, String& string)
222222

223223
addFormNumericBox(F("Point 1"), F("p067_adc1_chanA"), PCONFIG_LONG(0));
224224
html_add_estimate_symbol();
225-
addTextBox(F("p067_out1_chanA"), String(PCONFIG_FLOAT(0), 3), 10);
225+
addTextBox(F("p067_out1_chanA"), toString(PCONFIG_FLOAT(0), 3), 10);
226226

227227
addFormNumericBox(F("Point 2"), F("p067_adc2_chanA"), PCONFIG_LONG(1));
228228
html_add_estimate_symbol();
229-
addTextBox(F("p067_out2_chanA"), String(PCONFIG_FLOAT(1), 3), 10);
229+
addTextBox(F("p067_out2_chanA"), toString(PCONFIG_FLOAT(1), 3), 10);
230230

231231
//------------
232232
addFormSubHeader(F("Two Point Calibration Channel B"));
@@ -235,11 +235,11 @@ boolean Plugin_067(uint8_t function, struct EventStruct *event, String& string)
235235

236236
addFormNumericBox(F("Point 1"), F("p067_adc1_chanB"), PCONFIG_LONG(2));
237237
html_add_estimate_symbol();
238-
addTextBox(F("p067_out1_chanB"), String(PCONFIG_FLOAT(2), 3), 10);
238+
addTextBox(F("p067_out1_chanB"), toString(PCONFIG_FLOAT(2), 3), 10);
239239

240240
addFormNumericBox(F("Point 2"), F("p067_adc2_chanB"), PCONFIG_LONG(3));
241241
html_add_estimate_symbol();
242-
addTextBox(F("p067_out2_chanB"), String(PCONFIG_FLOAT(3), 3), 10);
242+
addTextBox(F("p067_out2_chanB"), toString(PCONFIG_FLOAT(3), 3), 10);
243243

244244
success = true;
245245
break;

src/_P073_7DGT.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,7 @@ bool p073_plugin_write_7dn(struct EventStruct *event, const String& text) {
11391139
switch (P073_data->displayModel) {
11401140
case P073_TM1637_4DGTCOLON: {
11411141
if ((event->Par1 > -1000) && (event->Par1 < 10000)) {
1142+
// FIXME TD-er: Why call round on an int?
11421143
P073_data->FillBufferWithNumber(String(round(event->Par1)));
11431144
}
11441145
else {

src/_P074_TSL2591.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ boolean Plugin_074(uint8_t function, struct EventStruct *event, String& string)
270270

271271
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
272272
String log = F("TSL2591: Lux: ");
273-
log += String(lux);
273+
log += toString(lux);
274274
log += F(" Full: ");
275275
log += String(full);
276276
log += F(" Visible: ");

src/_P076_HLW8012.ino

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,11 @@ boolean Plugin_076(uint8_t function, struct EventStruct *event, String &string)
217217
if (Plugin076_LoadMultipliers(event->TaskIndex, current, voltage, power)) {
218218
addFormSubHeader(F("Calibration Values"));
219219
addFormTextBox(F("Current Multiplier"), F("p076_currmult"),
220-
String(current, 2), 25);
220+
doubleToString(current, 2), 25);
221221
addFormTextBox(F("Voltage Multiplier"), F("p076_voltmult"),
222-
String(voltage, 2), 25);
222+
doubleToString(voltage, 2), 25);
223223
addFormTextBox(F("Power Multiplier"), F("p076_powmult"),
224-
String(power, 2), 25);
224+
doubleToString(power, 2), 25);
225225
}
226226

227227
success = true;

src/_P082_GPS.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ void P082_html_show_stats(struct EventStruct *event) {
677677
P082_html_show_satStats(event, false, false);
678678

679679
addRowLabel(F("HDOP"));
680-
addHtml(String(P082_data->gps->hdop.value() / 100.0f));
680+
addHtml(toString(P082_data->gps->hdop.value() / 100.0f));
681681

682682
addRowLabel(F("UTC Time"));
683683
struct tm dateTime;

src/_P090_CCS811.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ boolean Plugin_090(uint8_t function, struct EventStruct *event, String& string)
305305

306306
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
307307
String log = F("CCS811 : Compensating for Temperature: ");
308-
log += String(temperature) + temp + F(" & Humidity: ") + String(humidity) + F("%");
308+
log += toString(temperature) + temp + F(" & Humidity: ") + toString(humidity) + F("%");
309309
addLog(LOG_LEVEL_DEBUG, log);
310310
}
311311
#endif // ifndef BUILD_NO_DEBUG

src/_P096_eInk.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ boolean Plugin_096(uint8_t function, struct EventStruct *event, String& string)
370370

371371
#ifndef BUILD_NO_DEBUG
372372
s.add(usecPassedSince(statisticsTimerStart));
373-
tmpString += "<br/> Display timings = " + String(s.getAvg());
373+
tmpString += "<br/> Display timings = " + toString(s.getAvg());
374374
#endif
375375
P096_data->eInkScreen.clearBuffer();
376376
P096_data->plugin_096_sequence_in_progress = false;

src/_P103_Atlas_EZO_pH_ORP_EC_DO.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ boolean Plugin_103(uint8_t function, struct EventStruct *event, String &string)
190190
addUnit(F("V"));
191191

192192
addRowLabel(F("Sensor Data"));
193-
addHtml(String(UserVar[event->BaseVarIndex]));
193+
addHtml(toString(UserVar[event->BaseVarIndex]));
194194
switch (board_type)
195195
{
196196
case PH:

src/_P109_ThermOLED.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,9 +340,9 @@ boolean Plugin_109(byte function, struct EventStruct *event, String& string)
340340
}
341341

342342
logstr = F("Thermo : Starting status S:");
343-
logstr += String(UserVar[event->BaseVarIndex]);
343+
logstr += toString(UserVar[event->BaseVarIndex]);
344344
logstr += F(", R:");
345-
logstr += String(UserVar[event->BaseVarIndex + 1]);
345+
logstr += toString(UserVar[event->BaseVarIndex + 1]);
346346
addLog(LOG_LEVEL_INFO, logstr);
347347

348348
Plugin_109_changed = 1;

src/_P112_AS7265x.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ void queueEvent(taskIndex_t TaskIndex, int wavelength, float value) {
423423
RuleEvent += '#';
424424
RuleEvent += wavelength;
425425
RuleEvent += '=';
426-
RuleEvent += String(value, 2);
426+
RuleEvent += toString(value, 2);
427427
eventQueue.add(RuleEvent);
428428
}
429429

src/_P117_SCD30.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ boolean Plugin_117(uint8_t function, struct EventStruct *event, String& string)
9191
{
9292
addFormNumericBox(F("Altitude"), F("plugin_117_SCD30_alt"), PCONFIG(0), 0, 2000);
9393
addUnit(F("0..2000 m"));
94-
addFormTextBox(F("Temp offset"), F("plugin_117_SCD30_tmp"), String(PCONFIG_FLOAT(0), 2), 5);
94+
addFormTextBox(F("Temp offset"), F("plugin_117_SCD30_tmp"), toString(PCONFIG_FLOAT(0), 2), 5);
9595
addUnit(F("&deg;C"));
9696
success = true;
9797
break;
@@ -185,7 +185,7 @@ boolean Plugin_117(uint8_t function, struct EventStruct *event, String& string)
185185
{
186186
P117_data->getTemperatureOffset(&temp);
187187
log += F("Temp offset: ");
188-
log += String(temp, 2);
188+
log += toString(temp, 2);
189189
success = true;
190190
}
191191

src/src/Commands/Tasks.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const __FlashStringHelper * taskValueSet(struct EventStruct *event, const char *
101101
UserVar[uservarIndex] = result;
102102
} else {
103103
// TODO: Get Task description and var name
104-
serialPrintln(String(UserVar[uservarIndex]));
104+
serialPrintln(toString(UserVar[uservarIndex]));
105105
}
106106
success = true;
107107
return return_command_success();

src/src/DataStructs/Web_StreamingBuffer.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "../Globals/Services.h"
1010

1111
#include "../Helpers/ESPEasy_time_calc.h"
12+
#include "../Helpers/Convert.h"
1213

1314

1415
#ifdef ESP8266
@@ -43,12 +44,16 @@ Web_StreamingBuffer& Web_StreamingBuffer::operator+=(char a) {
4344
return addString(String(a));
4445
}
4546

46-
Web_StreamingBuffer& Web_StreamingBuffer::operator+=(long unsigned int a) {
47+
Web_StreamingBuffer& Web_StreamingBuffer::operator+=(long unsigned int a) {
4748
return addString(String(a));
4849
}
4950

50-
Web_StreamingBuffer& Web_StreamingBuffer::operator+=(float a) {
51-
return addString(String(a));
51+
Web_StreamingBuffer& Web_StreamingBuffer::operator+=(const float& a) {
52+
return addString(toString(a, 2));
53+
}
54+
55+
Web_StreamingBuffer& Web_StreamingBuffer::operator+=(const double& a) {
56+
return addString(doubleToString(a));
5257
}
5358

5459
Web_StreamingBuffer& Web_StreamingBuffer::operator+=(int a) {

src/src/DataStructs/Web_StreamingBuffer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class Web_StreamingBuffer {
3939
// Web_StreamingBuffer& operator=(const String& a);
4040
Web_StreamingBuffer& operator+=(char a);
4141
Web_StreamingBuffer& operator+=(long unsigned int a);
42-
Web_StreamingBuffer& operator+=(float a);
42+
Web_StreamingBuffer& operator+=(const float& a);
43+
Web_StreamingBuffer& operator+=(const double& a);
4344
Web_StreamingBuffer& operator+=(int a);
4445
Web_StreamingBuffer& operator+=(uint32_t a);
4546
Web_StreamingBuffer& operator+=(const String& a);

src/src/ESPEasyCore/ESPEasyWifi.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -677,14 +677,14 @@ void SetWiFiTXpower(float dBm, float rssi) {
677677
if (TX_pwr_int != last_log) {
678678
last_log = TX_pwr_int;
679679
String log = F("WiFi : Set TX power to ");
680-
log += String(dBm, 0);
680+
log += toString(dBm, 0);
681681
log += F("dBm");
682682
log += F(" sensitivity: ");
683-
log += String(threshold, 0);
683+
log += toString(threshold, 0);
684684
log += F("dBm");
685685
if (rssi < 0) {
686686
log += F(" RSSI: ");
687-
log += String(rssi, 0);
687+
log += toString(rssi, 0);
688688
log += F("dBm");
689689
}
690690
addLog(LOG_LEVEL_DEBUG, log);

src/src/Helpers/Convert.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,17 +234,48 @@ float ul2float(unsigned long ul)
234234
/*********************************************************************************************\
235235
Workaround for removing trailing white space when String() converts a float with 0 decimals
236236
\*********************************************************************************************/
237-
String toString(const float& value, uint8_t decimals)
237+
String toString(const float& value, unsigned int decimalPlaces)
238238
{
239-
String sValue = String(value, decimals);
239+
// This has been fixed in ESP32 code, not (yet) in ESP8266 code
240+
// https://github.com/espressif/arduino-esp32/pull/6138/files
241+
// #ifdef ESP8266
242+
char *buf = (char*)malloc(decimalPlaces + 42);
243+
if (nullptr == buf) {
244+
return F("nan");
245+
}
246+
String sValue(dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf));
247+
free(buf);
248+
// #else
249+
// String sValue = String(value, decimalPlaces);
250+
// #endif
240251

241252
sValue.trim();
242253
return sValue;
243254
}
244255

245-
String doubleToString(const double& value, int decimals, bool trimTrailingZeros) {
246-
String res(value, decimals);
256+
String doubleToString(const double& value, unsigned int decimalPlaces, bool trimTrailingZeros) {
257+
// This has been fixed in ESP32 code, not (yet) in ESP8266 code
258+
// https://github.com/espressif/arduino-esp32/pull/6138/files
259+
// #ifdef ESP8266
260+
unsigned int expectedChars = decimalPlaces + 4; // 1 dot, 2 minus signs and terminating zero
261+
if (value > 1e32 || value < -1e32) {
262+
expectedChars += 308; // Just assume the worst
263+
} else {
264+
expectedChars += 33;
265+
}
266+
char *buf = (char*)malloc(expectedChars);
267+
268+
if (nullptr == buf) {
269+
return F("nan");
270+
}
271+
String res(dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf));
272+
free(buf);
273+
274+
// #else
275+
// String res(value, decimalPlaces);
276+
// #endif
247277
res.trim();
278+
248279
if (trimTrailingZeros) {
249280
int dot_pos = res.lastIndexOf('.');
250281
if (dot_pos != -1) {

src/src/Helpers/Convert.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ float ul2float(unsigned long ul);
6565
/*********************************************************************************************\
6666
Workaround for removing trailing white space when String() converts a float with 0 decimals
6767
\*********************************************************************************************/
68-
String toString(const float& value, uint8_t decimals);
68+
String toString(const float& value, unsigned int decimalPlaces = 2);
6969

70-
String doubleToString(const double& value, int decimals = 2, bool trimTrailingZeros = false);
70+
String doubleToString(const double& value, unsigned int decimalPlaces = 2, bool trimTrailingZeros = false);
7171

7272

7373
#endif // HELPERS_CONVERT_H

0 commit comments

Comments
 (0)