Skip to content

Commit 4d0dce0

Browse files
Fix integer overflow for formats "s" and "p" in the struct module (GH-145750)
1 parent 9c1c710 commit 4d0dce0

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

Lib/test/test_struct.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,12 @@ def test_count_overflow(self):
555555
hugecount3 = '{}i{}q'.format(sys.maxsize // 4, sys.maxsize // 8)
556556
self.assertRaises(struct.error, struct.calcsize, hugecount3)
557557

558+
hugecount4 = '{}?s'.format(sys.maxsize)
559+
self.assertRaises(struct.error, struct.calcsize, hugecount4)
560+
561+
hugecount5 = '{}?p'.format(sys.maxsize)
562+
self.assertRaises(struct.error, struct.calcsize, hugecount5)
563+
558564
def test_trailing_counter(self):
559565
store = array.array('b', b' '*100)
560566

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Avoid undefined behaviour from signed integer overflow when parsing format
2+
strings in the :mod:`struct` module. Found by OSS Fuzz in
3+
:oss-fuzz:`488466741`.

Modules/_struct.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,13 @@ prepare_s(PyStructObject *self, PyObject *format)
16761676

16771677
switch (c) {
16781678
case 's': _Py_FALLTHROUGH;
1679-
case 'p': len++; ncodes++; break;
1679+
case 'p':
1680+
if (len == PY_SSIZE_T_MAX) {
1681+
goto overflow;
1682+
}
1683+
len++;
1684+
ncodes++;
1685+
break;
16801686
case 'x': break;
16811687
default:
16821688
if (num > PY_SSIZE_T_MAX - len) {

0 commit comments

Comments
 (0)