BBS: TELESC.NET.BR Assunto: exec/tests/msgbase/get_all_msg_headers_to_ext.js skipifsrc/sbbs3/js_ms De: Rob Swindell (on Windows 11) Data: Thu, 14 May 2026 01:58:37 -0700 ----------------------------------------------------------- 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.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). n --- mSynchronetn hgVertrauen n hHome of Synchronet n gh[vert/cvs/bbs].synchro.net ----------------------------------------------------------- [Voltar]