diff options
author | Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> | 2022-11-28 11:27:37 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-28 11:27:37 (GMT) |
commit | a8517978631535be8b42636922c4bd249d9f8c68 (patch) | |
tree | 7c0c0f70111442903eb5e1e73220199046f2e579 | |
parent | b1c148c1be73bcd65350e2fc7833db773a08b798 (diff) | |
download | cpython-a8517978631535be8b42636922c4bd249d9f8c68.zip cpython-a8517978631535be8b42636922c4bd249d9f8c68.tar.gz cpython-a8517978631535be8b42636922c4bd249d9f8c68.tar.bz2 |
[3.10] bpo-31718: Fix io.IncrementalNewlineDecoder SystemErrors and s… (#99842)
[3.10] bpo-31718: Fix io.IncrementalNewlineDecoder SystemErrors and segfaults (GH-18640)
Co-authored-by: Oren Milman <orenmn@gmail.com>
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>.
(cherry picked from commit 53eef27133c1da395b3b4d7ce0ab1d5b743ffb41)
Co-authored-by: Zackery Spytz <zspytz@gmail.com>
-rw-r--r-- | Lib/test/test_io.py | 10 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2020-02-23-23-48-15.bpo-31718.sXko5e.rst | 3 | ||||
-rw-r--r-- | Modules/_io/textio.c | 34 |
3 files changed, 33 insertions, 14 deletions
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index fcc7ebb..8dae85a 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3926,7 +3926,15 @@ class IncrementalNewlineDecoderTest(unittest.TestCase): self.assertEqual(decoder.decode(b"\r\r\n"), "\r\r\n") class CIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest): - pass + @support.cpython_only + def test_uninitialized(self): + uninitialized = self.IncrementalNewlineDecoder.__new__( + self.IncrementalNewlineDecoder) + self.assertRaises(ValueError, uninitialized.decode, b'bar') + self.assertRaises(ValueError, uninitialized.getstate) + self.assertRaises(ValueError, uninitialized.setstate, (b'foo', 0)) + self.assertRaises(ValueError, uninitialized.reset) + class PyIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest): pass diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-23-23-48-15.bpo-31718.sXko5e.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-23-23-48-15.bpo-31718.sXko5e.rst new file mode 100644 index 0000000..dd96c9e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-23-23-48-15.bpo-31718.sXko5e.rst @@ -0,0 +1,3 @@ +Raise :exc:`ValueError` instead of :exc:`SystemError` when methods of +uninitialized :class:`io.IncrementalNewlineDecoder` objects are called. +Patch by Oren Milman. diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index d5b311a..e1199a5 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -251,19 +251,16 @@ _io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, PyObject *errors) /*[clinic end generated code: output=fbd04d443e764ec2 input=89db6b19c6b126bf]*/ { - self->decoder = decoder; - Py_INCREF(decoder); if (errors == NULL) { - self->errors = _PyUnicode_FromId(&PyId_strict); - if (self->errors == NULL) + errors = _PyUnicode_FromId(&PyId_strict); + if (errors == NULL) { return -1; + } } - else { - self->errors = errors; - } - Py_INCREF(self->errors); + Py_XSETREF(self->errors, Py_NewRef(errors)); + Py_XSETREF(self->decoder, Py_NewRef(decoder)); self->translate = translate ? 1 : 0; self->seennl = 0; self->pendingcr = 0; @@ -298,6 +295,13 @@ check_decoded(PyObject *decoded) return 0; } +#define CHECK_INITIALIZED_DECODER(self) \ + if (self->errors == NULL) { \ + PyErr_SetString(PyExc_ValueError, \ + "IncrementalNewlineDecoder.__init__() not called"); \ + return NULL; \ + } + #define SEEN_CR 1 #define SEEN_LF 2 #define SEEN_CRLF 4 @@ -311,11 +315,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, Py_ssize_t output_len; nldecoder_object *self = (nldecoder_object *) myself; - if (self->decoder == NULL) { - PyErr_SetString(PyExc_ValueError, - "IncrementalNewlineDecoder.__init__ not called"); - return NULL; - } + CHECK_INITIALIZED_DECODER(self); /* decode input (with the eventual \r from a previous pass) */ if (self->decoder != Py_None) { @@ -529,6 +529,8 @@ _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) PyObject *buffer; unsigned long long flag; + CHECK_INITIALIZED_DECODER(self); + if (self->decoder != Py_None) { PyObject *state = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_getstate); @@ -573,6 +575,8 @@ _io_IncrementalNewlineDecoder_setstate(nldecoder_object *self, PyObject *buffer; unsigned long long flag; + CHECK_INITIALIZED_DECODER(self); + if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state argument must be a tuple"); return NULL; @@ -601,6 +605,8 @@ static PyObject * _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) /*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/ { + CHECK_INITIALIZED_DECODER(self); + self->seennl = 0; self->pendingcr = 0; if (self->decoder != Py_None) @@ -612,6 +618,8 @@ _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) static PyObject * incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context) { + CHECK_INITIALIZED_DECODER(self); + switch (self->seennl) { case SEEN_CR: return PyUnicode_FromString("\r"); |