mirror of
https://github.com/python/cpython.git
synced 2024-11-25 19:03:49 +08:00
Make tset_float pass. float(<unicode>) was never very good -- it used
a fixed-length buffer of 256 bytes.
This commit is contained in:
parent
a28c291e92
commit
2be161dcfa
@ -39,15 +39,15 @@ class FormatFunctionsTestCase(unittest.TestCase):
|
||||
self.assertRaises(ValueError, float.__setformat__,
|
||||
'chicken', 'unknown')
|
||||
|
||||
BE_DOUBLE_INF = '\x7f\xf0\x00\x00\x00\x00\x00\x00'
|
||||
LE_DOUBLE_INF = ''.join(reversed(BE_DOUBLE_INF))
|
||||
BE_DOUBLE_NAN = '\x7f\xf8\x00\x00\x00\x00\x00\x00'
|
||||
LE_DOUBLE_NAN = ''.join(reversed(BE_DOUBLE_NAN))
|
||||
BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
|
||||
LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
|
||||
BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
|
||||
LE_DOUBLE_NAN = bytes(reversed(BE_DOUBLE_NAN))
|
||||
|
||||
BE_FLOAT_INF = '\x7f\x80\x00\x00'
|
||||
LE_FLOAT_INF = ''.join(reversed(BE_FLOAT_INF))
|
||||
BE_FLOAT_NAN = '\x7f\xc0\x00\x00'
|
||||
LE_FLOAT_NAN = ''.join(reversed(BE_FLOAT_NAN))
|
||||
BE_FLOAT_INF = b'\x7f\x80\x00\x00'
|
||||
LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF))
|
||||
BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
|
||||
LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN))
|
||||
|
||||
# on non-IEEE platforms, attempting to unpack a bit pattern
|
||||
# representing an infinity or a NaN should raise an exception.
|
||||
|
@ -68,19 +68,18 @@ PyFloat_FromString(PyObject *v)
|
||||
const char *s, *last, *end;
|
||||
double x;
|
||||
char buffer[256]; /* for errors */
|
||||
char s_buffer[256]; /* for objects convertible to a char buffer */
|
||||
char *s_buffer = NULL;
|
||||
Py_ssize_t len;
|
||||
PyObject *result = NULL;
|
||||
|
||||
if (PyString_Check(v)) {
|
||||
s = PyString_AS_STRING(v);
|
||||
len = PyString_GET_SIZE(v);
|
||||
}
|
||||
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,
|
||||
@ -100,7 +99,7 @@ PyFloat_FromString(PyObject *v)
|
||||
s++;
|
||||
if (*s == '\0') {
|
||||
PyErr_SetString(PyExc_ValueError, "empty string for float()");
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
/* We don't care about overflow or underflow. If the platform supports
|
||||
* them, infinities and signed zeroes (on underflow) are fine.
|
||||
@ -109,7 +108,7 @@ PyFloat_FromString(PyObject *v)
|
||||
* whether strtod sets errno on underflow is not defined, so we can't
|
||||
* key off errno.
|
||||
*/
|
||||
PyFPE_START_PROTECT("strtod", return NULL)
|
||||
PyFPE_START_PROTECT("strtod", goto error)
|
||||
x = PyOS_ascii_strtod(s, (char **)&end);
|
||||
PyFPE_END_PROTECT(x)
|
||||
errno = 0;
|
||||
@ -121,7 +120,7 @@ PyFloat_FromString(PyObject *v)
|
||||
PyOS_snprintf(buffer, sizeof(buffer),
|
||||
"invalid literal for float(): %.200s", s);
|
||||
PyErr_SetString(PyExc_ValueError, buffer);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
/* Since end != s, the platform made *some* kind of sense out
|
||||
of the input. Trust it. */
|
||||
@ -131,22 +130,26 @@ PyFloat_FromString(PyObject *v)
|
||||
PyOS_snprintf(buffer, sizeof(buffer),
|
||||
"invalid literal for float(): %.200s", s);
|
||||
PyErr_SetString(PyExc_ValueError, buffer);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
else if (end != last) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"null byte in argument for float()");
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
if (x == 0.0) {
|
||||
/* See above -- may have been strtod being anal
|
||||
about denorms. */
|
||||
PyFPE_START_PROTECT("atof", return NULL)
|
||||
PyFPE_START_PROTECT("atof", goto error)
|
||||
x = PyOS_ascii_atof(s);
|
||||
PyFPE_END_PROTECT(x)
|
||||
errno = 0; /* whether atof ever set errno is undefined */
|
||||
}
|
||||
return PyFloat_FromDouble(x);
|
||||
result = PyFloat_FromDouble(x);
|
||||
error:
|
||||
if (s_buffer)
|
||||
PyMem_FREE(s_buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -869,6 +872,11 @@ float_getformat(PyTypeObject *v, PyObject* arg)
|
||||
char* s;
|
||||
float_format_type r;
|
||||
|
||||
if (PyUnicode_Check(arg)) {
|
||||
arg = _PyUnicode_AsDefaultEncodedString(arg, NULL);
|
||||
if (arg == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (!PyString_Check(arg)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"__getformat__() argument must be string, not %.500s",
|
||||
|
Loading…
Reference in New Issue
Block a user