- Beacon detail endpoints (LiveView + REST API) now hide unapproved beacons from anonymous and unauthorized viewers; only the submitter and admins can see pending records before approval. Adds Beacons.get_visible_beacon/2 with scope-aware checks. - API contact pagination now honors per_page end-to-end. Radio.list_contacts/1 accepts :per_page and clamps to 200. - API rate limiter: ETS table is now owned by a long-lived Sweeper GenServer (won't die with a request task); Sweeper periodically prunes expired-window rows to bound memory; init_table/0 race is rescued. - /scores/cells and /weather/cells: add per-IP rate limiting and a shared GridBounds clamp/413 guard so global / oversized viewports no longer drive unbounded binary responses. - NEXRAD PNG unfilter (sub/up/average/paeth): replace acc++[byte] + Enum.at(acc, idx-bpp) with O(n) binary recursion. Decode time for the 12200x5400 n0q frame goes from quadratic to linear. - LiveTableFooter.parse_page and ScoresFile.fetch_bound: switch String.to_integer/String.to_float to Integer.parse/Float.parse, fall back to defaults instead of raising. - PathLive and MapLive band-event handlers: replace String.to_integer(params["band"]) with parse_int / parse_band_param so a non-numeric band parameter no longer crashes the LiveView.
28 lines
1.3 KiB
Markdown
28 lines
1.3 KiB
Markdown
# Bugs Found 2026-05-11
|
|
|
|
The first batch (7 items: pending-beacon access control, per_page contract,
|
|
rate-limiter ETS lifecycle, unbounded grid endpoints, NEXRAD PNG quadratic
|
|
unfilter, LiveTableFooter parser, ScoresFile parser) was fixed and removed
|
|
from this file as each was resolved. The items below are additional bugs
|
|
surfaced by a follow-up audit.
|
|
|
|
## A. `String.to_integer` on user-controlled `band` param crashes LiveViews
|
|
|
|
**Status:** Fixed.
|
|
**Severity:** High
|
|
**Category:** Availability / unhandled crash on user input
|
|
**Files:**
|
|
- `lib/microwaveprop_web/live/path_live.ex` (formerly lines 227, 284)
|
|
- `lib/microwaveprop_web/live/map_live.ex` (formerly line 198)
|
|
|
|
`PathLive.handle_event("calculate", …)` and the auto-calculate path both
|
|
called `String.to_integer(params["band"])` directly on the `band` form
|
|
parameter. `MapLive.handle_event("select_band", %{"value" => band}, …)`
|
|
did the same. A non-numeric `band` value — supplied via a hand-crafted
|
|
URL (`/path?band=abc`) or a misbehaving JS hook — raised `ArgumentError`
|
|
inside the LiveView process and crashed the channel.
|
|
|
|
**Fix:** Use the existing `LiveHelpers.parse_int/2` (PathLive) and the
|
|
existing `parse_band_param/1` plus a small `normalize_band_event/1` helper
|
|
(MapLive). Unknown bands now fall back to a safe default or a no-op
|
|
instead of crashing the process.
|