Conversation
|
Thanks, but can you provide a way to reproduce the problem? |
|
Fair ask, and I should be upfront: I don't have a pure-Python reproducer. The bad read only happens on a frame whose co_code is empty, and I couldn't drive that through settrace. CPython's eval loop fatally errors ("Executing a cache") on a truly-empty co_code frame before any trace event fires, so the read is only reachable when a non-CPython executor (Cython's linetrace) calls the registered C trace function on such a frame. What led me to it: the pre-3.11 return branch already documents this exact case ("In unusual circumstances (Cython code), co_code can be the empty string") and range-checks f_lasti before the read. The 3.11+ RESUME paths in CTracer_handle_call and CTracer_handle_return read at f_lasti+1 / lasti with no such guard, so on an empty co_code they index one byte past a zero-length buffer. The patch just restores that guard, defaulting to the same result the pre-3.11 branch gives. If you'd rather not carry a guard without a runnable repro, I understand and you can close it. |
range-check f_lasti against co_code length in CTracer_handle_call and CTracer_handle_return before reading the RESUME byte, matching the existing guard in the pre-3.11 branch, so a frame with empty co_code (as Cython generates) can't cause an out-of-bounds read.