ReviewOS

zig-utils/zig-js

Private ABI: canonicalize Latin-1 module specifiers

#723
Closed chris opened this 11 days ago ·
11 days ago

Parents: #473, #495 Related: #474

Problem

The pinned Bun/Home JSC__JSModuleLoader__loadAndEvaluateModule and JSModuleLoader__import boundary decodes a BunString into an engine StringData value, then passes decoded.asStr() to Context.loadAndEvaluateModule. With flat Latin-1 storage active, asStr() is the physical one-byte-per-code-unit image, not canonical WTF-8. A semantic specifier such as /virtual/café.js is therefore looked up as /virtual/caf\xE9.js, missing the exact module registry entry and potentially reaching filesystem resolution with malformed bytes.

Scope

  • Consume the decoded module-name StringData as canonical WTF-8 before registry or filesystem resolution.
  • Add a private-ABI fixture that registers a non-ASCII Latin-1 virtual module and imports it through both exported BunString entry points.
  • Preserve the existing ASCII zero-conversion path, Promise identity/cache behavior, null-input exception behavior, ownership, OOM propagation, and pinned symbol/layout contract.

No-workaround rules

  • No ASCII-only restriction, lossy replacement, alternate registry alias, duplicate module registration, fixture-specific recognition, or fallback to the physical byte image.
  • Do not change Promise, microtask, queue, job, or module-registry scheduling semantics.

Acceptance

  • The exact old physical-byte path fails the new fixture and both corrected exports fulfill with the already-instantiated namespace.
  • Repeated ASCII and Latin-1 imports preserve namespace identity and do not re-evaluate the module.
  • Home private-ABI audit and Debug/ReleaseSafe/TSan behavior fixtures pass with no ABI inventory drift.
  • Full units remain green; applicable Test262 impact is recorded exactly.
11 days ago

Closed after a causal test disproved the reported path on current main.

I added an exact private-ABI fixture that registered /virtual/private-723-café.js, supplied the import name through an untagged Latin-1 BunString containing raw 0xE9, exercised both JSC__JSModuleLoader__loadAndEvaluateModule and JSModuleLoader__import, required both Promises to fulfill with the existing namespace, and required the module evaluation count to remain exactly one. The unmodified implementation passed the full 392/392 linked-symbol runtime matrix; the audit also remained 538 symbols, 447 implemented private, 0 pending, 0 unclassified.

The static suspicion missed an earlier boundary guarantee: privateBunStringValue converts Latin-1/UTF-16/UTF-8 BunString variants to canonical WTF-8 before constructing decoded. Also, strcell.flat_storage_active is currently false, so decoded.asStr() is canonical storage in this revision. No failure exists to repair, and retaining the proposed test or changing production code would not satisfy the issue premise. The temporary test-only diff was removed; no source change or commit was retained.

Sign in to comment on this issue.