Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Lib/test/test_marshal.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,27 @@ def test_slice(self):
with self.assertRaises(ValueError):
marshal.dumps(obj, version)

def test_slice_ref_reserve_failure(self):
# Test for the fix: if (idx < 0) { break; }
# This tests the case where r_ref_reserve fails when processing TYPE_SLICE with FLAG_REF
# We simulate a scenario where the reference list is too large

# Create malformed marshal data: TYPE_SLICE with FLAG_REF but invalid reference handling
# This should trigger the r_ref_reserve failure path and be handled gracefully
malformed_data = b'\xba' # TYPE_SLICE | FLAG_REF (0x3a | 0x80)
malformed_data += b'N' # None for start
malformed_data += b'N' # None for stop
malformed_data += b'N' # None for step

# This should raise an exception rather than crash
with self.assertRaises((ValueError, EOFError)):
marshal.loads(malformed_data)

# Test truncated data that would also trigger the error path
truncated_data = b'\xba' + b'N' # TYPE_SLICE | FLAG_REF + only one component
with self.assertRaises((ValueError, EOFError)):
marshal.loads(truncated_data)

@support.cpython_only
@unittest.skipUnless(_testcapi, 'requires _testcapi')
class CAPI_TestCase(unittest.TestCase, HelperMixin):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:mod:`marshal`: fix a possible crash when deserializing :class:`slice` objects.
3 changes: 3 additions & 0 deletions Python/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1656,6 +1656,9 @@ r_object(RFILE *p)
case TYPE_SLICE:
{
Py_ssize_t idx = r_ref_reserve(flag, p);
if (idx < 0) {
break;
}
PyObject *stop = NULL;
PyObject *step = NULL;
PyObject *start = r_object(p);
Expand Down
Loading