Issue #25678: Copy buffer objects to null-terminated strings.
Avoid buffer overreads when int(), long(), float(), and compile()
are passed buffer objects. Similar code is removed from the
complex() constructor, where it was not reachable.
Patch backported from issue #24802 by Eryk Sun.
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 0ce7f6c..1143fab 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -180,6 +180,7 @@
char *s_buffer = NULL;
#endif
Py_ssize_t len;
+ PyObject *str = NULL;
PyObject *result = NULL;
if (pend)
@@ -202,7 +203,14 @@
len = strlen(s);
}
#endif
- else if (PyObject_AsCharBuffer(v, &s, &len)) {
+ else if (!PyObject_AsCharBuffer(v, &s, &len)) {
+ /* Copy to NUL-terminated buffer. */
+ str = PyString_FromStringAndSize(s, len);
+ if (str == NULL)
+ return NULL;
+ s = PyString_AS_STRING(str);
+ }
+ else {
PyErr_SetString(PyExc_TypeError,
"float() argument must be a string or a number");
return NULL;
@@ -233,6 +241,7 @@
if (s_buffer)
PyMem_FREE(s_buffer);
#endif
+ Py_XDECREF(str);
return result;
}