mirror of
https://github.com/python/cpython.git
synced 2026-05-04 09:31:02 +00:00
gh-148653: Fix SIGSEGV in marshal.loads for self-referencing tuples
This commit is contained in:
parent
2faceeec5c
commit
7c214ea52e
3 changed files with 26 additions and 1 deletions
|
|
@ -731,5 +731,25 @@ def test_read_object_from_file(self):
|
|||
os_helper.unlink(os_helper.TESTFN)
|
||||
|
||||
|
||||
class SelfRefTupleTest(unittest.TestCase):
|
||||
"""Regression test for gh-148653: TYPE_TUPLE with FLAG_REF back-reference.
|
||||
|
||||
R_REF registered the tuple in p->refs before its slots were populated.
|
||||
A TYPE_REF back-reference to the partial tuple could reach a hashing
|
||||
site (PySet_Add) with NULL slots, crashing with SIGSEGV.
|
||||
|
||||
The fix uses the two-phase r_ref_reserve/r_ref_insert pattern so the
|
||||
Py_None placeholder is detected by the TYPE_REF handler, raising
|
||||
ValueError instead.
|
||||
"""
|
||||
|
||||
def test_self_ref_tuple(self):
|
||||
# TYPE_TUPLE|FLAG_REF n=2; NONE; TYPE_SET n=1; TYPE_REF(0)
|
||||
payload = (b'\xa8\x02\x00\x00\x00N'
|
||||
b'<\x01\x00\x00\x00r\x00\x00\x00\x00')
|
||||
with self.assertRaises(ValueError):
|
||||
marshal.loads(payload)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Fix SIGSEGV in :func:`marshal.loads` for self-referencing tuples. Such
|
||||
payloads will now raise :exc:`ValueError` instead of crashing.
|
||||
|
|
@ -1385,7 +1385,9 @@ r_object(RFILE *p)
|
|||
}
|
||||
_read_tuple:
|
||||
v = PyTuple_New(n);
|
||||
R_REF(v);
|
||||
idx = r_ref_reserve(flag, p);
|
||||
if (idx < 0)
|
||||
Py_CLEAR(v);
|
||||
if (v == NULL)
|
||||
break;
|
||||
|
||||
|
|
@ -1400,6 +1402,7 @@ r_object(RFILE *p)
|
|||
}
|
||||
PyTuple_SET_ITEM(v, i, v2);
|
||||
}
|
||||
v = r_ref_insert(v, idx, flag, p);
|
||||
retval = v;
|
||||
break;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue