From 69dc17c906eaae0da0de79696d26b69fb938edd4 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Thu, 20 Aug 2026 18:02:06 +0800 Subject: [PATCH] fix(code-runtime-python): bind BaseException into every settlement-path except clause MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rebindable-BaseException vector the bot flagged existed in every except clause of the settlement path, not just the _run outer catch: safe_model_traceback (three guards) and the post-done flush swallow resolved the module-global BaseException at runtime, so a __main__.BaseException rebind plus a throwing __str__ could let a render-time exception escape and lose the done frame. Bind BaseException into a _run local (at the top) and a closure cell in _make_failure_reporter, and change every such except clause to catch the local — immune to a one-line rebind. --- .../code-runtime-python/py/bootstrap.py | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/code-runtime/code-runtime-python/py/bootstrap.py b/packages/code-runtime/code-runtime-python/py/bootstrap.py index 3dc705452e..870a23b65d 100644 --- a/packages/code-runtime/code-runtime-python/py/bootstrap.py +++ b/packages/code-runtime/code-runtime-python/py/bootstrap.py @@ -727,6 +727,15 @@ def _clamped(which: int, soft: int, hard: int) -> tuple[int, int]: async def _run(channel: ProtocolChannel) -> None: + # The exception class every `except` clause in this function catches is bound + # into a LOCAL at the very top, before any model code runs. This bootstrap IS + # `__main__`, so `__main__.BaseException = RuntimeError` would otherwise + # rebind the module global the `except BaseException` clauses resolve at + # runtime — and a program exception that no longer matches would escape `_run` + # with no done frame, misreporting the run as a `worker-exit`. A frame local + # is not reachable by `__main__._X = ...`, so the catch is immune. + _BaseException = BaseException + # 1. Boot handshake. boot = channel.read_frame() if boot is None or boot.get("type") != "boot": @@ -786,7 +795,7 @@ async def _run(channel: ProtocolChannel) -> None: "lower the budget or raise the inherited address-space limit" % (_budget_key, effective_soft) ) - except BaseException as exc: # noqa: BLE001 -- report every failure to host + except _BaseException as exc: # noqa: BLE001 -- report every failure to host; `_BaseException` is a pre-program local channel.send_sync( { "type": "done", @@ -998,15 +1007,6 @@ async def _run(channel: ProtocolChannel) -> None: _os_write_local = _os_write _memoryview_local = _memoryview _fallback_frame_local = _FALLBACK_DONE_FRAME - # The exception class the outer try/except catches is bound into a LOCAL - # here, before the program runs. This bootstrap is `__main__`, so - # `__main__.BaseException = RuntimeError` would otherwise rebind the module - # global `BaseException` the `except BaseException` clause resolves at - # runtime, and a subsequent `ValueError` would then not match the clause — - # escaping `_run` with no `done` frame and misreporting the run as a - # `worker-exit`. Binding the class into a local makes the catch immune to a - # one-line rebind. - _BaseException = BaseException def send_done(payload: dict[str, Any] | str) -> None: try: @@ -1106,7 +1106,7 @@ async def _run(channel: ProtocolChannel) -> None: for _flush in (flush_out, flush_err): try: _flush() - except BaseException: # noqa: BLE001 -- swallow ONLY the log tail; `done` must reach the host + except _BaseException: # noqa: BLE001 -- swallow ONLY the log tail; `done` must reach the host; `_BaseException` is a pre-program local pass reply_task.cancel() send_done(done) @@ -2159,11 +2159,18 @@ def _make_failure_reporter() -> Any: cap_message = _cap_message model_traceback = _model_traceback unrenderable = _UNRENDERABLE_DIAGNOSTIC + # The exception class the guards below catch is bound into a closure cell + # here, at import time, before model code runs. `safe_model_traceback` runs + # AFTER the program (which is `__main__`) may have rebound the module global + # `BaseException`, so `except BaseException` would resolve the rebound class + # and a render-time throw could escape — losing the done frame. A closure cell + # is not reachable by `__main__._X = ...`, so the catch is immune. + _BaseException = BaseException def safe_model_traceback(exc: BaseException, max_bytes: int) -> str: try: return cap_message(model_traceback(exc, max_bytes), max_bytes) - except BaseException: # noqa: BLE001 -- a throw here would cost the done frame + except _BaseException: # noqa: BLE001 -- a throw here would cost the done frame pass try: raw_name = type(exc).__name__ @@ -2176,14 +2183,14 @@ def _make_failure_reporter() -> Any: # code-unit prefix, which bounds the bytes at 4x, and the following # `cap_message` still applies the exact byte cap. name = raw_name[:_MAX_FALLBACK_NAME_CHARS] if type(raw_name) is str else "" - except BaseException: # noqa: BLE001 -- a raising __name__ must not cost the done frame + except _BaseException: # noqa: BLE001 -- a raising __name__ must not cost the done frame name = "" # Wrapped for the same reason: `cap_message` encodes, and its allocation # is the only step left that can still fail. The fixed literal needs no # budget, so it can always be delivered. try: return cap_message(f"{name}: {unrenderable}", max_bytes) - except BaseException: # noqa: BLE001 -- the done frame outranks the diagnostic's detail + except _BaseException: # noqa: BLE001 -- the done frame outranks the diagnostic's detail return unrenderable return safe_model_traceback