diff options
-rw-r--r-- | Doc/c-api/object.rst | 9 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Objects/bytesobject.c | 46 |
3 files changed, 33 insertions, 25 deletions
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index b0700a1419..a7be156d16 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -142,10 +142,11 @@ Object Protocol .. index:: builtin: bytes - Compute a bytes representation of object *o*. *NULL* is returned on failure - and a bytes object on success. This is equivalent to the Python expression - ``bytes(o)``. - + Compute a bytes representation of object *o*. *NULL* is returned on + failure and a bytes object on success. This is equivalent to the Python + expression ``bytes(o)``, when *o* is not an integer. Unlike ``bytes(o)``, + a TypeError is raised when *o* is an integer instead of a zero-initialized + bytes object. .. cfunction:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) @@ -140,6 +140,9 @@ Core and Builtins - Issue #4856: Remove checks for win NT. +- Issue #6687: PyBytes_FromObject() no longer accepts an integer as its + argument to construct a null-initialized bytes object. + C-API ----- diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 41eee40d55..cb634481bd 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2884,6 +2884,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) const char *encoding = NULL; const char *errors = NULL; PyObject *new = NULL; + Py_ssize_t size; static char *kwlist[] = {"source", "encoding", "errors", 0}; if (type != &PyBytes_Type) @@ -2914,6 +2915,25 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) assert(PyBytes_Check(new)); return new; } + /* Is it an integer? */ + size = PyNumber_AsSsize_t(x, PyExc_ValueError); + if (size == -1 && PyErr_Occurred()) { + PyErr_Clear(); + } + else { + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + new = PyBytes_FromStringAndSize(NULL, size); + if (new == NULL) { + return NULL; + } + if (size > 0) { + memset(((PyBytesObject*)new)->ob_sval, 0, size); + } + return new; + } /* If it's not unicode, there can't be encoding or errors */ if (encoding != NULL || errors != NULL) { @@ -2934,27 +2954,6 @@ PyBytes_FromObject(PyObject *x) PyErr_BadInternalCall(); return NULL; } - - /* Is it an int? */ - size = PyNumber_AsSsize_t(x, PyExc_ValueError); - if (size == -1 && PyErr_Occurred()) { - PyErr_Clear(); - } - else { - if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return NULL; - } - new = PyBytes_FromStringAndSize(NULL, size); - if (new == NULL) { - return NULL; - } - if (size > 0) { - memset(((PyBytesObject*)new)->ob_sval, 0, size); - } - return new; - } - /* Use the modern buffer interface */ if (PyObject_CheckBuffer(x)) { Py_buffer view; @@ -2974,6 +2973,11 @@ PyBytes_FromObject(PyObject *x) PyBuffer_Release(&view); return NULL; } + if (PyUnicode_Check(x)) { + PyErr_SetString(PyExc_TypeError, + "cannot convert unicode object to bytes"); + return NULL; + } /* For iterator version, create a string object and resize as needed */ /* XXX(gb): is 64 a good value? also, optimize if length is known */ |