Example:
import array
res = bytes.fromhex(array.array('B', b' 1A 2B 30 '))
try:
bytes.fromhex(array.array('B', b' 1A 2B 3'))
except ValueError:
pass
Valgrind reports two "Use of uninitialised value of size 8" errors:
$ PYTHONMALLOC=malloc valgrind ./python x.py
==863634== Memcheck, a memory error detector
==863634== Copyright (C) 2002-2026, and GNU GPL'd, by Julian Seward et al.
==863634== Using Valgrind-3.27.1 and LibVEX; rerun with -h for copyright info
==863634== Command: ./python x.py
==863634==
==863634== Use of uninitialised value of size 8
==863634== at 0x497C07: _PyBytes_FromHex (bytesobject.c:2688)
==863634== by 0x497CC2: bytes_fromhex_impl (bytesobject.c:2618)
==863634== by 0x497D07: bytes_fromhex (bytesobject.c.h:1261)
==863634== by 0x4F491A: cfunction_vectorcall_O (methodobject.c:535)
==863634== by 0x49BDAF: _PyObject_VectorcallTstate (pycore_call.h:149)
==863634== by 0x49BE77: PyObject_Vectorcall (call.c:327)
==863634== by 0x5B0C90: _Py_VectorCallInstrumentation_StackRefSteal (ceval.c:770)
==863634== by 0x5B7E1C: _PyEval_EvalFrameDefault (generated_cases.c.h:1906)
==863634== by 0x5CFACD: _PyEval_EvalFrame (pycore_ceval.h:122)
==863634== by 0x5CFC98: _PyEval_Vector (ceval.c:2176)
==863634== by 0x5CFD7C: PyEval_EvalCode (ceval.c:681)
==863634== by 0x649C6B: run_eval_code_obj (pythonrun.c:1406)
==863634==
==863634== Use of uninitialised value of size 8
==863634== at 0x497BC1: _PyBytes_FromHex (bytesobject.c:2700)
==863634== by 0x497CC2: bytes_fromhex_impl (bytesobject.c:2618)
==863634== by 0x497D07: bytes_fromhex (bytesobject.c.h:1261)
==863634== by 0x4F491A: cfunction_vectorcall_O (methodobject.c:535)
==863634== by 0x49BDAF: _PyObject_VectorcallTstate (pycore_call.h:149)
==863634== by 0x49BE77: PyObject_Vectorcall (call.c:327)
==863634== by 0x5B0C90: _Py_VectorCallInstrumentation_StackRefSteal (ceval.c:770)
==863634== by 0x5B7E1C: _PyEval_EvalFrameDefault (generated_cases.c.h:1906)
==863634== by 0x5CFACD: _PyEval_EvalFrame (pycore_ceval.h:122)
==863634== by 0x5CFC98: _PyEval_Vector (ceval.c:2176)
==863634== by 0x5CFD7C: PyEval_EvalCode (ceval.c:681)
==863634== by 0x649C6B: run_eval_code_obj (pythonrun.c:1406)
==863634==
==863634==
==863634== HEAP SUMMARY:
==863634== in use at exit: 1,618 bytes in 4 blocks
==863634== total heap usage: 36,249 allocs, 36,245 frees, 9,219,652 bytes allocated
==863634==
==863634== LEAK SUMMARY:
==863634== definitely lost: 0 bytes in 0 blocks
==863634== indirectly lost: 0 bytes in 0 blocks
==863634== possibly lost: 0 bytes in 0 blocks
==863634== still reachable: 1,618 bytes in 4 blocks
==863634== suppressed: 0 bytes in 0 blocks
==863634== Rerun with --leak-check=full to see details of leaked memory
==863634==
==863634== Use --track-origins=yes to see where uninitialised values come from
==863634== For lists of detected and suppressed errors, rerun with: -s
==863634== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
The problem is in _PyBytes_FromHex(): str++ doesn't check if we reached end.
For example, for a buffer of 10 bytes, it can read the 11th: outside the buffer!
Linked PRs
Example:
Valgrind reports two "Use of uninitialised value of size 8" errors:
The problem is in
_PyBytes_FromHex():str++doesn't check if we reachedend.For example, for a buffer of 10 bytes, it can read the 11th: outside the buffer!
Linked PRs