summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorcolorfulappl <colorfulappl@qq.com>2022-11-24 14:01:26 (GMT)
committerGitHub <noreply@github.com>2022-11-24 14:01:26 (GMT)
commit8dbe08eb7c807f484fe9870f5b7f5ae2881fd966 (patch)
treee8a735022f12ba4a1b73dc2449d6e5e40383bded /Lib
parent69f6cc77d0f1664f983a83b6ae707d99a99f5c4f (diff)
downloadcpython-8dbe08eb7c807f484fe9870f5b7f5ae2881fd966.zip
cpython-8dbe08eb7c807f484fe9870f5b7f5ae2881fd966.tar.gz
cpython-8dbe08eb7c807f484fe9870f5b7f5ae2881fd966.tar.bz2
gh-99240: Fix double-free bug in Argument Clinic str_converter generated code (GH-99241)
Fix double-free bug mentioned at https://github.com/python/cpython/issues/99240, by moving memory clean up out of "exit" label. Automerge-Triggered-By: GH:erlend-aasland
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/clinic.test33
-rw-r--r--Lib/test/test_clinic.py15
2 files changed, 26 insertions, 22 deletions
diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test
index 7b804e8..f4842cc 100644
--- a/Lib/test/clinic.test
+++ b/Lib/test/clinic.test
@@ -1740,29 +1740,18 @@ test_str_converter_encoding(PyObject *module, PyObject *const *args, Py_ssize_t
goto exit;
}
return_value = test_str_converter_encoding_impl(module, a, b, c, d, d_length, e, e_length);
+ /* Post parse cleanup for a */
+ PyMem_FREE(a);
+ /* Post parse cleanup for b */
+ PyMem_FREE(b);
+ /* Post parse cleanup for c */
+ PyMem_FREE(c);
+ /* Post parse cleanup for d */
+ PyMem_FREE(d);
+ /* Post parse cleanup for e */
+ PyMem_FREE(e);
exit:
- /* Cleanup for a */
- if (a) {
- PyMem_FREE(a);
- }
- /* Cleanup for b */
- if (b) {
- PyMem_FREE(b);
- }
- /* Cleanup for c */
- if (c) {
- PyMem_FREE(c);
- }
- /* Cleanup for d */
- if (d) {
- PyMem_FREE(d);
- }
- /* Cleanup for e */
- if (e) {
- PyMem_FREE(e);
- }
-
return return_value;
}
@@ -1770,7 +1759,7 @@ static PyObject *
test_str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c,
char *d, Py_ssize_t d_length, char *e,
Py_ssize_t e_length)
-/*[clinic end generated code: output=8acb886a3843f3bc input=eb4c38e1f898f402]*/
+/*[clinic end generated code: output=999c1deecfa15b0a input=eb4c38e1f898f402]*/
/*[clinic input]
diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py
index a590fa5..890beeb 100644
--- a/Lib/test/test_clinic.py
+++ b/Lib/test/test_clinic.py
@@ -1045,6 +1045,17 @@ class ClinicFunctionalTest(unittest.TestCase):
self.assertEqual(ac_tester.str_converter('a', b'b', b'c'), ('a', 'b', 'c'))
self.assertEqual(ac_tester.str_converter('a', b'b', 'c\0c'), ('a', 'b', 'c\0c'))
+ def test_str_converter_encoding(self):
+ with self.assertRaises(TypeError):
+ ac_tester.str_converter_encoding(1)
+ self.assertEqual(ac_tester.str_converter_encoding('a', 'b', 'c'), ('a', 'b', 'c'))
+ with self.assertRaises(TypeError):
+ ac_tester.str_converter_encoding('a', b'b\0b', 'c')
+ self.assertEqual(ac_tester.str_converter_encoding('a', b'b', bytearray([ord('c')])), ('a', 'b', 'c'))
+ self.assertEqual(ac_tester.str_converter_encoding('a', b'b', bytearray([ord('c'), 0, ord('c')])),
+ ('a', 'b', 'c\x00c'))
+ self.assertEqual(ac_tester.str_converter_encoding('a', b'b', b'c\x00c'), ('a', 'b', 'c\x00c'))
+
def test_py_buffer_converter(self):
with self.assertRaises(TypeError):
ac_tester.py_buffer_converter('a', 'b')
@@ -1225,6 +1236,10 @@ class ClinicFunctionalTest(unittest.TestCase):
arg_refcount_after = sys.getrefcount(arg)
self.assertEqual(arg_refcount_origin, arg_refcount_after)
+ def test_gh_99240_double_free(self):
+ expected_error = r'gh_99240_double_free\(\) argument 2 must be encoded string without null bytes, not str'
+ with self.assertRaisesRegex(TypeError, expected_error):
+ ac_tester.gh_99240_double_free('a', '\0b')
if __name__ == "__main__":
unittest.main()