render: blank glyphs grow the glyph slot map and shape cache without bound #406
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis#406
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Two client-side glyph caches grow without bound on blank glyphs, which PTY output controls.
GlyphIndex::slots(crates/felis-render-wgpu/src/glyphs.rs) caches a blank rasterization asNone. ANoneentry takes no atlas space, so it never triggersreset_atlas_full, and that reset is the only thing that clears the map.ShapeCache(crates/felis-shaping/src/lib.rs,get_or_insert_sized) evicts oncebytes_usedexceeds its cap. A blank bitmap adds 0 bytes, so blank entries never count toward the cap.A key is
(char, cell_height, SizingKey), and a producer chooses both the char and the OSC 66 sizing. The OSC 66 ranges alone give 7 × 8 × 16 × 16 × 3 × 3 ≈ 1.3 × 10^5 sizings per char, before the four font styles. Multiplied by the chars that rasterize blank (the Unicode space characters, U+2800, and anything the font stack renders empty), this leaves on the order of 10^7 distinct keys. Each one becomes resident for the life of the client after being displayed once.This contradicts
docs/explanation/security-model.md"Resource exhaustion": "every unbounded quantity is capped where it is owned".This finding comes from reading the source. It has not been reproduced or measured.
Found by
Review of the foldhash change to the same maps (#397). Seeding the hasher randomly there addresses collision cost, but not size.
Direction (not decided)
shaped_runsalready does withSHAPED_RUN_CACHE_MAX.Either way, a test should pin the bound: display N distinct blank keys and assert that the map size stays under the cap.