Skip to content

analytics: escape-safe ?tab= lookup, pin remaining #191 test gaps, withQuery contract #193

Description

@dborup

Summary

These are follow-ups from the review of #191 (merged as 8e4b13d0). All are low priority. None blocked the merge.

1. ?tab= is interpolated into a querySelector selector without escaping (pre-existing)

init() in public/analytics.js builds an attribute selector from the ?tab= value.

Suggested fix: look the button up by comparing btn.dataset.tab === tab over the tab buttons, not with a selector. Fall back to Overview for unknown values. Add a test with " and with the crafted value.

2. Test gaps in test-analytics-tab-state-and-query.js

Three of the reviewer's mutants survive:

  • The neighbor-graph URL is not pinned by the test, although the PR text says it is.
  • The Prefix Tool's own request can't be told apart from the shared load with the same URL. A mutant that drops the area filter from the Prefix Tool call passes.
  • setAreaFilterVisibility in init() is not covered.

Add assertions that kill these mutants.

3. withQuery(path, frag) contract

withQuery expects an &… fragment and a path without a query:

  • withQuery('/a', 'region=X') returns /a?egion=X;
  • a path that already contains ? gets a second ?.

No current caller hits these cases. Either make it tolerant (accept '', &… and ?…, and append with & when the path already has ?) or document and assert the contract. Add unit tests for the edge cases.

Acceptance criteria

Activity

  1. added a commit that references this issue on Oct 3, 2026
  2. dborup commented on Oct 3, 2026

    @dborup
    OwnerAuthor

    Fixed by #194 (merged as 6f7a5e7c):

    Leftover, low priority, from the #194 review: the hostile-value list in test-analytics-tab-state-and-query.js has no partial or differently-cased real tab name. Three mutants of the new lookup therefore survive: a substring match, a prefix match and a case-insensitive compare. The shipped code uses an exact ===, so this is a test gap only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions