[PR #1963] [MERGED] fix(wasm): accept unpadded WABT section rows #4937

Closed
opened 2026-10-31 00:57:09 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1963
Author: @sathariels
Created: 10/11/2026
Status: ✅ Merged
Merged: 10/11/2026
Merged by: @morluto

Base: main ← Head: fix/wasm-datacount-section-row


📝 Commits (2)

  • 9f5cf29 fix(wasm): accept unpadded WABT section rows
  • 9cf3bcd fix(ci): refresh MIPS expectations and Windows test paths

📊 Changes

6 files changed (+147 additions, -12 deletions)

View changed files

📝 .github/workflows/ci.yml (+1 -1)
📝 docs/testing.md (+2 -1)
📝 scripts/verify-wasm-artifact.mjs (+25 -0)
📝 src/wasm/WabtOutput.test.ts (+104 -0)
📝 src/wasm/WabtOutput.ts (+1 -1)
📝 tests/boundary/filesystem/mipsAbiFlags.test.ts (+14 -9)

📄 Description

Summary

Fixes #1956. Valid WebAssembly modules that contain a DataCount section were rejected while parsing WABT 1.0.42 section output. inspect_wasm_artifact and rea inspect-wasm-artifact returned unreadable_output with reason Unrecognized WABT section row. after validation had already succeeded.

WABT right-aligns section names in a 9-column field. DataCount is 9 characters, so its row has no leading spaces or tabs. The section-row pattern required one or more leading spaces or tabs ([ \t]+). It now allows zero ([ \t]*).

Problem and expected behavior

Smallest trigger: compile this module with WABT 1.0.42 wat2wasm --enable-all, then inspect the bytes:

(module
  (memory 1)
  (data "x")
  (func (export "init")
    i32.const 0
    i32.const 0
    i32.const 1
    memory.init 0
    data.drop 0))

wasm-objdump -h prints:

DataCount start=0x00000023 end=0x00000024 (size=0x00000001) count: 1

That row is legal producer output. REA rejected it before constructing Evidence. Inspection should retain the DataCount section, the rest of the section table, and the decoded WAT. Malformed rows, inconsistent ranges, and a missing section header must still fail.

Change and scope

parseWabtOutput in src/wasm/WabtOutput.ts is the owner of this producer text. The only pattern change is [ \t]+ to [ \t]* on the section-row regex.

Leading whitespace is not what separates the header from section rows:

  • The header is matched first by a fixed prefix: a leading newline, module.wasm:\tfile format wasm 0x1, a blank line, and Sections:.
  • The row loop stops on the exact marker \nSection Details:\n, not on indentation.
  • Custom section names are framed by the quoted names from decoded WAT.
  • A row still requires KIND start=0xHEX end=0xHEX (size=0xHEX) including the space after the size group.
  • Range checks are unchanged: start is at least 8, start is at least the previous end, end minus start equals the size, end is within the artifact, and the last end equals the artifact length.

No section-kind allowlist was added. Padded unknown kinds were already accepted when the fields and ranges were well formed. Zero padding does not relax those checks.

Not included: a WABT installer, a second parser, or any change to validation flags, Evidence fields, or tool arguments.

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/wasm/WabtOutput.ts, after successful WABT validation, while parsing wasm-objdump section text.
  • CLI and MCP/tool-catalog contract: none. inspect_wasm_artifact / inspect-wasm-artifact keep the same input, output schema, and error categories. Modules that were wrongly rejected now return successful Evidence.
  • Provider, bridge, target-format, or platform compatibility: caller-supplied WABT 1.0.42 only. Confirmed with the official wabt-1.0.42-linux-x64 binaries. No new host tool is installed by REA.
  • Evidence, artifact, provenance, or reconstruction contract: none. Section ranges, original header text, decoded WAT, and failure reasons stay intact. The previously dropped DataCount row is now retained.
  • Process execution, authorization, cleanup, or containment impact: none.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact (CI generates and validates ignored catalogs and skills/; edit authored instructions in skill-src/ and never commit build outputs): none. No catalog, skill, or package metadata change.

Evidence and regression coverage

The unit test uses the real WABT 1.0.42 section table for the module above (61 bytes, last section end 0x3d). On the unfixed parser that test throws Unrecognized WABT section row. The same test then rejects a column-0 row with missing fields, a Sections: label in the table, a DataCount row missing the required space after the size, a size that does not match the range, a DataCount start that overlaps the previous section, an artifact length shorter than the last end, and output with the section header removed.

The existing golden test still rejects a short artifact, a size/range mismatch, unexpected text before Section Details, and a DataCount-shaped row that omits the trailing space.

  • Tests added or updated: src/wasm/WabtOutput.test.ts (unpadded DataCount acceptance plus malformed-output and bad-range rejections). scripts/verify-wasm-artifact.mjs compiles the issue module and requires an unpadded DataCount header line and section { kind: "DataCount", start: 0x23, end: 0x24, bytes: 1, description: "count: 1" } through the compiled CLI and real MCP client. docs/testing.md mentions that module in the real-WABT lane description.
  • Base reproduction or other evidence: executed. Before the pattern change, npm run test:focused -- src/wasm/WabtOutput.test.ts failed the new test with Error: Unrecognized WABT section row. at src/wasm/WabtOutput.ts:19. The other 3 tests in that file passed, including the extended golden rejection. Real wasm-objdump -h from WABT 1.0.42 printed the unpadded DataCount row used by the test.
  • User-visible CLI/MCP output (if applicable): before the fix, inspection failed with code: unreadable_output, reason: Unrecognized WABT section row. After the fix, the real-WABT lane accepts the module on both CLI and MCP, with the DataCount section above. Case count for that lane is 30 (24 before this module, plus 6 for the new source: CLI/MCP success and the truncated and invalid inputs).
  • Remaining proof gaps: the full verify:wasm:artifact process was run on the fixed revision, not rebuilt against the unfixed parser. The unit test is the base reproduction. macOS and Windows WABT binaries were not run. verify:wasm:package was not run.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

Node.js 24.18.0 and npm 11.16.0 (nvm use 24.18.0). Dependencies from npm ci. WABT 1.0.42 linux-x64 from the official release asset wabt-1.0.42-linux-x64.tar.gz, SHA-256 84895407a6bbb80e918f33b16b2fb2206021c150b6bc9ff6f761263a745ab131, matching the GitHub release digest. REA_WABT_BIN_DIRECTORY=/tmp/wabt/wabt-1.0.42/bin.

  • npm run test:focused -- src/wasm/WabtOutput.test.ts on the unfixed parser -- failed: 1 failed, 3 passed. New test threw Unrecognized WABT section row.
  • npm run test:focused -- src/wasm/WabtOutput.test.ts on this revision -- passed: 4 tests.
  • npm run verify:wasm:artifact -- passed: {"status":"passed","cases":30,"tool_profile":"wabt@1.0.42"}.
  • npm run check -- passed: turbo typecheck, lint, format:check, knip, and metadata:check (6 successful); lint reported 0 errors; architecture guards passed across 1151 source files.
  • npm run verify:test-discovery -- passed: discovered all 878 test files exactly once.
  • pre-push npm run check:fast -- passed: typecheck and lint, cached.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Previously valid modules stay valid. Modules whose only defect was a fully filled DataCount name column are now accepted. Invalid producer text still fails closed.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable. Real WABT 1.0.42 was verified on Linux x86_64. macOS and Windows WABT hosts were not run.
  • Package or release metadata impact: none. No changelog edit. Release Please can record the fix from the commit subject.
  • Security, privacy, process, or containment review: none. No new process, network, or file authority. The parser still rejects malformed section text and inconsistent ranges. No target execution or byte mutation.

Review checklist

  • This PR addresses a concrete problem or an agreed enhancement.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1963 **Author:** [@sathariels](https://github.com/sathariels) **Created:** 10/11/2026 **Status:** ✅ Merged **Merged:** 10/11/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/wasm-datacount-section-row` --- ### 📝 Commits (2) - [`9f5cf29`](https://github.com/morluto/rea/commit/9f5cf29092dcb165ceee52eaccefa053a0824e9c) fix(wasm): accept unpadded WABT section rows - [`9cf3bcd`](https://github.com/morluto/rea/commit/9cf3bcd5d01012d0dde5df3b0407a1583f1c69d3) fix(ci): refresh MIPS expectations and Windows test paths ### 📊 Changes **6 files changed** (+147 additions, -12 deletions) <details> <summary>View changed files</summary> 📝 `.github/workflows/ci.yml` (+1 -1) 📝 `docs/testing.md` (+2 -1) 📝 `scripts/verify-wasm-artifact.mjs` (+25 -0) 📝 `src/wasm/WabtOutput.test.ts` (+104 -0) 📝 `src/wasm/WabtOutput.ts` (+1 -1) 📝 `tests/boundary/filesystem/mipsAbiFlags.test.ts` (+14 -9) </details> ### 📄 Description <!-- PR title: fix(wasm): accept unpadded WABT section rows The title becomes the squash-merge commit subject and generated changelog entry. --> ## Summary Fixes #1956. Valid WebAssembly modules that contain a DataCount section were rejected while parsing WABT 1.0.42 section output. `inspect_wasm_artifact` and `rea inspect-wasm-artifact` returned `unreadable_output` with reason `Unrecognized WABT section row.` after validation had already succeeded. WABT right-aligns section names in a 9-column field. `DataCount` is 9 characters, so its row has no leading spaces or tabs. The section-row pattern required one or more leading spaces or tabs (`[ \t]+`). It now allows zero (`[ \t]*`). ## Problem and expected behavior Smallest trigger: compile this module with WABT 1.0.42 `wat2wasm --enable-all`, then inspect the bytes: ```wat (module (memory 1) (data "x") (func (export "init") i32.const 0 i32.const 0 i32.const 1 memory.init 0 data.drop 0)) ``` `wasm-objdump -h` prints: ```text DataCount start=0x00000023 end=0x00000024 (size=0x00000001) count: 1 ``` That row is legal producer output. REA rejected it before constructing Evidence. Inspection should retain the DataCount section, the rest of the section table, and the decoded WAT. Malformed rows, inconsistent ranges, and a missing section header must still fail. ## Change and scope `parseWabtOutput` in `src/wasm/WabtOutput.ts` is the owner of this producer text. The only pattern change is `[ \t]+` to `[ \t]*` on the section-row regex. Leading whitespace is not what separates the header from section rows: - The header is matched first by a fixed prefix: a leading newline, `module.wasm:\tfile format wasm 0x1`, a blank line, and `Sections:`. - The row loop stops on the exact marker `\nSection Details:\n`, not on indentation. - Custom section names are framed by the quoted names from decoded WAT. - A row still requires `KIND start=0xHEX end=0xHEX (size=0xHEX) ` including the space after the size group. - Range checks are unchanged: start is at least 8, start is at least the previous end, end minus start equals the size, end is within the artifact, and the last end equals the artifact length. No section-kind allowlist was added. Padded unknown kinds were already accepted when the fields and ranges were well formed. Zero padding does not relax those checks. Not included: a WABT installer, a second parser, or any change to validation flags, Evidence fields, or tool arguments. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/wasm/WabtOutput.ts`, after successful WABT validation, while parsing `wasm-objdump` section text. - CLI and MCP/tool-catalog contract: none. `inspect_wasm_artifact` / `inspect-wasm-artifact` keep the same input, output schema, and error categories. Modules that were wrongly rejected now return successful Evidence. - Provider, bridge, target-format, or platform compatibility: caller-supplied WABT 1.0.42 only. Confirmed with the official `wabt-1.0.42-linux-x64` binaries. No new host tool is installed by REA. - Evidence, artifact, provenance, or reconstruction contract: none. Section ranges, original header text, decoded WAT, and failure reasons stay intact. The previously dropped DataCount row is now retained. - Process execution, authorization, cleanup, or containment impact: none. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `skill-src/` and never commit build outputs): none. No catalog, skill, or package metadata change. ## Evidence and regression coverage The unit test uses the real WABT 1.0.42 section table for the module above (61 bytes, last section end `0x3d`). On the unfixed parser that test throws `Unrecognized WABT section row.` The same test then rejects a column-0 row with missing fields, a `Sections:` label in the table, a DataCount row missing the required space after the size, a size that does not match the range, a DataCount start that overlaps the previous section, an artifact length shorter than the last end, and output with the section header removed. The existing golden test still rejects a short artifact, a size/range mismatch, unexpected text before `Section Details`, and a DataCount-shaped row that omits the trailing space. - Tests added or updated: `src/wasm/WabtOutput.test.ts` (unpadded DataCount acceptance plus malformed-output and bad-range rejections). `scripts/verify-wasm-artifact.mjs` compiles the issue module and requires an unpadded `DataCount` header line and section `{ kind: "DataCount", start: 0x23, end: 0x24, bytes: 1, description: "count: 1" }` through the compiled CLI and real MCP client. `docs/testing.md` mentions that module in the real-WABT lane description. - Base reproduction or other evidence: executed. Before the pattern change, `npm run test:focused -- src/wasm/WabtOutput.test.ts` failed the new test with `Error: Unrecognized WABT section row.` at `src/wasm/WabtOutput.ts:19`. The other 3 tests in that file passed, including the extended golden rejection. Real `wasm-objdump -h` from WABT 1.0.42 printed the unpadded DataCount row used by the test. - User-visible CLI/MCP output (if applicable): before the fix, inspection failed with `code: unreadable_output`, `reason: Unrecognized WABT section row.` After the fix, the real-WABT lane accepts the module on both CLI and MCP, with the DataCount section above. Case count for that lane is 30 (24 before this module, plus 6 for the new source: CLI/MCP success and the truncated and invalid inputs). - Remaining proof gaps: the full `verify:wasm:artifact` process was run on the fixed revision, not rebuilt against the unfixed parser. The unit test is the base reproduction. macOS and Windows WABT binaries were not run. `verify:wasm:package` was not run. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed Node.js 24.18.0 and npm 11.16.0 (`nvm use 24.18.0`). Dependencies from `npm ci`. WABT 1.0.42 linux-x64 from the official release asset `wabt-1.0.42-linux-x64.tar.gz`, SHA-256 `84895407a6bbb80e918f33b16b2fb2206021c150b6bc9ff6f761263a745ab131`, matching the GitHub release digest. `REA_WABT_BIN_DIRECTORY=/tmp/wabt/wabt-1.0.42/bin`. - `npm run test:focused -- src/wasm/WabtOutput.test.ts` on the unfixed parser -- failed: 1 failed, 3 passed. New test threw `Unrecognized WABT section row.` - `npm run test:focused -- src/wasm/WabtOutput.test.ts` on this revision -- passed: 4 tests. - `npm run verify:wasm:artifact` -- passed: `{"status":"passed","cases":30,"tool_profile":"wabt@1.0.42"}`. - `npm run check` -- passed: turbo typecheck, lint, format:check, knip, and metadata:check (6 successful); lint reported 0 errors; architecture guards passed across 1151 source files. - `npm run verify:test-discovery` -- passed: discovered all 878 test files exactly once. - pre-push `npm run check:fast` -- passed: typecheck and lint, cached. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Previously valid modules stay valid. Modules whose only defect was a fully filled DataCount name column are now accepted. Invalid producer text still fails closed. - Real Hopper/Ghidra, browser, or OS coverage: not applicable. Real WABT 1.0.42 was verified on Linux x86_64. macOS and Windows WABT hosts were not run. - Package or release metadata impact: none. No changelog edit. Release Please can record the fix from the commit subject. - Security, privacy, process, or containment review: none. No new process, network, or file authority. The parser still rejects malformed section text and inconsistent ranges. No target execution or byte mutation. ## Review checklist - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 00:57:09 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4937
No description provided.