Skip to content

Commit fd04005

Browse files
_struct.c: Fix UB from integer overflow in prepare_s (GH-145158)
Avoid possible undefined behaviour from signed overflow in `struct` module As discovered via oss-fuzz.
1 parent ae7fc4a commit fd04005

File tree

3 files changed

+14
-1
lines changed

3 files changed

+14
-1
lines changed

Lib/test/test_struct.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,9 @@ def test_count_overflow(self):
552552
hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2)
553553
self.assertRaises(struct.error, struct.calcsize, hugecount2)
554554

555+
hugecount3 = '{}i{}q'.format(sys.maxsize // 4, sys.maxsize // 8)
556+
self.assertRaises(struct.error, struct.calcsize, hugecount3)
557+
555558
def test_trailing_counter(self):
556559
store = array.array('b', b' '*100)
557560

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

Modules/_struct.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1678,7 +1678,15 @@ prepare_s(PyStructObject *self)
16781678
case 's': _Py_FALLTHROUGH;
16791679
case 'p': len++; ncodes++; break;
16801680
case 'x': break;
1681-
default: len += num; if (num) ncodes++; break;
1681+
default:
1682+
if (num > PY_SSIZE_T_MAX - len) {
1683+
goto overflow;
1684+
}
1685+
len += num;
1686+
if (num) {
1687+
ncodes++;
1688+
}
1689+
break;
16821690
}
16831691

16841692
itemsize = e->size;

0 commit comments

Comments
 (0)