Skip to content

Commit dd35504

Browse files
[3.13] _struct.c: Fix UB from integer overflow in prepare_s (GH-145158) (#145163)
`_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. (cherry picked from commit fd04005) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
1 parent 0acd41f commit dd35504

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
@@ -547,6 +547,9 @@ def test_count_overflow(self):
547547
hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2)
548548
self.assertRaises(struct.error, struct.calcsize, hugecount2)
549549

550+
hugecount3 = '{}i{}q'.format(sys.maxsize // 4, sys.maxsize // 8)
551+
self.assertRaises(struct.error, struct.calcsize, hugecount3)
552+
550553
def test_trailing_counter(self):
551554
store = array.array('b', b' '*100)
552555

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
@@ -1478,7 +1478,15 @@ prepare_s(PyStructObject *self)
14781478
case 's': /* fall through */
14791479
case 'p': len++; ncodes++; break;
14801480
case 'x': break;
1481-
default: len += num; if (num) ncodes++; break;
1481+
default:
1482+
if (num > PY_SSIZE_T_MAX - len) {
1483+
goto overflow;
1484+
}
1485+
len += num;
1486+
if (num) {
1487+
ncodes++;
1488+
}
1489+
break;
14821490
}
14831491

14841492
itemsize = e->size;

0 commit comments

Comments
 (0)