Skip to content

Commit 6644cd2

Browse files
[3.12] gh-124248: Fix crash in struct when processing 0p fields (GH-124251) (#124278)
gh-124248: Fix crash in struct when processing 0p fields (GH-124251) (cherry picked from commit 63f1960) Co-authored-by: Brian Schubert <[email protected]>
1 parent 6c6b044 commit 6644cd2

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

Lib/test/test_struct.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ def test_new_features(self):
9696
('10s', b'helloworld', b'helloworld', b'helloworld', 0),
9797
('11s', b'helloworld', b'helloworld\0', b'helloworld\0', 1),
9898
('20s', b'helloworld', b'helloworld'+10*b'\0', b'helloworld'+10*b'\0', 1),
99+
('0p', b'helloworld', b'', b'', 1),
100+
('1p', b'helloworld', b'\x00', b'\x00', 1),
101+
('2p', b'helloworld', b'\x01h', b'\x01h', 1),
102+
('10p', b'helloworld', b'\x09helloworl', b'\x09helloworl', 1),
103+
('11p', b'helloworld', b'\x0Ahelloworld', b'\x0Ahelloworld', 0),
104+
('12p', b'helloworld', b'\x0Ahelloworld\0', b'\x0Ahelloworld\0', 1),
105+
('20p', b'helloworld', b'\x0Ahelloworld'+9*b'\0', b'\x0Ahelloworld'+9*b'\0', 1),
99106
('b', 7, b'\7', b'\7', 0),
100107
('b', -7, b'\371', b'\371', 0),
101108
('B', 7, b'\7', b'\7', 0),
@@ -339,6 +346,7 @@ def assertStructError(func, *args, **kwargs):
339346
def test_p_code(self):
340347
# Test p ("Pascal string") code.
341348
for code, input, expected, expectedback in [
349+
('0p', b'abc', b'', b''),
342350
('p', b'abc', b'\x00', b''),
343351
('1p', b'abc', b'\x00', b''),
344352
('2p', b'abc', b'\x01a', b'a'),
@@ -580,6 +588,7 @@ def test__sizeof__(self):
580588
self.check_sizeof('187s', 1)
581589
self.check_sizeof('20p', 1)
582590
self.check_sizeof('0s', 1)
591+
self.check_sizeof('0p', 1)
583592
self.check_sizeof('0c', 0)
584593

585594
def test_boundary_error_message(self):

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,7 @@ Scott Schram
16371637
Robin Schreiber
16381638
Chad J. Schroeder
16391639
Simon-Martin Schroeder
1640+
Brian Schubert
16401641
Christian Schubert
16411642
Sam Schulenburg
16421643
Andreas Schwab
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed potential crash when using :mod:`struct` to process zero-width
2+
'Pascal string' fields (``0p``).

Modules/_struct.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,9 +1662,16 @@ s_unpack_internal(PyStructObject *soself, const char *startfrom,
16621662
if (e->format == 's') {
16631663
v = PyBytes_FromStringAndSize(res, code->size);
16641664
} else if (e->format == 'p') {
1665-
Py_ssize_t n = *(unsigned char*)res;
1666-
if (n >= code->size)
1667-
n = code->size - 1;
1665+
Py_ssize_t n;
1666+
if (code->size == 0) {
1667+
n = 0;
1668+
}
1669+
else {
1670+
n = *(unsigned char*)res;
1671+
if (n >= code->size) {
1672+
n = code->size - 1;
1673+
}
1674+
}
16681675
v = PyBytes_FromStringAndSize(res + 1, n);
16691676
} else {
16701677
v = e->unpack(state, res, e);
@@ -1975,8 +1982,12 @@ s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset,
19751982
n = PyByteArray_GET_SIZE(v);
19761983
p = PyByteArray_AS_STRING(v);
19771984
}
1978-
if (n > (code->size - 1))
1985+
if (code->size == 0) {
1986+
n = 0;
1987+
}
1988+
else if (n > (code->size - 1)) {
19791989
n = code->size - 1;
1990+
}
19801991
if (n > 0)
19811992
memcpy(res + 1, p, n);
19821993
if (n > 255)

0 commit comments

Comments
 (0)