• exec/tests/msgbase/get_al

    From Rob Swindell (on Windows@VERT to Git commit to main/sbbs/m on Thursday, May 14, 2026 01:58:00
    https://gitlab.synchro.net/main/sbbs/-/commit/ca448cb8bb1a2cb8177f9643
    Added Files:
    exec/tests/msgbase/get_all_msg_headers_to_ext.js skipif
    Modified Files:
    src/sbbs3/js_msgbase.cpp
    Log Message:
    js_msgbase: fix get_all_msg_headers() returning undefined for *_NULL fields

    MsgBase.get_all_msg_headers() returned header objects whose LAZY_STRING_TRUNCSP_NULL-defaulted fields (to_ext, from_ext, replyto, replyto_ext, replyto_list, to_list, cc_list, summary, tags, from_org,
    etc.) yielded `undefined` on first JS access Ä even when the underlying p->msg.<field> was populated. Touching ANY other property first (e.g.
    h.number, h.attr, or JSON.stringify(h) which enumerates) then "primed"
    the object's SpiderMonkey shape and made all subsequent lazy resolves
    work normally on the same object.

    Stock callers (hotline.js, msglist.js, msgutil.js, etc.) didn't trip on
    this because they all happen to access a non-NULL field (number, attr, when_imported, ...) before any *_NULL field, masking the bug. It only
    surfaces in code that reads a *_NULL field as the first property
    touched on a bulk-fetched header Ä which is exactly what filtering by
    to_ext or from_ext naturally does.

    get_msg_header() does not exhibit this because each retrieval is
    followed by user code that organically touches a non-NULL field, again
    priming the shape before any *_NULL access.

    Fix: in js_get_all_msg_headers, eagerly JS_DefineProperty("number",
    ...) immediately after JS_SetPrivate on each fresh header object. That
    single defineProperty triggers the SpiderMonkey shape transition once
    per header at construction time, so the first lazy resolve of a *_NULL-defaulted field operates on a settled shape and returns the
    correct value.

    Add a regression test in exec/tests/msgbase/:

    - get_all_msg_headers_to_ext.js Ä creates a temp msgbase, saves a
    message with to_ext="1", reopens, fetches all headers, and reads
    h.to_ext as the FIRST property touched on each bulk-fetched header.
    Throws if the value is anything other than "1".

    - skipif Ä skips the entire msgbase/ test category when MsgBase isn't
    available (e.g. under JSDoor).

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows@VERT to Git commit to main/sbbs/m on Thursday, May 14, 2026 02:08:00
    https://gitlab.synchro.net/main/sbbs/-/commit/afb2714094b2bb3eb0f5fc27
    Modified Files:
    exec/tests/msgbase/get_all_msg_headers_to_ext.js
    Log Message:
    tests/msgbase: mkpath(system.temp_dir) for fresh-install / CI runners

    The get_all_msg_headers_to_ext.js test failed in CI with:
    smb_open_fp 2 'No such file or directory' opening .../temp/test_..._N.shd

    system.temp_dir is configured but its filesystem path doesn't necessarily
    exist yet on a freshly-cloned tree (e.g. a GitLab runner workspace), and smb_open / smb_open_fp uses O_CREAT for the file but does not mkdir the
    parent. Call mkpath(system.temp_dir) before constructing the MsgBase so
    the test is self-sufficient.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows@VERT to Git commit to main/sbbs/m on Wednesday, May 20, 2026 21:48:00
    https://gitlab.synchro.net/main/sbbs/-/commit/666ff71ceef9557cbb62d0a5
    Modified Files:
    exec/tests/msgbase/get_all_msg_headers.js src/sbbs3/js_msgbase.cpp
    Log Message:
    js_msgbase: fully fix get_all_msg_headers() *_NULL fields on real mailbases

    Commit ca448cb8b eagerly JS_DefineProperty("number") per header to force a SpiderMonkey shape transition, fixing get_all_msg_headers() header objects returning undefined on first access of a LAZY_STRING_TRUNCSP_NULL field (to_ext, from_ext, replyto, to_list, cc_list, summary, tags, from_org, ...). That masked the bug for tiny/uniform message bases (and the single-message regression test), but NOT for real mailboxes: the resolve hook still leaves a *_NULL field undefined whenever its value is NULL, which corrupts the 1.8.5 property cache for the shared header shape, so every subsequent same-shape header then reads undefined on first access of that field. On a live ~14.4k- message mail base this bit ~98% of headers once the first NULL-to_ext message appeared (cold to_ext==1 count: 0; correct count after priming: ~9150).

    Fix: eagerly RESOLVE each header's data fields at construction in js_get_all_msg_headers (js_get_msg_header_resolve with JSID_VOID) instead of just defining 'number'. Non-NULL fields become own properties up front, so callers iterating bulk-fetched headers never trigger the GET-path lazy resolve (nor the property-cache fast-path that mis-serves undefined). A new privatemsg_t.defer_listing flag skips the expensive field_list[]/can_read branches during this eager pass (they remain lazily resolved on first access), and p->enumerated is left unset so a later enumeration still builds them. Fetch cost is unchanged (dominated by smb_getmsghdr, not field population).

    Extend exec/tests/msgbase/get_all_msg_headers.js with a multi-message, mixed-NULL, shape-diverse bulk scenario that reads *_NULL fields as the first access. Note: the real-mailbox property-cache corruption could not be reproduced with synthetic save_msg()'d messages, so the test is a behavioral guard validated against a real base, not a standalone reproducer.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows@VERT to Git commit to main/sbbs/m on Saturday, May 23, 2026 22:50:00
    https://gitlab.synchro.net/main/sbbs/-/commit/edf75242977c665f506b8457
    Modified Files:
    exec/tests/msgbase/get_all_msg_headers.js src/sbbs3/js_msgbase.cpp sbbsdefs.h
    Log Message:
    sbbsdefs: disable JSOPTION_JIT (TraceMonkey) by default -- fixes #1143

    JAVASCRIPT_OPTIONS dropped from 0x810 to 0x10 (kept JSOPTION_COMPILE_N_GO, dropped JSOPTION_JIT / bit 0x800 / TraceMonkey). TraceMonkey is the true
    root cause of MsgBase.get_all_msg_headers() returning `undefined` on cold
    first access of LAZY_STRING_TRUNCSP_NULL fields (to_ext, from_ext, replyto, to_list, cc_list, summary, tags, from_org, ...) on bulk-fetched headers:
    the trace recorder's shape-guarded GETPROP over a hot for..in dot-access
    loop mis-replays `undefined` across the shared header shape, since the
    *_NULL fields are conditionally-resolved own properties (present on some headers, absent on others).

    Confirmed via A/B on the same build by flipping only this bit
    (js.options 0x810 -> 0x10) on a live ~7.7k-msg mail base: cold
    hdr.to_ext undefined collapses from thousands of spurious mispredicts
    to exactly the genuinely-NULL count (216 of 7698 headers, matching the
    primed count). Reproduced on Linux/gcc and Windows/MSVC (both compile
    JS_TRACER into libmozjs); does not reproduce on FreeBSD/Clang (which
    builds with --disable-tracejit per 3rdp/build/GNUmakefile:38-43).

    JSOPTION_METHODJIT (bit 0x4000) was already off and remains off. Its
    PolyIC has a similarly shape-guarded structure and would warrant a
    re-run of the issue's probe_to_ext.js / probe_enum.js before being
    enabled. Prior art: a0607c011 dropped METHODJIT for analogous reasons (xtrn_sec.js misbehavior).

    Reverts two prior workarounds, which both named the wrong cache
    (interpreter PropertyCache rather than the trace JIT):
    ca448cb8b - eager JS_DefineProperty("number") (ineffective on real bases)
    666ff71ce - eager full js_get_msg_header_resolve(JSID_VOID) + defer_listing
    (effective but at the cost of laziness, on the wrong diagnosis)

    Tests: rewrites exec/tests/msgbase/get_all_msg_headers.js to (1) hard-
    assert JSOPTION_JIT is off in js.options, failing fast with a clear
    message if re-enabled, and (2) keep the behavioral bulk-fetch contract
    guard. Drops the now-stale single-message scenario.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net