Skip to content
Snippets Groups Projects
Commit cea6cf8a authored by Damien George's avatar Damien George
Browse files

py/formatfloat: Fix buffer overflow when formatting tiny numbers.

parent 0d1f8868
Branches
No related tags found
No related merge requests found
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "py/mpconfig.h" #include "py/mpconfig.h"
#if MICROPY_FLOAT_IMPL != MICROPY_FLOAT_IMPL_NONE #if MICROPY_FLOAT_IMPL != MICROPY_FLOAT_IMPL_NONE
#include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include "py/formatfloat.h" #include "py/formatfloat.h"
...@@ -210,13 +211,15 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch ...@@ -210,13 +211,15 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
dec = -1; dec = -1;
*s++ = first_dig; *s++ = first_dig;
if (prec + e + 1 > buf_remaining) {
prec = buf_remaining - e - 1;
}
if (org_fmt == 'g') { if (org_fmt == 'g') {
prec += (e - 1); prec += (e - 1);
} }
// truncate precision to prevent buffer overflow
if (prec + 2 > buf_remaining) {
prec = buf_remaining - 2;
}
num_digits = prec; num_digits = prec;
if (num_digits) { if (num_digits) {
*s++ = '.'; *s++ = '.';
...@@ -390,6 +393,9 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch ...@@ -390,6 +393,9 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
} }
*s = '\0'; *s = '\0';
// verify that we did not overrun the input buffer
assert((size_t)(s + 1 - buf) <= buf_size);
return s - buf; return s - buf;
} }
......
...@@ -26,3 +26,19 @@ print("%02.3d" % 123) # prec > width ...@@ -26,3 +26,19 @@ print("%02.3d" % 123) # prec > width
print("%+f %+f" % (1.23, -1.23)) # float sign print("%+f %+f" % (1.23, -1.23)) # float sign
print("% f % f" % (1.23, -1.23)) # float space sign print("% f % f" % (1.23, -1.23)) # float space sign
print("%0f" % -1.23) # negative number with 0 padding print("%0f" % -1.23) # negative number with 0 padding
# numbers with large negative exponents
print('%f' % 1e-10)
print('%f' % 1e-20)
print('%f' % 1e-50)
print('%f' % 1e-100)
print('%f' % 1e-300)
# large decimal precision should be truncated and not overflow buffer
# the output depends on the FP calculation so only first 2 digits are printed
# (the 'g' with small e are printed using 'f' style, so need to be checked)
print(('%.40f' % 1e-300)[:2])
print(('%.40g' % 1e-1)[:2])
print(('%.40g' % 1e-2)[:2])
print(('%.40g' % 1e-3)[:2])
print(('%.40g' % 1e-4)[:2])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment