diff options
author | Marc-André Lemburg <mal@egenix.com> | 2002-12-29 19:44:06 (GMT) |
---|---|---|
committer | Marc-André Lemburg <mal@egenix.com> | 2002-12-29 19:44:06 (GMT) |
commit | 79f57833f3df0d2f3dd08639f436113286ee6067 (patch) | |
tree | 7dca4ea91edb396d86a857d0a5d65030284e1bb2 /Objects | |
parent | bbfb91041634d11c73046775f62a1c44bc729bc3 (diff) | |
download | cpython-79f57833f3df0d2f3dd08639f436113286ee6067.zip cpython-79f57833f3df0d2f3dd08639f436113286ee6067.tar.gz cpython-79f57833f3df0d2f3dd08639f436113286ee6067.tar.bz2 |
Patch for bug #659709: bogus computation of float length
Python 2.2.x backport candidate. (This bug has been around since
Python 1.6.)
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/stringobject.c | 22 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 31 |
2 files changed, 37 insertions, 16 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 1e42856..748592e 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -3361,21 +3361,31 @@ formatfloat(char *buf, size_t buflen, int flags, prec = 6; if (type == 'f' && fabs(x)/1e25 >= 1e25) type = 'g'; - PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", - (flags&F_ALT) ? "#" : "", - prec, type); - /* worst case length calc to ensure no buffer overrun: + /* Worst case length calc to ensure no buffer overrun: + + 'g' formats: fmt = %#.<prec>g buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp for any double rep.) len = 1 + prec + 1 + 2 + 5 = 9 + prec + + 'f' formats: + buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) + len = 1 + 50 + 1 + prec = 52 + prec + If prec=0 the effective precision is 1 (the leading digit is - always given), therefore increase by one to 10+prec. */ - if (buflen <= (size_t)10 + (size_t)prec) { + always given), therefore increase the length by one. + + */ + if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) || + (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { PyErr_SetString(PyExc_OverflowError, "formatted float is too long (precision too large?)"); return -1; } + PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", + (flags&F_ALT) ? "#" : "", + prec, type); PyOS_snprintf(buf, buflen, fmt, x); return strlen(buf); } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8565fb1..8dcec51 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5999,20 +5999,31 @@ formatfloat(Py_UNICODE *buf, prec = 6; if (type == 'f' && (fabs(x) / 1e25) >= 1e25) type = 'g'; - PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", - (flags & F_ALT) ? "#" : "", prec, type); - /* worst case length calc to ensure no buffer overrun: - fmt = %#.<prec>g - buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp - for any double rep.) - len = 1 + prec + 1 + 2 + 5 = 9 + prec + /* Worst case length calc to ensure no buffer overrun: + + 'g' formats: + fmt = %#.<prec>g + buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp + for any double rep.) + len = 1 + prec + 1 + 2 + 5 = 9 + prec + + 'f' formats: + buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) + len = 1 + 50 + 1 + prec = 52 + prec + If prec=0 the effective precision is 1 (the leading digit is - always given), therefore increase by one to 10+prec. */ - if (buflen <= (size_t)10 + (size_t)prec) { + always given), therefore increase the length by one. + + */ + if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) || + (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { PyErr_SetString(PyExc_OverflowError, - "formatted float is too long (precision too long?)"); + "formatted float is too long (precision too large?)"); return -1; } + PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", + (flags&F_ALT) ? "#" : "", + prec, type); return usprintf(buf, fmt, x); } |