fix thread safety of io.StringIO.truncate (#133732)

This commit is contained in:
Kumar Aditya 2025-05-09 13:29:17 +05:30 committed by GitHub
parent 308ceffc68
commit 2cd24ebfe9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 22 additions and 14 deletions

View file

@ -149,13 +149,13 @@ PyDoc_STRVAR(_io_StringIO_truncate__doc__,
{"truncate", _PyCFunction_CAST(_io_StringIO_truncate), METH_FASTCALL, _io_StringIO_truncate__doc__},
static PyObject *
_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size);
_io_StringIO_truncate_impl(stringio *self, PyObject *pos);
static PyObject *
_io_StringIO_truncate(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
Py_ssize_t size = ((stringio *)self)->pos;
PyObject *pos = Py_None;
if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) {
goto exit;
@ -163,12 +163,10 @@ _io_StringIO_truncate(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
if (nargs < 1) {
goto skip_optional;
}
if (!_Py_convert_optional_to_ssize_t(args[0], &size)) {
goto exit;
}
pos = args[0];
skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = _io_StringIO_truncate_impl((stringio *)self, size);
return_value = _io_StringIO_truncate_impl((stringio *)self, pos);
Py_END_CRITICAL_SECTION();
exit:
@ -552,4 +550,4 @@ _io_StringIO_newlines_get(PyObject *self, void *Py_UNUSED(context))
return return_value;
}
/*[clinic end generated code: output=5bfaaab7f41ee6b5 input=a9049054013a1b77]*/
/*[clinic end generated code: output=bccc25ef8e6ce9ef input=a9049054013a1b77]*/

View file

@ -444,7 +444,7 @@ stringio_iternext(PyObject *op)
/*[clinic input]
@critical_section
_io.StringIO.truncate
pos as size: Py_ssize_t(accept={int, NoneType}, c_default="((stringio *)self)->pos") = None
pos: object = None
/
Truncate size to pos.
@ -455,16 +455,26 @@ Returns the new absolute position.
[clinic start generated code]*/
static PyObject *
_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size)
/*[clinic end generated code: output=eb3aef8e06701365 input=fa8a6c98bb2ba780]*/
_io_StringIO_truncate_impl(stringio *self, PyObject *pos)
/*[clinic end generated code: output=c76c43b5ecfaf4e2 input=d59fd2ee49757ae6]*/
{
CHECK_INITIALIZED(self);
CHECK_CLOSED(self);
if (size < 0) {
PyErr_Format(PyExc_ValueError,
"Negative size value %zd", size);
return NULL;
Py_ssize_t size;
if (pos == Py_None) {
size = self->pos;
}
else {
size = PyLong_AsLong(pos);
if (size == -1 && PyErr_Occurred()) {
return NULL;
}
if (size < 0) {
PyErr_Format(PyExc_ValueError,
"negative pos value %zd", size);
return NULL;
}
}
if (size < self->string_size) {