mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
gh-111942: Fix crashes in TextIOWrapper.reconfigure() (GH-111976)
* Fix crash when encoding is not string or None. * Fix crash when both line_buffering and write_through raise exception when converted ti int. * Add a number of tests for constructor and reconfigure() method with invalid arguments.
This commit is contained in:
parent
a519b87958
commit
ee06fffd38
3 changed files with 122 additions and 5 deletions
|
|
@ -1284,30 +1284,40 @@ textiowrapper_change_encoding(textio *self, PyObject *encoding,
|
|||
errors = &_Py_ID(strict);
|
||||
}
|
||||
}
|
||||
Py_INCREF(errors);
|
||||
|
||||
const char *c_encoding = PyUnicode_AsUTF8(encoding);
|
||||
if (c_encoding == NULL) {
|
||||
Py_DECREF(encoding);
|
||||
Py_DECREF(errors);
|
||||
return -1;
|
||||
}
|
||||
const char *c_errors = PyUnicode_AsUTF8(errors);
|
||||
if (c_errors == NULL) {
|
||||
Py_DECREF(encoding);
|
||||
Py_DECREF(errors);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create new encoder & decoder
|
||||
PyObject *codec_info = _PyCodec_LookupTextEncoding(
|
||||
PyUnicode_AsUTF8(encoding), "codecs.open()");
|
||||
c_encoding, "codecs.open()");
|
||||
if (codec_info == NULL) {
|
||||
Py_DECREF(encoding);
|
||||
Py_DECREF(errors);
|
||||
return -1;
|
||||
}
|
||||
if (_textiowrapper_set_decoder(self, codec_info, c_errors) != 0 ||
|
||||
_textiowrapper_set_encoder(self, codec_info, c_errors) != 0) {
|
||||
Py_DECREF(codec_info);
|
||||
Py_DECREF(encoding);
|
||||
Py_DECREF(errors);
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(codec_info);
|
||||
|
||||
Py_SETREF(self->encoding, encoding);
|
||||
Py_SETREF(self->errors, Py_NewRef(errors));
|
||||
Py_SETREF(self->errors, errors);
|
||||
|
||||
return _textiowrapper_fix_encoder_state(self);
|
||||
}
|
||||
|
|
@ -1338,6 +1348,26 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding,
|
|||
int write_through;
|
||||
const char *newline = NULL;
|
||||
|
||||
if (encoding != Py_None && !PyUnicode_Check(encoding)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"reconfigure() argument 'encoding' must be str or None, not %s",
|
||||
Py_TYPE(encoding)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if (errors != Py_None && !PyUnicode_Check(errors)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"reconfigure() argument 'errors' must be str or None, not %s",
|
||||
Py_TYPE(errors)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if (newline_obj != NULL && newline_obj != Py_None &&
|
||||
!PyUnicode_Check(newline_obj))
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"reconfigure() argument 'newline' must be str or None, not %s",
|
||||
Py_TYPE(newline_obj)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
/* Check if something is in the read buffer */
|
||||
if (self->decoded_chars != NULL) {
|
||||
if (encoding != Py_None || errors != Py_None || newline_obj != NULL) {
|
||||
|
|
@ -1357,9 +1387,12 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding,
|
|||
|
||||
line_buffering = convert_optional_bool(line_buffering_obj,
|
||||
self->line_buffering);
|
||||
if (line_buffering < 0) {
|
||||
return NULL;
|
||||
}
|
||||
write_through = convert_optional_bool(write_through_obj,
|
||||
self->write_through);
|
||||
if (line_buffering < 0 || write_through < 0) {
|
||||
if (write_through < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue