Enforce declared capability limits; add name-length limits - #7
Merged
Conversation
capabilities-0.2 declared several limits that nothing ever checked. A profile could validate clean while exceeding them, which is the failure mode issue #3 was filed about: a limit that never fires is worse than an absent one, because it looks enforced. Adds the four name-length limits from #3 section 4 and wires up the two that are enforceable against profile 0.1 today: - schema: declare max_channel_name_chars, max_zone_name_chars, max_scan_list_name_chars, max_contact_name_chars. The limits block is additionalProperties: false, so undeclared keys are rejected outright. - baofeng_dm32: 16/16/10/16, per the values in #3. - profile.py: _check_name_length() helper; zone names checked during profile validation. - resolved.py: channel display names checked as they resolve, which is the first point where a channel name exists (0.1 profiles select assignments; names come from SSRF). Absent limits skip their check, matching the existing degrade-rather-than- fail behavior of _check_radio_support, so an incomplete capabilities file does not start producing false failures. Scan-list and contact name limits are declared but not yet enforced; profile 0.1 has no scan lists or contacts to check them against. They are recorded now so 0.2 designs against them instead of rediscovering them on hardware. Also extracts _load_capabilities() so the resolver reads capabilities through the same schema-validated path as the validator rather than re-reading the file. Tests: 8 -> 13. Includes an at-the-limit accept, an absent-limit skip, and a resolver-path rejection. Verified the new tests fail against the prior commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes part of #3 (section 4), and fixes a gap the issue did not name.
The gap
capabilities-0.2declares nine limit keys.profile.pychecks three:max_zones,max_channels_per_zone,max_channels(lines 214/244/251 onmain). Everything added inaabcddd—max_scan_lists,max_channels_per_scan_list,max_rx_group_lists,max_talkgroups_per_rx_group_list— is declared, schema-validated, andnever checked against a profile.
That is the same failure shape #3 was filed about. A limit that validates
clean and never fires is worse than an absent one, because it looks
enforced. #3 frames the problem as "the numbers are wrong"; the numbers are
right as of
aabcddd, but most of them are inert.What this does
Adds the four name-length limits from #3 section 4, and enforces the two
that apply to profile
0.1today.max_channel_name_chars,max_zone_name_chars,max_scan_list_name_chars,max_contact_name_chars.limitsisadditionalProperties: false, so these had to be declared or they wouldbe rejected.
radios/baofeng_dm32:16 / 16 / 10 / 16, per DM-32 capabilities.json models the CPS ceiling, not the radio's real constraints #3.profile.py:_check_name_length(); zone names checked duringprofile validation.
resolved.py: channel display names checked as they resolve. That isthe first point at which a channel name exists —
0.1profiles selectassignments, and names come from SSRF, so this check cannot live in
profile validation.
Absent limits skip their check, matching the existing
degrade-rather-than-fail behavior of
_check_radio_support. An incompletecapabilities file does not start producing false failures.
Also extracts
_load_capabilities()so the resolver reads capabilitiesthrough the same schema-validated path as the validator, instead of
re-reading the file.
Naming note
Used
max_scan_list_name_chars, not #3'smax_scanlist_name_chars—consistent with the existing
max_scan_lists/max_channels_per_scan_list. Easy to change if you would rather match theissue text.
Still not enforced, deliberately
max_scan_list_name_charsandmax_contact_name_charsare declared butunchecked: profile
0.1has no scan lists or contacts to check themagainst. Recorded now so
0.2designs against them rather thanrediscovering them on hardware — which is #3's own argument for filing
early.
The scan-list count limits stay inert for the same reason. Worth a
follow-up issue so they do not sit there looking enforced.
Verification
New coverage: over-limit rejection, at-limit acceptance (16 chars must
pass, not fail), absent-limit skip, and rejection via the resolver path.
Confirmed the new tests actually exercise the change — stashed the diff and
re-ran: 8 pass on
aabcddd, so the 5 new tests genuinely fail without itrather than passing vacuously.
Not hardware-tested. These are storage-derived limits from #3's cited
sources; nothing here has been written to a radio.