Skip to content

Commit

Permalink
[2.7] bpo-31243: Fixed PyArg_ParseTuple failure checks. (GH-3171) (#3235
Browse files Browse the repository at this point in the history
)
  • Loading branch information
orenmn authored and serhiy-storchaka committed Aug 29, 2017
1 parent 0b69b37 commit 20958e6
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 10 deletions.
20 changes: 20 additions & 0 deletions Lib/test/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -2702,6 +2702,26 @@ def _make_illegal_wrapper():
#t = _make_illegal_wrapper()
#self.assertRaises(TypeError, t.read)

# Issue 31243: calling read() while the return value of decoder's
# getstate() is invalid should neither crash the interpreter nor
# raise a SystemError.
def _make_very_illegal_wrapper(getstate_ret_val):
class BadDecoder:
def getstate(self):
return getstate_ret_val
def _get_bad_decoder(dummy):
return BadDecoder()
quopri = codecs.lookup("quopri_codec")
with support.swap_attr(quopri, 'incrementaldecoder',
_get_bad_decoder):
return _make_illegal_wrapper()
t = _make_very_illegal_wrapper(42)
with self.maybeRaises(TypeError):
t.read(42)
t = _make_very_illegal_wrapper(())
with self.maybeRaises(TypeError):
t.read(42)


class CTextIOWrapperTest(TextIOWrapperTest):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a crash in some methods of `io.TextIOWrapper`, when the decoder's state
is invalid. Patch by Oren Milman.
2 changes: 1 addition & 1 deletion Modules/_io/textio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1416,7 +1416,7 @@ textiowrapper_read_chunk(textio *self)
/* Given this, we know there was a valid snapshot point
* len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
*/
if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) {
if (!PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags)) {
Py_DECREF(state);
return -1;
}
Expand Down
27 changes: 18 additions & 9 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -911,8 +911,9 @@ test_L_code(PyObject *self)
PyTuple_SET_ITEM(tuple, 0, num);

value = -1;
if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) {
return NULL;
}
if (value != 42)
return raiseTestError("test_L_code",
"L code returned wrong value for long 42");
Expand All @@ -925,8 +926,9 @@ test_L_code(PyObject *self)
PyTuple_SET_ITEM(tuple, 0, num);

value = -1;
if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) {
return NULL;
}
if (value != 42)
return raiseTestError("test_L_code",
"L code returned wrong value for int 42");
Expand Down Expand Up @@ -1207,8 +1209,9 @@ test_k_code(PyObject *self)
PyTuple_SET_ITEM(tuple, 0, num);

value = 0;
if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)
if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) {
return NULL;
}
if (value != ULONG_MAX)
return raiseTestError("test_k_code",
"k code returned wrong value for long 0xFFF...FFF");
Expand All @@ -1226,8 +1229,9 @@ test_k_code(PyObject *self)
PyTuple_SET_ITEM(tuple, 0, num);

value = 0;
if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)
if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) {
return NULL;
}
if (value != (unsigned long)-0x42)
return raiseTestError("test_k_code",
"k code returned wrong value for long -0xFFF..000042");
Expand Down Expand Up @@ -1587,14 +1591,16 @@ test_u_code(PyObject *self)
PyTuple_SET_ITEM(tuple, 0, obj);

value = 0;
if (PyArg_ParseTuple(tuple, "u:test_u_code", &value) < 0)
if (!PyArg_ParseTuple(tuple, "u:test_u_code", &value)) {
return NULL;
}
if (value != PyUnicode_AS_UNICODE(obj))
return raiseTestError("test_u_code",
"u code returned wrong value for u'test'");
value = 0;
if (PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len) < 0)
if (!PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len)) {
return NULL;
}
if (value != PyUnicode_AS_UNICODE(obj) ||
len != PyUnicode_GET_SIZE(obj))
return raiseTestError("test_u_code",
Expand Down Expand Up @@ -1692,17 +1698,19 @@ test_empty_argparse(PyObject *self)
tuple = PyTuple_New(0);
if (!tuple)
return NULL;
if ((result = PyArg_ParseTuple(tuple, "|:test_empty_argparse")) < 0)
if (!(result = PyArg_ParseTuple(tuple, "|:test_empty_argparse"))) {
goto done;
}
dict = PyDict_New();
if (!dict)
goto done;
result = PyArg_ParseTupleAndKeywords(tuple, dict, "|:test_empty_argparse", kwlist);
done:
Py_DECREF(tuple);
Py_XDECREF(dict);
if (result < 0)
if (!result) {
return NULL;
}
else {
Py_RETURN_NONE;
}
Expand Down Expand Up @@ -2494,8 +2502,9 @@ test_raise_signal(PyObject* self, PyObject *args)
{
int signum, err;

if (PyArg_ParseTuple(args, "i:raise_signal", &signum) < 0)
if (!PyArg_ParseTuple(args, "i:raise_signal", &signum)) {
return NULL;
}

err = raise(signum);
if (err)
Expand Down

0 comments on commit 20958e6

Please sign in to comment.