Repository navigation
Conversation
|
Verified: No production defect found in the scoped review of
Optional test improvement: The new cyclic-case row assertion also passes on the unpatched baseline with Lua 5.5.1: the existing Review informationTest scope: Synthetic configurations through the actual menu script, with stubbed Community review: Independent automated community review, unaffiliated with the Omarchy team, intended to help prepare PRs for their review. Automated AI review: Astra Medium initial inspection, independent Opus 5.5 High and GPT 6 Sol Xhigh technical reviews, followed by Astra synthesis against source and retained test evidence and a fresh Astra Medium editorial check. |
The cyclic-case row assertion also passes on an unpatched baseline: the existing pcall catches Lua's stack overflow and still yields a fallback row, so the test could not detect removal of the cycle check. Run the case with DEBUG=1 and assert the cycle-specific diagnostic, per the omacom#12916 review.
The Lua bind scan dofile's the user's config under a fake environment and serializes bind arguments back into dispatcher expressions, whose size doubles every nesting level. A cyclic table, a nested dispatcher chain or a runaway loop grew without bound: the scan ballooned to ~18GB, the OOM killer fired, and Hyprland segfaulted tearing down its NVIDIA context. The uncapped child also left bash parked in anon_pipe_read forever. Containment in layers, so a runaway fails the scan instead of the session: - lua_literal detects cycles, caps nesting at 10 and total serialized size at 64KiB, aborting the scan cleanly - the config run carries an instruction watchdog, so an infinite loop burns its budget and pcall catches it - the lua child runs under timeout 20 with a 1GiB address-space ulimit: whatever escapes the caps above cannot take the session's memory - stale keybindings.XXXXXX mktemp scratch from killed refreshes is pruned; the records glob never matched those names A failed scan is the safe outcome: the menu renders binds without their dispatch, which every downstream path already handles. Regression tests cover all three runaways (cyclic argument, 40-level nested dispatcher, infinite config loop) plus the real-config path, which still completes in 0.23s.
The cyclic-case row assertion also passes on an unpatched baseline: the existing pcall catches Lua's stack overflow and still yields a fallback row, so the test could not detect removal of the cycle check. Run the case with DEBUG=1 and assert the cycle-specific diagnostic, per the omacom#12916 review.
5331744 to
cd56498
Compare
|
Rebased onto current The conflict was upstream's Checked after the rebase:
|
|
Looked at this at What I did check: the branch sits on current Next: a later run, when the second model is available, will classify it, reproduce the runaway on a worker against |
|
For the maintainer's comparison: the instruction-budget hook and the |
Summary
SUPER + Kcould OOM-kill the session and take Hyprland down (issue #12852). Root cause: the keybindings menu's Lua bind scan dofiles the user's config under a fakehlenvironment, and two growth paths there were unbounded:hl.dsp.*(...)calls doubles in size every level — ~35 levels is ~16GB, matching the reported 18GB.lua_literal()recursed through tables with no cycle detection, so a cyclic config argument recursed without bound.The uncapped
luachild then exhausted RAM+swap (kernel OOM killer fired on theluaprocess), Hyprland segfaulted in its NVIDIA EGL teardown, and the parent bash parked inanon_pipe_readforever — the reported hang with 0-bytekeybindings.*temp files.Containment in layers — a runaway now fails the scan instead of the session
lua_literalcaps: cycle detection, max nesting depth 10, max serialized size 64KiB — the scan aborts cleanly on any of them.debug.sethook) around the config run: a config stuck in an infinite loop burns its budget and thepcallcatches it instead of spinning until the OOM killer arrives.luachild runs undertimeout 20with a 1GiB address-space ulimit, so anything that slips past the Lua caps still cannot take the session's memory.keybindings.XXXXXXmktemp files the records-glob prune never matched; those now get cleaned.A failed scan is the safe outcome: the menu renders binds without their dispatch, a shape every downstream path already handles (unresolved
__luabinds render as plain rows today).Test plan
test/shell.d/keybindings-menu-test.sh: cyclic bind argument, 40-level nested dispatcher bomb, infinite config loop — each must fail the scan and still render the menu row. All 22 assertions in the suite pass, plusmenu-guards-test.shandbin-style-test.sh.hyprland.luascans in 0.23s with all 225 entries rendered — the watchdog does not false-positive on legitimate configs.Closes #12852.