Skip to content

Commit f3c7b49

Browse files
committed
Fixes String(float) issue with Stack Smashing
1 parent 1c45987 commit f3c7b49

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

cores/esp32/WString.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,14 @@ String::String(unsigned long value, unsigned char base) {
114114

115115
String::String(float value, unsigned char decimalPlaces) {
116116
init();
117-
char buf[34];
118-
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
117+
char buf[64];
118+
*this = dtostrf(value, sizeof(buf) - 1, decimalPlaces, buf);
119119
}
120120

121121
String::String(double value, unsigned char decimalPlaces) {
122122
init();
123-
char buf[34];
124-
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
123+
char buf[64];
124+
*this = dtostrf(value, sizeof(buf) - 1, decimalPlaces, buf);
125125
}
126126

127127
String::~String() {

cores/esp32/stdlib_noniso.c

+30-19
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,36 @@ char* ultoa(unsigned long value, char* result, int base) {
9292
// This version is intended to be user proof
9393
// It avoids Stack Smashing issue, even for s = String(-234223.4f, 32) or String(0.0f, 100)
9494
char *dtostrf(double number, signed char width, unsigned char prec, char *s) {
95-
char fmt[34];
96-
// calculates how many characters the integer part of the float will take
97-
sprintf(fmt, "%32.0f", number);
98-
// finds the start of number ignoring the blanks
99-
char *start = fmt;
100-
while (*start == ' ') start++;
101-
unsigned char numSize = strlen(start), maxSize = sizeof(fmt) - 1;
102-
int maxPrec;
103-
104-
if (prec) numSize += 1; // for the '.'
105-
106-
// avoiding Stack smashing protect failure!
107-
if (width > maxSize) width = maxSize;
108-
maxPrec = maxSize - numSize;
109-
prec = maxPrec > 0 ? maxPrec : 0;
110-
111-
sprintf(fmt, "%%%d.%df", width, prec);
112-
sprintf(s, fmt, number);
113-
return s;
95+
char fmt[20]; // just for the formating in sprintf()
96+
uint8_t numSize = 0;
97+
int maxPrec;
98+
99+
if (isnan(number)) {
100+
strcpy(s, "nan");
101+
return s;
102+
}
103+
if (isinf(number)) {
104+
strcpy(s, "inf");
105+
return s;
106+
}
107+
108+
// calculates how many characters the integer part of the float will take
109+
if (number < 0) { // number is negative
110+
numSize = 1; // for the '-' simbol
111+
}
112+
double n = fabs(number);
113+
do {
114+
numSize++;
115+
n = n / 10;
116+
} while (n > 1);
117+
if (prec) numSize += 1; // for the '.'
118+
// avoiding Stack smashing protect failure!
119+
maxPrec = width - numSize;
120+
if (prec) prec = maxPrec > 0 ? maxPrec : 0;
121+
122+
sprintf(fmt, "%%%d.%df", numSize, prec);
123+
sprintf(s, fmt, number);
124+
return s;
114125
}
115126
#else
116127
// orginal code from Arduino ESP8266

0 commit comments

Comments
 (0)