Closed
Description
It seems to me that Print.printf(fmt, ...) is allocating a local buffer but never actually uses it, always running vsnprintf() twice. A buffer of size 64 is allocated but then vsnprintf is called with (NULL, 0, ...) parameters just to calculate the length. Then it always allocates a new buffer to vsnprintf into. I've modified the code in such a way that loc_buf[64] is used at first and if it proofs insufficient, only then allocate another. I think this was the original idea.
Also: vsnprintf() returns int, and negative int for an error. I guess this may wreck havoc in various ways when that gets assigned to size_t (uint) and becomes some (large) positive number.
Have a look at this diff for the problem and the fix:
diff --git a/cores/esp32/Print.cpp b/cores/esp32/Print.cpp
index 8c29534..57d725f 100644
--- a/cores/esp32/Print.cpp
+++ b/cores/esp32/Print.cpp
@@ -52,15 +52,19 @@ size_t Print::printf(const char *format, ...)
va_list copy;
va_start(arg, format);
va_copy(copy, arg);
- size_t len = vsnprintf(NULL, 0, format, copy);
+ int len = vsnprintf(temp, sizeof(loc_buf), format, copy);
va_end(copy);
+ if(len < 0) {
+ va_end(arg);
+ return 0;
+ };
if(len >= sizeof(loc_buf)){
temp = new char[len+1];
if(temp == NULL) {
return 0;
}
+ len = vsnprintf(temp, len+1, format, arg);
}
- len = vsnprintf(temp, len+1, format, arg);
write((uint8_t*)temp, len);
va_end(arg);
if(len >= sizeof(loc_buf)){