summaryrefslogtreecommitdiffstats
path: root/Modules/_testcapi/bytes.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-03-25 15:32:11 (GMT)
committerGitHub <noreply@github.com>2024-03-25 15:32:11 (GMT)
commit0c1a42cf9c8cd0d4534d5c1d58f118ce7c5c446e (patch)
tree929ca228612a2f48b5e7afa86101fcecb04ad29d /Modules/_testcapi/bytes.c
parent01e7405da400e8997f8964d06cc414045e144681 (diff)
downloadcpython-0c1a42cf9c8cd0d4534d5c1d58f118ce7c5c446e.zip
cpython-0c1a42cf9c8cd0d4534d5c1d58f118ce7c5c446e.tar.gz
cpython-0c1a42cf9c8cd0d4534d5c1d58f118ce7c5c446e.tar.bz2
gh-87193: Support bytes objects with refcount > 1 in _PyBytes_Resize() (GH-117160)
Create a new bytes object and destroy the old one if it has refcount > 1.
Diffstat (limited to 'Modules/_testcapi/bytes.c')
-rw-r--r--Modules/_testcapi/bytes.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/Modules/_testcapi/bytes.c b/Modules/_testcapi/bytes.c
new file mode 100644
index 0000000..02294d8
--- /dev/null
+++ b/Modules/_testcapi/bytes.c
@@ -0,0 +1,53 @@
+#include "parts.h"
+#include "util.h"
+
+
+/* Test _PyBytes_Resize() */
+static PyObject *
+bytes_resize(PyObject *Py_UNUSED(module), PyObject *args)
+{
+ PyObject *obj;
+ Py_ssize_t newsize;
+ int new;
+
+ if (!PyArg_ParseTuple(args, "Onp", &obj, &newsize, &new))
+ return NULL;
+
+ NULLABLE(obj);
+ if (new) {
+ assert(obj != NULL);
+ assert(PyBytes_CheckExact(obj));
+ PyObject *newobj = PyBytes_FromStringAndSize(NULL, PyBytes_Size(obj));
+ if (newobj == NULL) {
+ return NULL;
+ }
+ memcpy(PyBytes_AsString(newobj), PyBytes_AsString(obj), PyBytes_Size(obj));
+ obj = newobj;
+ }
+ else {
+ Py_XINCREF(obj);
+ }
+ if (_PyBytes_Resize(&obj, newsize) < 0) {
+ assert(obj == NULL);
+ }
+ else {
+ assert(obj != NULL);
+ }
+ return obj;
+}
+
+
+static PyMethodDef test_methods[] = {
+ {"bytes_resize", bytes_resize, METH_VARARGS},
+ {NULL},
+};
+
+int
+_PyTestCapi_Init_Bytes(PyObject *m)
+{
+ if (PyModule_AddFunctions(m, test_methods) < 0) {
+ return -1;
+ }
+
+ return 0;
+}