Describe the bug
group_number_ranges() in scripts/convert.py compresses a list of reference numbers (CAPEC/ASVS/MASTG IDs) into ranges for the printed cards, e.g. [25, 26, 27] -> "25-27". It does this using itertools.groupby, which only detects consecutive runs correctly if the input is already sorted ascending with no duplicates:
data_numbers = [int(s) for s in data] # no sort, no dedupe for k, g in groupby(enumerate(data_numbers), lambda x: x[0] - x[1]): ...
Several source/*mappings*.yaml files list numbers out of order or with duplicates (they're hand-maintained), which produces incorrect, non-ascending, or duplicated text on the generated cards.
To Reproduce
source/mobileapp-mappings-2.0.yaml, suit CRM, card CRMX, tag capec: [20, 116, 117, 97, 112, 485]
- Run this through the converter's
check_make_list_into_text() (used by build_template_dict() for every card tag)
- Output is
"20, 116-117, 97, 112, 485" — not ascending, so the reader can't tell at a glance that 112 and 485 haven't already been covered.
A worse case, source/webapp-mappings-2.2.yaml suit WC, card JOB: capec: [184, 242, 416, 438, 441, 444, 523, 518, 519, 548, 636, 691] renders as "184, 242, 416, 438, 441, 444, 523, 518-519, 548, 636, 691" — 518-519 appears after 523, which reads as a typo/data error to anyone using the card for actual ASVS/CAPEC lookups.
A duplicate case: ["5", "5", "6"] renders as "5, 5-6" instead of "5-6".
Expected behavior
Reference numbers should render sorted ascending, de-duplicated, with consecutive runs grouped into ranges, regardless of the order they appear in the source YAML.
Affected files (confirmed by scanning all mapping files)
mobileapp-mappings-1.0.yaml, mobileapp-mappings-1.1.yaml, mobileapp-mappings-2.0.yaml, companion-mappings-1.0.yaml, webapp-mappings-2.2.yaml, webapp-mappings-3.0.yaml — dozens of individual card entries.
Proposed fix
Sort and de-duplicate before grouping:
data_numbers = sorted(set(int(s) for s in data))
Existing unit tests only ever exercise pre-sorted, de-duplicated input, which is why this hasn't been caught. Happy to submit a PR with the fix plus regression tests using the real unsorted data above.
Describe the bug
group_number_ranges()inscripts/convert.pycompresses a list of reference numbers (CAPEC/ASVS/MASTG IDs) into ranges for the printed cards, e.g.[25, 26, 27] -> "25-27". It does this usingitertools.groupby, which only detects consecutive runs correctly if the input is already sorted ascending with no duplicates:Several
source/*mappings*.yamlfiles list numbers out of order or with duplicates (they're hand-maintained), which produces incorrect, non-ascending, or duplicated text on the generated cards.To Reproduce
source/mobileapp-mappings-2.0.yaml, suitCRM, cardCRMX, tagcapec: [20, 116, 117, 97, 112, 485]check_make_list_into_text()(used bybuild_template_dict()for every card tag)"20, 116-117, 97, 112, 485"— not ascending, so the reader can't tell at a glance that112and485haven't already been covered.A worse case,
source/webapp-mappings-2.2.yamlsuitWC, cardJOB:capec: [184, 242, 416, 438, 441, 444, 523, 518, 519, 548, 636, 691]renders as"184, 242, 416, 438, 441, 444, 523, 518-519, 548, 636, 691"—518-519appears after523, which reads as a typo/data error to anyone using the card for actual ASVS/CAPEC lookups.A duplicate case:
["5", "5", "6"]renders as"5, 5-6"instead of"5-6".Expected behavior
Reference numbers should render sorted ascending, de-duplicated, with consecutive runs grouped into ranges, regardless of the order they appear in the source YAML.
Affected files (confirmed by scanning all mapping files)
mobileapp-mappings-1.0.yaml,mobileapp-mappings-1.1.yaml,mobileapp-mappings-2.0.yaml,companion-mappings-1.0.yaml,webapp-mappings-2.2.yaml,webapp-mappings-3.0.yaml— dozens of individual card entries.Proposed fix
Sort and de-duplicate before grouping:
Existing unit tests only ever exercise pre-sorted, de-duplicated input, which is why this hasn't been caught. Happy to submit a PR with the fix plus regression tests using the real unsorted data above.