]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-106307: Fix PyMapping_GetOptionalItemString() (GH-108797)
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 6 Sep 2023 19:47:38 +0000 (22:47 +0300)
committerGitHub <noreply@github.com>
Wed, 6 Sep 2023 19:47:38 +0000 (19:47 +0000)
The resulting pointer was not set to NULL if the creation of a temporary
string object was failed.

The tests were also missed due to oversight.

Lib/test/test_capi/test_abstract.py
Objects/abstract.c

index 3f51e5b28104d97efc67f8b35c246ac940da7c14..671f62b977d2aa5b232e8a2759f4cc5879bf1605 100644 (file)
@@ -265,6 +265,43 @@ class CAPITest(unittest.TestCase):
         self.assertRaises(TypeError, getitemstring, [], b'a')
         self.assertRaises(SystemError, getitemstring, NULL, b'a')
 
+    def test_mapping_getoptionalitem(self):
+        getitem = _testcapi.mapping_getoptionalitem
+        dct = {'a': 1, '\U0001f40d': 2}
+        self.assertEqual(getitem(dct, 'a'), 1)
+        self.assertEqual(getitem(dct, 'b'), KeyError)
+        self.assertEqual(getitem(dct, '\U0001f40d'), 2)
+
+        dct2 = ProxyGetItem(dct)
+        self.assertEqual(getitem(dct2, 'a'), 1)
+        self.assertEqual(getitem(dct2, 'b'), KeyError)
+
+        self.assertEqual(getitem(['a', 'b', 'c'], 1), 'b')
+
+        self.assertRaises(TypeError, getitem, 42, 'a')
+        self.assertRaises(TypeError, getitem, {}, [])  # unhashable
+        self.assertRaises(IndexError, getitem, [], 1)
+        self.assertRaises(TypeError, getitem, [], 'a')
+        # CRASHES getitem({}, NULL)
+        # CRASHES getitem(NULL, 'a')
+
+    def test_mapping_getoptionalitemstring(self):
+        getitemstring = _testcapi.mapping_getoptionalitemstring
+        dct = {'a': 1, '\U0001f40d': 2}
+        self.assertEqual(getitemstring(dct, b'a'), 1)
+        self.assertEqual(getitemstring(dct, b'b'), KeyError)
+        self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2)
+
+        dct2 = ProxyGetItem(dct)
+        self.assertEqual(getitemstring(dct2, b'a'), 1)
+        self.assertEqual(getitemstring(dct2, b'b'), KeyError)
+
+        self.assertRaises(TypeError, getitemstring, 42, b'a')
+        self.assertRaises(UnicodeDecodeError, getitemstring, {}, b'\xff')
+        self.assertRaises(SystemError, getitemstring, {}, NULL)
+        self.assertRaises(TypeError, getitemstring, [], b'a')
+        # CRASHES getitemstring(NULL, b'a')
+
     def test_mapping_haskey(self):
         haskey = _testcapi.mapping_haskey
         dct = {'a': 1, '\U0001f40d': 2}
index 6713926b86d218eb76fd73d99719d5eda0488fd2..b57190d2521e11cf3022e357213fd039840b75fd 100644 (file)
@@ -2393,11 +2393,13 @@ int
 PyMapping_GetOptionalItemString(PyObject *obj, const char *key, PyObject **result)
 {
     if (key == NULL) {
+        *result = NULL;
         null_error();
         return -1;
     }
     PyObject *okey = PyUnicode_FromString(key);
     if (okey == NULL) {
+        *result = NULL;
         return -1;
     }
     int rc = PyMapping_GetOptionalItem(obj, okey, result);