From: Victor Stinner Date: Mon, 15 Sep 2025 14:32:43 +0000 (+0100) Subject: gh-129813, PEP 782: Use PyBytesWriter in _codecs.escape_decode() (#138919) X-Git-Tag: v3.15.0a1~363 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=67cc1cf68a26d931ece3a6790ba914cf8a9b62f8;p=thirdparty%2FPython%2Fcpython.git gh-129813, PEP 782: Use PyBytesWriter in _codecs.escape_decode() (#138919) Replace PyBytes_FromStringAndSize(NULL, size) and _PyBytes_Resize() with the new public PyBytesWriter API. --- diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 82a46ec1e70d..33e262f2ba1e 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -202,55 +202,50 @@ _codecs_escape_encode_impl(PyObject *module, PyObject *data, const char *errors) /*[clinic end generated code: output=4af1d477834bab34 input=8f4b144799a94245]*/ { - Py_ssize_t size; - Py_ssize_t newsize; - PyObject *v; - - size = PyBytes_GET_SIZE(data); + Py_ssize_t size = PyBytes_GET_SIZE(data); if (size > PY_SSIZE_T_MAX / 4) { PyErr_SetString(PyExc_OverflowError, "string is too large to encode"); return NULL; } - newsize = 4*size; - v = PyBytes_FromStringAndSize(NULL, newsize); + Py_ssize_t newsize = 4*size; - if (v == NULL) { + PyBytesWriter *writer = PyBytesWriter_Create(newsize); + if (writer == NULL) { return NULL; } - else { - Py_ssize_t i; - char c; - char *p = PyBytes_AS_STRING(v); - - for (i = 0; i < size; i++) { - /* There's at least enough room for a hex escape */ - assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); - c = PyBytes_AS_STRING(data)[i]; - if (c == '\'' || c == '\\') - *p++ = '\\', *p++ = c; - else if (c == '\t') - *p++ = '\\', *p++ = 't'; - else if (c == '\n') - *p++ = '\\', *p++ = 'n'; - else if (c == '\r') - *p++ = '\\', *p++ = 'r'; - else if (c < ' ' || c >= 0x7f) { - *p++ = '\\'; - *p++ = 'x'; - *p++ = Py_hexdigits[(c & 0xf0) >> 4]; - *p++ = Py_hexdigits[c & 0xf]; - } - else - *p++ = c; + char *p = PyBytesWriter_GetData(writer); + + for (Py_ssize_t i = 0; i < size; i++) { + /* There's at least enough room for a hex escape */ + assert(newsize - (p - (char*)PyBytesWriter_GetData(writer)) >= 4); + + char c = PyBytes_AS_STRING(data)[i]; + if (c == '\'' || c == '\\') { + *p++ = '\\'; *p++ = c; } - *p = '\0'; - if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { - return NULL; + else if (c == '\t') { + *p++ = '\\'; *p++ = 't'; + } + else if (c == '\n') { + *p++ = '\\'; *p++ = 'n'; + } + else if (c == '\r') { + *p++ = '\\'; *p++ = 'r'; + } + else if (c < ' ' || c >= 0x7f) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = Py_hexdigits[(c & 0xf0) >> 4]; + *p++ = Py_hexdigits[c & 0xf]; + } + else { + *p++ = c; } } - return codec_tuple(v, size); + PyObject *decoded = PyBytesWriter_FinishWithPointer(writer, p); + return codec_tuple(decoded, size); } /* --- Decoder ------------------------------------------------------------ */