diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 9e1985bb3a7639..576499517b11c7 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -459,6 +459,11 @@ def test_fromhex(self): self.assertRaises(ValueError, self.type2test.fromhex, '\x00') self.assertRaises(ValueError, self.type2test.fromhex, '12 \x00 34') + # For odd number of character(s) + with self.assertRaises(ValueError) as cm: + self.type2test.fromhex("a") + self.assertIn("fromhex() arg must be of even length", str(cm.exception)) + for data, pos in ( # invalid first hexadecimal character ('12 x4 56', 3), diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 8c7651f0f3aa45..b076d922e2da71 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2490,7 +2490,7 @@ PyObject* _PyBytes_FromHex(PyObject *string, int use_bytearray) { char *buf; - Py_ssize_t hexlen, invalid_char; + Py_ssize_t hexlen, invalid_char,real_len=0; unsigned int top, bot; const Py_UCS1 *str, *end; _PyBytesWriter writer; @@ -2516,6 +2516,19 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray) } assert(PyUnicode_KIND(string) == PyUnicode_1BYTE_KIND); + + const Py_UCS1 *s = PyUnicode_1BYTE_DATA(string); + for (Py_ssize_t i = 0; i < hexlen; i++) { + if (!Py_ISSPACE(s[i])) { + real_len++; + } + } + if (real_len % 2 != 0) { + PyErr_SetString(PyExc_ValueError, + "fromhex() arg must be of even length"); + _PyBytesWriter_Dealloc(&writer); + return NULL; + } str = PyUnicode_1BYTE_DATA(string); /* This overestimates if there are spaces */