ui-redesign #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "ui-redesign"
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?
api_preset_save validated the payload via _clean_bands but then wrote payload.get("bands", []) - the raw request body - to disk. _clean_bands silently drops any band with enabled:false, so a disabled band carrying an HTML/JS injection string in freq passed validation only because it was skipped, yet still landed verbatim in the persisted preset JSON. The frontend's loadPresetIntoEditor force-enables all bands on load and buildTable renders band fields via innerHTML, so loading the poisoned preset executes attacker script same-origin, which can then POST /api/flash without the confirm dialog. Persist _clean_bands' return value (validated, type-coerced, enabled-only) instead of the raw payload. No functionality loss: the frontend already sends enabled-only bands in its payload. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>cmd_watch's poll loop only caught (DuskError, ValueError) around the parse/apply block. Editors and REW commonly save via write-temp-then- rename ("atomic save"): cmd_watch detects the mtime change via stat, then calls parse_rew(args.file), which does its own open() - if the rename lands in between, that open() raises FileNotFoundError (an OSError subclass), uncaught, which killed the watcher process entirely. Add OSError to the except tuple so a transient file-not-found during an atomic save is reported and retried on the next tick, like other recoverable errors, instead of crashing the watcher. (cmd_watch_device already guards its own device_present() call separately and is unaffected.) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>test_never_writes_index_ten_or_higher called dq.apply_runtime(tp, self.BANDS * 1, -4.0) - self.BANDS * 1 is a no-op list multiplication (single-band list, not 10 bands), so apply_runtime only ever wrote to indexes 0-1. The assertion `words[1] <= 9` was trivially true regardless of whether the index >= 10 guard existed, making the test vacuous for the hardware-safety invariant it claims to pin ("never write runtime DSP index >= 10"). Reuse the existing 10-frequency list from test_ten_band_mode_folds_into_index_zero (hoisted to a shared TEN_BAND_FREQS class tuple) so the test actually drives ten bands and writes span indexes 0-9. Also add test_write_dsp_refuses_alias_index, exercising the write_dsp MAX_SAFE_INDEX guard directly (indexes 10, 11, -1 all raise ValueError) rather than only indirectly through apply_runtime's band count - so the guard itself is pinned and fails loudly if ever weakened or removed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>Live exploration on chip 31988 confirms the Task 21 premise: switch_eq_mode (cmd 90) reloads the runtime DSP. Walked modes 1-12; modes 1-5 are distinct factory curves, mode 6+ read back identical to mode 5 (firmware keeps the last valid preset loaded rather than erroring on out-of-range mode numbers - read_eq_mode echoes back whatever was written even out of range). A 0.4s settle after switch is necessary and sufficient; immediate reads sometimes still show the previous mode's curve. Restoring the original mode reproduced the original custom curve exactly. Captured docs/factory-curves/mode-{1..5}.txt via `factory-presets --save-dir`. All bands decoded as clean PK filters (no raw-biquad fallback needed, so no fold-fit regression cases to add). Findings recorded as comments atop cmd_factory_presets. Device left on mode 0 with the original custom curve intact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>