mirror of
https://github.com/python/cpython.git
synced 2025-09-30 12:21:51 +00:00
[3.6] bpo-30184: Add tests for invalid use of PyArg_ParseTupleAndKeywords. (GH-1316). (#1441)
(cherry picked from commit 5f161fd86d
)
This commit is contained in:
parent
af71364c3f
commit
1bebd8a219
2 changed files with 43 additions and 20 deletions
|
@ -490,9 +490,8 @@ class SkipitemTest(unittest.TestCase):
|
||||||
# test the format unit when not skipped
|
# test the format unit when not skipped
|
||||||
format = c + "i"
|
format = c + "i"
|
||||||
try:
|
try:
|
||||||
# (note: the format string must be bytes!)
|
|
||||||
_testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
|
_testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
|
||||||
format.encode("ascii"), keywords)
|
format, keywords)
|
||||||
when_not_skipped = False
|
when_not_skipped = False
|
||||||
except SystemError as e:
|
except SystemError as e:
|
||||||
s = "argument 1 (impossible<bad format char>)"
|
s = "argument 1 (impossible<bad format char>)"
|
||||||
|
@ -504,7 +503,7 @@ class SkipitemTest(unittest.TestCase):
|
||||||
optional_format = "|" + format
|
optional_format = "|" + format
|
||||||
try:
|
try:
|
||||||
_testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
|
_testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
|
||||||
optional_format.encode("ascii"), keywords)
|
optional_format, keywords)
|
||||||
when_skipped = False
|
when_skipped = False
|
||||||
except SystemError as e:
|
except SystemError as e:
|
||||||
s = "impossible<bad format char>: '{}'".format(format)
|
s = "impossible<bad format char>: '{}'".format(format)
|
||||||
|
@ -517,40 +516,64 @@ class SkipitemTest(unittest.TestCase):
|
||||||
self.assertIs(when_skipped, when_not_skipped, message)
|
self.assertIs(when_skipped, when_not_skipped, message)
|
||||||
|
|
||||||
def test_parse_tuple_and_keywords(self):
|
def test_parse_tuple_and_keywords(self):
|
||||||
# parse_tuple_and_keywords error handling tests
|
# Test handling errors in the parse_tuple_and_keywords helper itself
|
||||||
self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
|
self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
|
||||||
(), {}, 42, [])
|
(), {}, 42, [])
|
||||||
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
|
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
|
||||||
(), {}, b'', 42)
|
(), {}, '', 42)
|
||||||
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
|
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
|
||||||
(), {}, b'', [''] * 42)
|
(), {}, '', [''] * 42)
|
||||||
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
|
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
|
||||||
(), {}, b'', [42])
|
(), {}, '', [42])
|
||||||
|
|
||||||
|
def test_bad_use(self):
|
||||||
|
# Test handling invalid format and keywords in
|
||||||
|
# PyArg_ParseTupleAndKeywords()
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(1,), {}, '||O', ['a'])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(1, 2), {}, '|O|O', ['a', 'b'])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(), {'a': 1}, '$$O', ['a'])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(), {'a': 1, 'b': 2}, '$O$O', ['a', 'b'])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(), {'a': 1}, '$|O', ['a'])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(), {'a': 1, 'b': 2}, '$O|O', ['a', 'b'])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(1,), {}, '|O', ['a', 'b'])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(1,), {}, '|OO', ['a'])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(), {}, '|$O', [''])
|
||||||
|
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
|
||||||
|
(), {}, '|OO', ['a', ''])
|
||||||
|
|
||||||
def test_positional_only(self):
|
def test_positional_only(self):
|
||||||
parse = _testcapi.parse_tuple_and_keywords
|
parse = _testcapi.parse_tuple_and_keywords
|
||||||
|
|
||||||
parse((1, 2, 3), {}, b'OOO', ['', '', 'a'])
|
parse((1, 2, 3), {}, 'OOO', ['', '', 'a'])
|
||||||
parse((1, 2), {'a': 3}, b'OOO', ['', '', 'a'])
|
parse((1, 2), {'a': 3}, 'OOO', ['', '', 'a'])
|
||||||
with self.assertRaisesRegex(TypeError,
|
with self.assertRaisesRegex(TypeError,
|
||||||
r'Function takes at least 2 positional arguments \(1 given\)'):
|
r'Function takes at least 2 positional arguments \(1 given\)'):
|
||||||
parse((1,), {'a': 3}, b'OOO', ['', '', 'a'])
|
parse((1,), {'a': 3}, 'OOO', ['', '', 'a'])
|
||||||
parse((1,), {}, b'O|OO', ['', '', 'a'])
|
parse((1,), {}, 'O|OO', ['', '', 'a'])
|
||||||
with self.assertRaisesRegex(TypeError,
|
with self.assertRaisesRegex(TypeError,
|
||||||
r'Function takes at least 1 positional arguments \(0 given\)'):
|
r'Function takes at least 1 positional arguments \(0 given\)'):
|
||||||
parse((), {}, b'O|OO', ['', '', 'a'])
|
parse((), {}, 'O|OO', ['', '', 'a'])
|
||||||
parse((1, 2), {'a': 3}, b'OO$O', ['', '', 'a'])
|
parse((1, 2), {'a': 3}, 'OO$O', ['', '', 'a'])
|
||||||
with self.assertRaisesRegex(TypeError,
|
with self.assertRaisesRegex(TypeError,
|
||||||
r'Function takes exactly 2 positional arguments \(1 given\)'):
|
r'Function takes exactly 2 positional arguments \(1 given\)'):
|
||||||
parse((1,), {'a': 3}, b'OO$O', ['', '', 'a'])
|
parse((1,), {'a': 3}, 'OO$O', ['', '', 'a'])
|
||||||
parse((1,), {}, b'O|O$O', ['', '', 'a'])
|
parse((1,), {}, 'O|O$O', ['', '', 'a'])
|
||||||
with self.assertRaisesRegex(TypeError,
|
with self.assertRaisesRegex(TypeError,
|
||||||
r'Function takes at least 1 positional arguments \(0 given\)'):
|
r'Function takes at least 1 positional arguments \(0 given\)'):
|
||||||
parse((), {}, b'O|O$O', ['', '', 'a'])
|
parse((), {}, 'O|O$O', ['', '', 'a'])
|
||||||
with self.assertRaisesRegex(SystemError, r'Empty parameter name after \$'):
|
with self.assertRaisesRegex(SystemError, r'Empty parameter name after \$'):
|
||||||
parse((1,), {}, b'O|$OO', ['', '', 'a'])
|
parse((1,), {}, 'O|$OO', ['', '', 'a'])
|
||||||
with self.assertRaisesRegex(SystemError, 'Empty keyword'):
|
with self.assertRaisesRegex(SystemError, 'Empty keyword'):
|
||||||
parse((1,), {}, b'O|OO', ['', 'a', ''])
|
parse((1,), {}, 'O|OO', ['', 'a', ''])
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
@unittest.skipUnless(threading, 'Threading required for this test.')
|
||||||
|
|
|
@ -1571,7 +1571,7 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *sub_args;
|
PyObject *sub_args;
|
||||||
PyObject *sub_kwargs;
|
PyObject *sub_kwargs;
|
||||||
char *sub_format;
|
const char *sub_format;
|
||||||
PyObject *sub_keywords;
|
PyObject *sub_keywords;
|
||||||
|
|
||||||
Py_ssize_t i, size;
|
Py_ssize_t i, size;
|
||||||
|
@ -1584,7 +1584,7 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
double buffers[8][4]; /* double ensures alignment where necessary */
|
double buffers[8][4]; /* double ensures alignment where necessary */
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OOyO:parse_tuple_and_keywords",
|
if (!PyArg_ParseTuple(args, "OOsO:parse_tuple_and_keywords",
|
||||||
&sub_args, &sub_kwargs,
|
&sub_args, &sub_kwargs,
|
||||||
&sub_format, &sub_keywords))
|
&sub_format, &sub_keywords))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue