https://gitlab.synchro.net/main/sbbs/-/commit/8068616e30b3fa825aadc690
Modified Files:
src/sbbs3/js_global.cpp js_internal.cpp
Log Message:
Fix crash/regression in require() when a required symbol is undefined
js_IsTerminated() was reading its object argument's JS private slot as a js_callback_t*, but the only caller (js_require) passes the execution
scope -- for a top-level require() that's the global object, whose
private is a global_private_t, not a js_callback_t. Reinterpreting it
walked garbage: js_callback_t::terminated (offset 16) lands in the
middle of global_private_t and ::bg lands past its end, so the result is undefined. In jsexec those bytes happened to dereference truthy; in
sbbsctrl they were the unmapped pointer 0x000007fc, faulting with an
access violation in JS_TriggerAllOperationCallbacks' call chain and
taking down the Control Panel (WER minidump 2026-06-24).
The condition was also inverted: generating-12-calm (c185d884eb)
uncommented urge-22-door's (78b2682ec8, gitlab #681) stubbed
`if (TRUE) { //!js_IsTerminated(...)` as `if (js_IsTerminated(...))`,
dropping the `!`. The two defects cancelled in the common case (garbage returned true, so the inverted test still printed the error), which is
why it went unnoticed -- but it meant #681's actual purpose, suppressing
the "symbol not defined" error during termination, never worked, and on
Windows it crashed instead.
Fix js_IsTerminated() to walk the scope chain to the internal "js"
object (mirroring js_execfile's lookup) before reading the js_callback_t,
and restore the `!` so the error is reported unless the script is
genuinely terminating. Verified: require() of a defined symbol succeeds, require() of an undefined symbol throws "symbol 'x' not defined by
script 'y'", and no crash.
Co-Authored-By: Claude Opus 4.8 (1M context) <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net