diff --git a/lib/microwaveprop/aprs/path_parser.ex b/lib/microwaveprop/aprs/path_parser.ex index 6fe08458..59d44c0c 100644 --- a/lib/microwaveprop/aprs/path_parser.ex +++ b/lib/microwaveprop/aprs/path_parser.ex @@ -36,9 +36,12 @@ defmodule Microwaveprop.Aprs.PathParser do heard_at: DateTime.t() } - @alias_regex ~r/^(WIDE[12](-[0-9])?|TRACE[12](-[0-9])?|RELAY|ECHO|GATE|NOGATE|RFONLY)$/ + # WIDEn-N / TRACEn-N allow n and N up to 7 per the APRS New-N paradigm. + @alias_regex ~r/^(WIDE[1-7](-[1-7])?|TRACE[1-7](-[1-7])?|RELAY|ECHO|GATE|NOGATE|RFONLY)$/ @callsign_regex ~r/^[A-Z0-9]{1,2}[0-9][A-Z]{1,3}(-[0-9]{1,2})?$/ - @q_construct_regex ~r/^qA[A-Za-z]$/ + # Explicit allowlist of real APRS-IS Q-constructs (RFC qAR/qAC/qAo/etc.) + # rather than `qA[A-Za-z]` which would over-match `qAa`, `qAd`, … + @q_constructs ~w(qAC qAX qAU qAo qAO qAS qAr qAR qAZ qAI) @spec parse_hops( sender_callsign :: String.t(), @@ -72,7 +75,7 @@ defmodule Microwaveprop.Aprs.PathParser do defp classify(token) do cond do - Regex.match?(@q_construct_regex, token) -> :q_construct + token in @q_constructs -> :q_construct token in ["TCPIP", "TCPXX"] -> :internet Regex.match?(@alias_regex, token) -> :alias Regex.match?(@callsign_regex, token) -> :callsign