Skip to content

Commit

Permalink
gh-106307: Fix PyMapping_GetOptionalItemString() (GH-108797)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
serhiy-storchaka committed Sep 6, 2023
1 parent bf414b7 commit 3a08db8
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
37 changes: 37 additions & 0 deletions Lib/test/test_capi/test_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,43 @@ def test_mapping_getitemstring(self):
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}
Expand Down
2 changes: 2 additions & 0 deletions Objects/abstract.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 3a08db8

Please sign in to comment.