Skip to content

resolver: implement URL template substitution + conditional data block#8

Merged
kurtseifried merged 1 commit into
mainfrom
fix/url-template-substitution
May 28, 2026
Merged

resolver: implement URL template substitution + conditional data block#8
kurtseifried merged 1 commit into
mainfrom
fix/url-template-substitution

Conversation

@kurtseifried

Copy link
Copy Markdown
Contributor

Summary

Phase 2.5(a) — fixes the two highest-impact bugs in the Python Server-API resolver, both surfaced by SecID-Client-SDK PR #4's conformance suite.

Bug 1: URL templates pass through unrendered

`{id}`, `{num}`, `{parent}`, `{sub}` placeholders reach clients literally instead of being substituted. Affected 4 conformance fixtures.

Bug 2: `data` block leaks on URL-bearing results

Every URL result dumped internal registry metadata (description, examples, schema info) into the response. The canonical Worker only includes `data` when there's no URL.

Implementation

New `_substitute_url_template(template, child_data, captured_input)` helper. Two layered modes mirroring SecID-Service:

Mode 1 — explicit variables:
```json
"variables": {
"num": { "extract": "^CWE-(\d+)$" }
}
```
Extract regex matched against input; group 1 supplies the value.

Mode 2 — implicit `{id}`:
Defaults to the captured input. Layered on top of Mode 1, not exclusive.

Unrecognized `{placeholders}` are left visible so registry data bugs are diagnosable.

`data` conditional: included only when there's no URL (canonical Worker contract).

Conformance progression

Before After
3 / 10 pass 7 / 10 pass

Newly passing:

  • `resolve-cve-2021-44228` (implicit `{id}` + no `data` field)
  • `resolve-cwe-79` (explicit `{num}` via extract regex)
  • `resolve-attck-t1059-003` (multiple explicit variables — `{parent}` and `{sub}`)
  • `resolve-aiid-1` (implicit `{id}`)

Still failing (independent Phase 2.5 follow-up PRs):

  • `resolve-cve-cross-source` — bare-namespace cross-source search
  • `list-advisory-namespaces` — bare-type discovery
  • `list-types` — `/api/v1/types` endpoint missing

Verification

```
$ pytest test_smoke.py -v
19/19 passed (13 prior + 6 new substitution unit tests)

$ python3 tests/conformance-harness/python/run.py --target http://localhost:8765
Results: 7 passed, 3 failed (out of 10)
```

New unit tests

  • `test_substitute_template_no_placeholders` — fast-path
  • `test_substitute_implicit_id` — CVE case
  • `test_substitute_explicit_variable` — CWE case
  • `test_substitute_multiple_variables` — ATT&CK sub-technique
  • `test_substitute_implicit_id_with_explicit_others` — layered modes
  • `test_substitute_unrecognized_placeholder_left_visible` — diagnostic-friendly fallback

🤖 Generated with Claude Code

Phase 2.5(a) of the testing-maturity initiative. Fixes two related
resolver bugs surfaced by the conformance suite added in
SecID-Client-SDK PR #4:

1. URL templates pass through unrendered ({id}, {num}, {parent}/{sub}
   placeholders reach clients literally instead of being substituted).
2. Every URL-bearing result carries an extra `data` block dumping
   internal registry metadata into the response.

The new _substitute_url_template() supports two layered modes,
matching SecID-Service Worker's behavior:

  Mode 1: explicit variables
    Child match_node's data.variables = {name: {extract: <regex>}}.
    The extract regex matches the captured input; group 1 (or group 0
    if no groups) supplies the variable's value.
    Example: CWE-79 + extract '^CWE-(\d+)$' -> num=79.

  Mode 2: implicit {id}
    Defaults to the captured input unless explicitly defined. Layered
    on top of Mode 1, not exclusive — both can fire if a template uses
    both {id} and other named placeholders.
    Example: CVE-2021-44228 -> {id}=CVE-2021-44228.

Unrecognized {placeholders} are left as-is so registry data bugs are
visible rather than silently swallowed.

The data-block fix matches the canonical Worker contract:
  - URL-bearing results: no `data` field (URL is the result)
  - Description-only results: `data` field present (no URL means
    `data` is the only meaningful content)

Tests:
  python/test_smoke.py — 6 new unit tests covering each substitution
  mode plus the unrecognized-placeholder edge case. 19/19 pass.

Conformance against the canonical Worker:
  Before this PR: 3/10 pass against Python Server-API
  After this PR:  7/10 pass
  Newly passing:
    - resolve-cve-2021-44228 (implicit {id} + no data field)
    - resolve-cwe-79         (explicit {num} via extract)
    - resolve-attck-t1059-003 (multiple explicit variables)
    - resolve-aiid-1         (implicit {id})
  Still failing (Phase 2.5c+d — separate PRs):
    - resolve-cve-cross-source     (bare-namespace cross-source search)
    - list-advisory-namespaces     (bare-type discovery)
    - list-types                   (/api/v1/types endpoint missing)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@kurtseifried kurtseifried merged commit 2f7584a into main May 28, 2026
@kurtseifried kurtseifried deleted the fix/url-template-substitution branch May 28, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant