-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Stack smash with String(float, precision) #5873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@MitchBradley What Arduino core are you using (1.0.6, 2.0.0 or 2.0.1)? Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
Serial.printf("ChipRevision %d, Cpu Freq %d, SDK Version %s\n", ESP.getChipRevision(), ESP.getCpuFreqMHz(), ESP.getSdkVersion());
Serial.printf("Flash Size %d, Flash Speed %d\n", ESP.getFlashChipSize(), ESP.getFlashChipSpeed());
|
I have tried it with numerous setups - Arduino IDE, with Arduino core 1.0.6 and 2.0.1, and PlatformIO with framework-arduinoespressif32 version 3.10006.210326 and also a pull from git as of about a month ago. git blame says that the code in question - the 33-character buffer - has not changed since it was imported from the esp8266 version 5 years ago. That suggests that the bug might be in the 8266 version too. Yes, same bug here Here are two of the many environments I have tried: Arduino IDE 1.8.13 + Arduino core 1.0.6
Arduino IDE 1.8.13 + Arduino ESP32 core 2.0.1
Here is the sketch:
The delay(10000); slows down the reboot loop so the output can be captured. |
@MitchBradley |
Passing a large floating point value, or a large precision, to String::String(float value, unsigned char decimalPlaces) causes a stack smash.
Any one of these lines, individually, in any context, will do it:
The problem is in WString.cpp which uses a buffer of length 33
char buf[33]
Since FLT_MAX is 3.4e38, 33 bytes is not enough. Furthermore, there is no limit on the precision value that can be passed through to dtostrf(), so you can crash it either with large floating point values or large precision numbers.To fix it without going into dtostrf(), you would have to both increase the buffer size to around 80 - accounting for possible minus sign, decimal point, 39 predecimal digits, 38 postdecimal digits, and null terminator, and also limit the number of decimal places to 38.
The problem is even worse with the version of String whose argument is double; there the buffer size would need to be about 620.
The text was updated successfully, but these errors were encountered: