Skip to content

fix(ui): clamp column width to avoid makeslice panic on huge -width#101

Merged
peczenyj merged 1 commit into
develfrom
fix/truncpad-huge-width
Jun 3, 2026
Merged

fix(ui): clamp column width to avoid makeslice panic on huge -width#101
peczenyj merged 1 commit into
develfrom
fix/truncpad-huge-width

Conversation

@peczenyj
Copy link
Copy Markdown
Owner

@peczenyj peczenyj commented Jun 3, 2026

What

Clamp the side-by-side column width to maxColWidth (1<<16 cells) in truncPad and renderSideBySide.

Why

A user-supplied -width flowed unclamped into the renderer; both runewidth.FillRight and the divider's strings.Repeat would attempt a multi-GB allocation:

$ structalign -diff=side -width=4611686018427387904 ./_example
panic: runtime error: makeslice: len out of range

Found by fuzzing during the ClusterFuzzLite work (#99)fuzz_trunc_pad crashed within 5 seconds in the OSS-Fuzz container. The bug predates #94: the old hand-rolled loop panicked identically in strings.Repeat(" ", w-total).

Fix shape

  • truncPad: w = min(w, maxColWidth) — the fuzzed function is now total.
  • renderSideBySide: clamp once into a local width shared by the header, divider, and rows (keeps exact column geometry).

Verification

  • TDD: regression tests TestTruncPadHugeWidth + TestRenderSideBySideHugeWidth reproduced the exact panic (RED) before the fix, pass after (GREEN).
  • CLI repro now renders (clamped) instead of crashing.
  • fuzz_trunc_pad in the OSS-Fuzz container: 64k+ executions / 60s, zero crashes (was: crash in <5s).
  • task ci green (204 tests, lint + go-consistent 0 issues).

Closes #100

🤖 Generated with Claude Code

A user-supplied -width propagated unclamped into the side-by-side
renderer, where both truncPad (via runewidth.FillRight) and the divider
(strings.Repeat) would attempt a multi-gigabyte allocation and panic
with "makeslice: len out of range":

    structalign -diff=side -width=4611686018427387904 ./pkg

Clamp the per-side width to maxColWidth (1<<16 cells, far wider than
any real terminal) inside truncPad - making the fuzzed function total -
and once in renderSideBySide so the divider shares the bound.

Found by fuzzing during the ClusterFuzzLite integration (#99):
fuzz_trunc_pad crashed within seconds in the OSS-Fuzz container. The
bug predates #94 - the old hand-rolled loop panicked identically in
strings.Repeat. After the fix the target runs 64k+ executions clean.

Closes #100

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@peczenyj peczenyj merged commit ee2be3d into devel Jun 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Panic on huge -width: makeslice len out of range in side-by-side rendering

1 participant