ReviewOS

home-lang/home

fix(markdown): reject tables wider than 128 columns

#750
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Home defines TABLE_MAXCOLCOUNT = 128 but its stale isTableUnderline loop continues counting past the limit. The alignment array write is guarded, yet table_col_count remains unbounded and processTableRow pads every short body row to that count. A delimiter row with N columns followed by M bare-pipe rows can therefore emit O(N x M) empty cells from linear-size input.\n\nBun's live Rust returns not-a-table immediately after incrementing col_count beyond TABLE_MAXCOLCOUNT. The copied regression at packages/runtime/test/test/js/bun/md/md-edge-cases.test.ts requires:\n- 128 columns still render as a table\n- 129 columns do not\n- a 1,000-column x 2,000-row adversarial input remains proportional and does not emit a table\n\nAcceptance:\n- port Bun's exact post-increment TABLE_MAXCOLCOUNT rejection\n- preserve the 128-column boundary and ordinary table semantics\n- no output truncation or input-specific shortcut\n- run focused semantics and guarded adversarial verification\n- update #66 with exact evidence

9 days ago

Implemented and pushed in 49e5162.\n\nPorted Bun's exact post-increment TABLE_MAXCOLCOUNT rejection in isTableUnderline. Home now treats delimiter rows wider than 128 columns as ordinary Markdown instead of carrying an unbounded col_count into per-row padding. This is parser validation, not output truncation.\n\nVerification:\n- focused real Markdown leaf suite: 17/17 passed\n- 128 columns still render as a table\n- 129 columns do not render as a table\n- adversarial 1,000-column delimiter plus 2,000 sparse rows: 8,004-byte input -> 8,011-byte output, no table amplification\n- guarded peak tree footprint: 218 MB under the fixed 3,840 MB ceiling\n- zig ast-check, zig fmt --check, and git diff --check passed

Sign in to comment on this issue.