fix: validate tracked callsign before navigation #35
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/m5-track-callsign-validation"
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?
Fixes M5 from bugs.md.
handle_track_callsign/2normalized the input but never validated it beforepush_patch("/#{callsign}"). A callsign containing/(the commonW5ABC/Mportable suffix),?,#or%produced a path the router cannot match, solive_link_info!/3raised and the LiveView died on a normal form submit. Because the bad callsign was assigned before the patch, it also poisoned every subsequent URL update.Changes:
track_validated_callsign/2, which applies the sameParamUtils.valid_callsign?/1contract as the callsign search box; invalid input gets an error flash and no navigation.push_patchnow uses a verified~proute, andtrack_validated_callsignonly ever navigates for validated callsigns.Tests: regression test in
index_test.exssubmitsW5ABC/M,W5ABC?Q, andW5ABC#Qand asserts the view survives and a subsequent valid callsign still navigates.Verification: focused callsign suites 170 passed, full suite 2236 passed, credo strict clean, dialyzer clean (43 pre-existing suppressed, no new warnings).
🤖 Skippy PR review
1 finding — 1 blocking before merge.
lib/aprsme_web/live/map_live/events.ex:180Reviewed
b0ff0a5a54f6. Commentskippy reviewto re-run.@ -186,0 +177,4 @@# and kills the view on a normal form submit — and assigning the bad callsign# first would poison every later URL update. Same contract as the search box.defp track_validated_callsign(callsign, socket) doif ParamUtils.valid_callsign?(callsign) do🟡 Warning — Guard covers the form only — the URL entry point still poisons tracked_callsign
Index.mount/3(lib/aprsme_web/live/map_live/index.ex:59) assignstracked_callsignstraight fromparams["callsign"] || params["call"]with trim/upcase only, and Plug decodes query strings, so/?call=W5ABC/M(no encoding needed;/W5ABC%2FMalso works) still puts"W5ABC/M"in the socket. The nextupdate_url_with_current_state— trail-duration/hist change or clear-tracking,events.ex:417— builds"/#{socket.assigns.tracked_callsign}?lat=…"as a plain string andpush_patches it, no route matches two segments,live_link_info!/3raises, and the view dies. Same crash this PR fixes, reached from a URL instead of the form (the comment here names that poison vector as in scope). Fix: validate inmount/3beforeState.finalize—if ParamUtils.valid_callsign?(tracked_callsign), do: tracked_callsign, else: ""— so the bad value never reaches an assign.Resolved 1 of 1 earlier finding —
mount/3now drops unroutable URL callsigns (routable_callsign?/1) before they reach an assign, so the/?call=W5ABC/Mpoison vector is closed. 0 still open.Nothing new in
b0ff0a5a..aced185d. I checked the guard's edges: values that stay a single path segment (.., spaces, raw invalid UTF-8 via%FF) still match/:callsignand don't raise inURI.parse/String.trim/upcase, so the new check is sufficient for the crash class it targets — the mount check being looser than the form'svalid_callsign?/1is deliberate and changes no failure path.