Skip to content

Commit db9bea0

Browse files
gh-127740: For odd-length input to bytes.fromhex(...) change the error message to ValueError: fromhex() arg must be of even length (#127756)
1 parent 12b4f1a commit db9bea0

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

Lib/test/test_bytes.py

+6
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,12 @@ def test_fromhex(self):
459459
self.assertRaises(ValueError, self.type2test.fromhex, '\x00')
460460
self.assertRaises(ValueError, self.type2test.fromhex, '12 \x00 34')
461461

462+
# For odd number of character(s)
463+
for value in ("a", "aaa", "deadbee"):
464+
with self.assertRaises(ValueError) as cm:
465+
self.type2test.fromhex(value)
466+
self.assertIn("fromhex() arg must contain an even number of hexadecimal digits", str(cm.exception))
467+
462468
for data, pos in (
463469
# invalid first hexadecimal character
464470
('12 x4 56', 3),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix error message in :func:`bytes.fromhex` when given an odd number of
2+
digits to properly indicate that an even number of hexadecimal digits is
3+
required.

Objects/bytesobject.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -2543,7 +2543,12 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray)
25432543

25442544
bot = _PyLong_DigitValue[*str];
25452545
if (bot >= 16) {
2546-
invalid_char = str - PyUnicode_1BYTE_DATA(string);
2546+
/* Check if we had a second digit */
2547+
if (str >= end){
2548+
invalid_char = -1;
2549+
} else {
2550+
invalid_char = str - PyUnicode_1BYTE_DATA(string);
2551+
}
25472552
goto error;
25482553
}
25492554
str++;
@@ -2554,9 +2559,14 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray)
25542559
return _PyBytesWriter_Finish(&writer, buf);
25552560

25562561
error:
2557-
PyErr_Format(PyExc_ValueError,
2558-
"non-hexadecimal number found in "
2559-
"fromhex() arg at position %zd", invalid_char);
2562+
if (invalid_char == -1) {
2563+
PyErr_SetString(PyExc_ValueError,
2564+
"fromhex() arg must contain an even number of hexadecimal digits");
2565+
} else {
2566+
PyErr_Format(PyExc_ValueError,
2567+
"non-hexadecimal number found in "
2568+
"fromhex() arg at position %zd", invalid_char);
2569+
}
25602570
_PyBytesWriter_Dealloc(&writer);
25612571
return NULL;
25622572
}

0 commit comments

Comments
 (0)