summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-10-26 21:11:20 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2009-10-26 21:11:20 (GMT)
commit8568b198506b4d2ff3c0dc847f75989865b1e33e (patch)
tree9f9f6150ffc106bad3e2cd7e89b728ac2fddeb44
parent3e1eb0f715b804f87fb1b0cf3ec6576d15ff0663 (diff)
downloadcpython-8568b198506b4d2ff3c0dc847f75989865b1e33e.zip
cpython-8568b198506b4d2ff3c0dc847f75989865b1e33e.tar.gz
cpython-8568b198506b4d2ff3c0dc847f75989865b1e33e.tar.bz2
Issue #7117: Use PyOS_string_to_double instead of PyOS_ascii_strtod in
floatobject.c. Also, remove limitation on length of unicode inputs to float().
-rw-r--r--Lib/test/test_float.py2
-rw-r--r--Objects/floatobject.c59
2 files changed, 24 insertions, 37 deletions
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index 844a649..9d0c69d 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -31,8 +31,6 @@ class GeneralFloatCases(unittest.TestCase):
if test_support.have_unicode:
self.assertEqual(float(unicode(" 3.14 ")), 3.14)
self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14)
- # Implementation limitation in PyFloat_FromString()
- self.assertRaises(ValueError, float, unicode("1"*10000))
@test_support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
def test_float_with_comma(self):
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 1bfc57e..28b2004 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -181,9 +181,10 @@ PyFloat_FromString(PyObject *v, char **pend)
double x;
char buffer[256]; /* for errors */
#ifdef Py_USING_UNICODE
- char s_buffer[256]; /* for objects convertible to a char buffer */
+ char *s_buffer = NULL;
#endif
Py_ssize_t len;
+ PyObject *result = NULL;
if (pend)
*pend = NULL;
@@ -193,23 +194,21 @@ PyFloat_FromString(PyObject *v, char **pend)
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(v)) {
- if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) {
- PyErr_SetString(PyExc_ValueError,
- "Unicode float() literal too long to convert");
- return NULL;
- }
+ s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
+ if (s_buffer == NULL)
+ return PyErr_NoMemory();
if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
PyUnicode_GET_SIZE(v),
s_buffer,
NULL))
- return NULL;
+ goto error;
s = s_buffer;
len = strlen(s);
}
#endif
else if (PyObject_AsCharBuffer(v, &s, &len)) {
PyErr_SetString(PyExc_TypeError,
- "float() argument must be a string or a number");
+ "float() argument must be a string or a number");
return NULL;
}
last = s + len;
@@ -219,36 +218,26 @@ PyFloat_FromString(PyObject *v, char **pend)
/* We don't care about overflow or underflow. If the platform
* supports them, infinities and signed zeroes (on underflow) are
* fine. */
- errno = 0;
- PyFPE_START_PROTECT("strtod", return NULL)
- x = PyOS_ascii_strtod(s, (char **)&end);
- PyFPE_END_PROTECT(x)
- if (end == s) {
- if (errno == ENOMEM)
- PyErr_NoMemory();
- else {
- PyOS_snprintf(buffer, sizeof(buffer),
- "invalid literal for float(): %.200s", s);
- PyErr_SetString(PyExc_ValueError, buffer);
- }
- return NULL;
- }
- /* Since end != s, the platform made *some* kind of sense out
- of the input. Trust it. */
+ x = PyOS_string_to_double(s, (char **)&end, NULL);
+ if (x == -1.0 && PyErr_Occurred())
+ goto error;
while (Py_ISSPACE(*end))
end++;
- if (end != last) {
- if (*end == '\0')
- PyErr_SetString(PyExc_ValueError,
- "null byte in argument for float()");
- else {
- PyOS_snprintf(buffer, sizeof(buffer),
- "invalid literal for float(): %.200s", s);
- PyErr_SetString(PyExc_ValueError, buffer);
- }
- return NULL;
+ if (end == last)
+ result = PyFloat_FromDouble(x);
+ else {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "invalid literal for float(): %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ result = NULL;
}
- return PyFloat_FromDouble(x);
+
+ error:
+#ifdef Py_USING_UNICODE
+ if (s_buffer)
+ PyMem_FREE(s_buffer);
+#endif
+ return result;
}
static void