summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2010-01-12 22:23:56 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2010-01-12 22:23:56 (GMT)
commit8efef5ce9f6c0dfd2cb4720b61a37bbdfdb5e30e (patch)
tree749d0392efbc8ef53bd5f9bc22a25a41c8b4ba6d
parentefa45f35b529a61aceb4e1266ded7a0b268b0c17 (diff)
downloadcpython-8efef5ce9f6c0dfd2cb4720b61a37bbdfdb5e30e.zip
cpython-8efef5ce9f6c0dfd2cb4720b61a37bbdfdb5e30e.tar.gz
cpython-8efef5ce9f6c0dfd2cb4720b61a37bbdfdb5e30e.tar.bz2
Issue #7632: Fix a problem with _Py_dg_strtod that could lead to
crashes in debug builds, for certain long numeric strings corresponding to subnormal values.
-rw-r--r--Lib/test/floating_points.txt7
-rw-r--r--Misc/NEWS4
-rw-r--r--Python/dtoa.c26
3 files changed, 26 insertions, 11 deletions
diff --git a/Lib/test/floating_points.txt b/Lib/test/floating_points.txt
index 70d21ea..539073d 100644
--- a/Lib/test/floating_points.txt
+++ b/Lib/test/floating_points.txt
@@ -1019,3 +1019,10 @@
+43723334984997307E-26
+10182419849537963E-24
-93501703572661982E-26
+
+# A value that caused a crash in debug builds for Python >= 2.7, 3.1
+# See http://bugs.python.org/issue7632
+2183167012312112312312.23538020374420446192e-370
+
+# Another value designed to test a corner case of Python's strtod code.
+0.99999999999999999999999999999999999999999e+23
diff --git a/Misc/NEWS b/Misc/NEWS
index 245b6a6..9fc17dc 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 3?
Core and Builtins
-----------------
+- Issue #7632: Fix a crash in dtoa.c that occurred in debug builds
+ when parsing certain long numeric strings corresponding to subnormal
+ values.
+
- Issue #7319: Silence DeprecationWarning by default.
- Issue #2335: Backport set literals syntax from Python 3.x.
diff --git a/Python/dtoa.c b/Python/dtoa.c
index 12e6f80..4d64be5 100644
--- a/Python/dtoa.c
+++ b/Python/dtoa.c
@@ -1142,7 +1142,7 @@ bigcomp(U *rv, const char *s0, BCinfo *bc)
dsign = bc->dsign;
nd = bc->nd;
nd0 = bc->nd0;
- p5 = nd + bc->e0 - 1;
+ p5 = nd + bc->e0;
speccase = 0;
if (rv->d == 0.) { /* special case: value near underflow-to-zero */
/* threshold was rounded to zero */
@@ -1227,17 +1227,21 @@ bigcomp(U *rv, const char *s0, BCinfo *bc)
}
}
- /* Now b/d = exactly half-way between the two floating-point values */
- /* on either side of the input string. Compute first digit of b/d. */
-
- if (!(dig = quorem(b,d))) {
- b = multadd(b, 10, 0); /* very unlikely */
- if (b == NULL) {
- Bfree(d);
- return -1;
- }
- dig = quorem(b,d);
+ /* Now 10*b/d = exactly half-way between the two floating-point values
+ on either side of the input string. If b >= d, round down. */
+ if (cmp(b, d) >= 0) {
+ dd = -1;
+ goto ret;
+ }
+
+ /* Compute first digit of 10*b/d. */
+ b = multadd(b, 10, 0);
+ if (b == NULL) {
+ Bfree(d);
+ return -1;
}
+ dig = quorem(b, d);
+ assert(dig < 10);
/* Compare b/d with s0 */