Skip to content

Commit 9d22a53

Browse files
authored
gh-158583: Fix uninitialized memory read in bytes.fromhex() (#158584)
1 parent 880696a commit 9d22a53

3 files changed

Lines changed: 21 additions & 8 deletions

File tree

‎Lib/test/test_bytes.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,15 @@ def test_fromhex(self):
518518
self.type2test.fromhex(data)
519519
self.assertIn('at position %s' % pos, str(cm.exception))
520520

521+
# gh-158583: Check for out of bounds reads (uninitialized bytes).
522+
# Create an array from a list to not overallocate.
523+
a = array.array('B', list(b'1234 ')) # Py_ISSPACE() loop
524+
self.assertEqual(self.type2test.fromhex(a), b'\x12\x34')
525+
526+
a = array.array('B', list(b'12345')) # Missing second digit
527+
with self.assertRaises(ValueError):
528+
self.type2test.fromhex(a)
529+
521530
def test_hex(self):
522531
self.assertRaises(TypeError, self.type2test.hex)
523532
self.assertRaises(TypeError, self.type2test.hex, 1)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:meth:`bytes.fromhex` and :meth:`bytearray.fromhex`: Fix uninitialized
2+
memory read. Patch by Victor Stinner.

‎Objects/bytesobject.c‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2702,33 +2702,35 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray)
27022702
if (Py_ISSPACE(*str)) {
27032703
do {
27042704
str++;
2705+
if (str >= end) {
2706+
goto done;
2707+
}
27052708
} while (Py_ISSPACE(*str));
2706-
if (str >= end)
2707-
break;
27082709
}
27092710

27102711
top = _PyLong_DigitValue[*str];
27112712
if (top >= 16) {
27122713
invalid_char = str - start;
27132714
goto error;
27142715
}
2716+
27152717
str++;
2718+
if (str >= end) {
2719+
invalid_char = -1;
2720+
goto error;
2721+
}
27162722

27172723
bot = _PyLong_DigitValue[*str];
27182724
if (bot >= 16) {
2719-
/* Check if we had a second digit */
2720-
if (str >= end){
2721-
invalid_char = -1;
2722-
} else {
2723-
invalid_char = str - start;
2724-
}
2725+
invalid_char = str - start;
27252726
goto error;
27262727
}
27272728
str++;
27282729

27292730
*buf++ = (unsigned char)((top << 4) + bot);
27302731
}
27312732

2733+
done:
27322734
if (view.obj != NULL) {
27332735
PyBuffer_Release(&view);
27342736
}

0 commit comments

Comments
 (0)