Skip to content

fix: formatting normalization, DOM API XSS fixes, script robustness#60

Open
Fail-Safe wants to merge 12 commits intomainfrom
feat/formatting-normalization
Open

fix: formatting normalization, DOM API XSS fixes, script robustness#60
Fail-Safe wants to merge 12 commits intomainfrom
feat/formatting-normalization

Conversation

@Fail-Safe
Copy link
Owner

@Fail-Safe Fail-Safe commented Dec 5, 2025

Summary

  • Numeric normalization: normalizeUsageQuantity() utility prevents floating-point artifacts (e.g. 406.59000000000003) from leaking into UI and persisted state; applied throughout billing calculations in extension.ts, viewModel.ts, and usageUtils.ts
  • XSS / injection hardening: renderSummary and renderMultiMonthAnalysis in webview.js rewritten from innerHTML template literals to DOM API; sidebarProvider.ts trend direction assignments likewise; status bar tooltip uses md.appendText instead of string interpolation; openExternal validates scheme via Uri.parse
  • Script robustness: release-bump.mjs now applies sanitizeChangelogInner to the actual changelog insertion (was computed but unused); refactored for unit-testability via import.meta.url guard; update-plan-data.mjs replaces fragile regex HTML parsing with node-html-parser
  • Webview features: time-range selector (24h/7d/30d/all) for trend chart; multi-month analysis rendering; Y-axis formatYAxisValue with locale-aware decimal precision
  • Tests: unit tests for update-plan-data table parsing and release-bump sanitizer; type declaration files for .mjs script imports
  • Docs: added CLAUDE.md with build commands, architecture overview, and test structure

Test plan

  • npm run test:unit — 26/26 pass
  • npm test — full suite including VS Code Extension Host integration tests
  • Smoke test webview panel: verify no floating-point display artifacts, time-range selector filters chart correctly, multi-month section visible when data available

🤖 Generated with Claude Code

@Fail-Safe Fail-Safe changed the title feat: normalize numeric formatting & add time-range selector for usage trends feat: normalize numeric formatting & add time-range selector for usage trends (sanitization fix) Dec 5, 2025
Fail-Safe and others added 7 commits December 5, 2025 15:26
…UDE.md

- fix(release-bump): apply sanitizedInner to changelog insertion (was computed but unused)
- fix(release-bump): refactor to export sanitizeChangelogInner for unit testing and guard direct execution via import.meta.url
- fix(update-plan-data): replace regex-based HTML parsing with node-html-parser for robustness; add node-html-parser to devDependencies
- fix(extension): validate URI scheme via Uri.parse in openExternal handler instead of string prefix check
- fix(extension): use md.appendText for error string in status bar tooltip to prevent markdown injection
- fix(sidebarProvider): rewrite trend direction innerHTML assignments to DOM API to prevent XSS; wrap updateView in try/catch with fallback postMessage
- fix(webview): rewrite renderSummary and renderMultiMonthAnalysis to use DOM API instead of innerHTML template literals
- fix(.gitignore): add codeql-results*.sarif pattern
- chore(tsconfig): include src/**/*.d.ts so test type declarations are picked up by tsc
- chore(tests): add type declaration files for mjs scripts; add unit tests for update-plan-data and release-bump sanitizer
- docs: add CLAUDE.md with build commands, architecture overview, and test structure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d test runs

startAutoRefresh() fires an unconditional immediate performAutoRefresh() when
restartAutoRefresh() is called from the refreshIntervalMinutes config change
handler. This raced with lastAttemptGate.test.ts setting its own timestamps
even though CPUM_TEST_DISABLE_TIMERS=1 was set (that guard only covered the
initial activation path). Suppress the eager refresh when CPUM_TEST_DISABLE_TIMERS
is active; restart-count increments are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The test hardcoded oneIntervalMs = 5 * 60_000 but _test_getAttemptMeta()
reads refreshIntervalMinutes live from config at assertion time. If the
setting hasn't propagated fully (write race or prior test state), the
computed intervalMs would be larger (e.g. 15 min = 900000 ms) and the
620 s time delta would fail both gating conditions.

Fix: wait 100 ms after the config change to let any triggered background
ops settle, then read the effective interval back from config to derive
all timestamp offsets — ensuring the test's math is always consistent
with what _test_getAttemptMeta will compute.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Fail-Safe Fail-Safe changed the title feat: normalize numeric formatting & add time-range selector for usage trends (sanitization fix) fix: formatting normalization, DOM API XSS fixes, script robustness Mar 11, 2026
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