Skip to content

fix(geometry): measure text overflow against the content box - #230

Merged
LeadcodeDev merged 1 commit into
chantier/audit-2026-09from
fix/geometry-text-overflow-box
Sep 22, 2026
Merged

LeadcodeDev merged 1 commit into
chantier/audit-2026-09from
fix/geometry-text-overflow-box

Conversation

@LeadcodeDev

Copy link
Copy Markdown
Owner

Severity Low, category correctness. Location: crates/rustmotion/src/cli/commands/geometry.rs:785

Impact

bbox here is raw_bbox = bbox_of(layout) (geometry.rs:272, 376-383), i.e. layout.width — the BORDER box. But LegacyPaintDispatcher::dispatch (crates/rustmotion-components/src/legacy_dispatch.rs) hands every non-codeblock painter a synthetic BoxLayout { width: cw, height: ch, border/padding: zero } taken from layout.content_box() and translates the canvas to the content-box origin. So Text::paint wraps and draws inside cw, not layout.width. A white-space: nowrap text with style.padding: "0 24px" in a 300px box has cw = 252; a natural line width of 280px paints 28px past the box's right edge, yet 280 > 300 is false and nothing is reported. The sibling check check_content_overflows_box (geometry.rs:848) does this correctly via layout.content_box() — the two checks disagree about which box text lives in, and the flagship unwrappable_text_overflow is the one that is wrong. The gap equals padding.left + padding.right + border.left + border.right.

Fix

In walk/walk_anim, pass layout.content_box()'s (x, y, w, h) to check_unwrappable_text instead of raw_bbox, matching check_content_overflows_box. Keep raw_bbox for check_viewport (which genuinely tests the border box against the frame).

Evidence the audit read

let (natural_w, _) = intrinsic.measure(
    (None, None),
    (AvailableSpace::Definite(bbox.w), AvailableSpace::MaxContent),
);
if natural_w > bbox.w + 0.5 {

Stacked on fix/validate-relative-paths, which carries the previous finding of this workstream. GitHub shows only this finding's diff; merge in order.

Part of the September 2026 audit remediation chantier. Refs #220 (RM-31).

@LeadcodeDev LeadcodeDev added the bug Something isn't working label Sep 21, 2026
@LeadcodeDev LeadcodeDev self-assigned this Sep 21, 2026
@LeadcodeDev
LeadcodeDev force-pushed the fix/validate-relative-paths branch from 95e7b59 to 1ac44d6 Compare September 21, 2026 23:39
@LeadcodeDev
LeadcodeDev force-pushed the fix/geometry-text-overflow-box branch from 25b96c4 to b142b14 Compare September 21, 2026 23:39
@LeadcodeDev
LeadcodeDev force-pushed the fix/validate-relative-paths branch from bef57d4 to b62a1cc Compare September 22, 2026 06:09
@LeadcodeDev
LeadcodeDev force-pushed the fix/geometry-text-overflow-box branch from 53cb999 to da0db80 Compare September 22, 2026 06:09
@LeadcodeDev
LeadcodeDev force-pushed the fix/validate-relative-paths branch from b62a1cc to d585af3 Compare September 22, 2026 08:33
@LeadcodeDev
LeadcodeDev force-pushed the fix/geometry-text-overflow-box branch from da0db80 to 82dafe2 Compare September 22, 2026 08:33
@LeadcodeDev
LeadcodeDev force-pushed the fix/validate-relative-paths branch from d585af3 to 4984fbc Compare September 22, 2026 08:43
@LeadcodeDev
LeadcodeDev force-pushed the fix/geometry-text-overflow-box branch from 82dafe2 to 931a445 Compare September 22, 2026 08:43
@LeadcodeDev
LeadcodeDev changed the base branch from fix/validate-relative-paths to chantier/audit-2026-09 September 22, 2026 08:52
@LeadcodeDev
LeadcodeDev force-pushed the fix/geometry-text-overflow-box branch from 931a445 to aa62b65 Compare September 22, 2026 08:58
`bbox` here is `raw_bbox = bbox_of(layout)` (geometry.rs:272, 376-383), i.e. `layout.width` — the BORDER box. But `LegacyPaintDispatcher::dispatch` (crates/rustmotion-components/src/legacy_dispatch.rs) hands every non-codeblock painter a synthetic `BoxLayout { width: cw, height: ch, border/padding: zero }` taken from `layout.content_box()` and translates the canvas to the content-box origin. So `Text::paint` wraps and draws inside `cw`, not `layout.width`. A `white-space: nowrap` text with `style.padding: "0 24px"` in a 300px box has `cw = 252`; a natural line width of 280px paints 28px past the box's right edge, yet `280 > 300` is false and nothing is reported. The sibling check `check_content_overflows_box` (geometry.rs:848) does this correctly via `layout.content_box()` — the two checks disagree about which box text lives in, and the flagship `unwrappable_text_overflow` is the one that is wrong. The gap equals `padding.left + padding.right + border.left + border.right`.

Refs #220
@LeadcodeDev
LeadcodeDev force-pushed the fix/geometry-text-overflow-box branch from aa62b65 to a252cd5 Compare September 22, 2026 09:04
@LeadcodeDev
LeadcodeDev merged commit e36dfec into chantier/audit-2026-09 Sep 22, 2026
LeadcodeDev added a commit that referenced this pull request Sep 22, 2026
`bbox` here is `raw_bbox = bbox_of(layout)` (geometry.rs:272, 376-383), i.e. `layout.width` — the BORDER box. But `LegacyPaintDispatcher::dispatch` (crates/rustmotion-components/src/legacy_dispatch.rs) hands every non-codeblock painter a synthetic `BoxLayout { width: cw, height: ch, border/padding: zero }` taken from `layout.content_box()` and translates the canvas to the content-box origin. So `Text::paint` wraps and draws inside `cw`, not `layout.width`. A `white-space: nowrap` text with `style.padding: "0 24px"` in a 300px box has `cw = 252`; a natural line width of 280px paints 28px past the box's right edge, yet `280 > 300` is false and nothing is reported. The sibling check `check_content_overflows_box` (geometry.rs:848) does this correctly via `layout.content_box()` — the two checks disagree about which box text lives in, and the flagship `unwrappable_text_overflow` is the one that is wrong. The gap equals `padding.left + padding.right + border.left + border.right`.

Refs #220
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant