Skip to content

Latest commit

 

History

History
150 lines (128 loc) · 7.26 KB

CHANGELOG.md

File metadata and controls

150 lines (128 loc) · 7.26 KB

Changelog

All notable changes to Vuer are documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Rule-id stability promise: a vue/... rule id is never reused or silently re-severed. Removing a rule is a major-version event announced here.

[Unreleased]

[0.3.0] - 2026-09-12

Added

  • Phase 3: the performance, accessibility, and architecture categories are now populated (11 new rules, 26 total):

    performance:

    • no-v-if-with-v-for — v-if and v-for on the same element are discouraged in Vue 3; filter with a computed instead (Medium).
    • no-deep-watch-without-handler — watch(src, cb, { deep: true }) traverses the whole object graph on every change (Low).
    • no-reactive-in-v-for — ref/reactive/computed wrappers created inside loop bodies allocate an effect per iteration that is never released (Low).
    • no-large-list-without-virtualization — heuristic: v-for over a curated set of large-looking collection names without a virtual-scroll wrapper (Low, documented heuristic).

    accessibility:

    • no-img-without-alt — screen readers announce an <img> by its alt text; alt="" and bound forms are accepted (Medium).
    • no-click-without-role-keyboard — @click on a non-interactive element with neither role nor a keyboard handler is unreachable for keyboard-only users (Medium).
    • no-form-without-label — fields must be labelled via <label for>, a wrapping <label>, or aria-label/aria-labelledby (Medium).
    • no-button-without-type — a <button> defaults to submit, which submits the form on any click (Low).

    architecture:

    • no-side-effect-in-computed — assignments, mutating calls, fetch/watch/emit, and async getters inside computed(...) are re-run unpredictably by Vue (Medium).
    • no-mutation-of-props — writes to props.x or a destructured defineProps value break one-way data flow (Medium).
    • no-async-setup-without-error-boundary — heuristic: async setup() without a <Suspense> boundary renders nothing until the promise settles (Low).

Fixed

  • SFC extraction no longer truncates a <script>/<style> block when its body contains a bare < that is not a tag opener (e.g. i < items.length): the boundary scanner previously skipped to the next > — the closing tag's — and silently dropped the whole block, silencing every script rule for that file.
  • Integration snapshot path filters now accept Windows separators and JSON-escaped \\ separators, so the suite runs on Windows.
  • .gitattributes pins every tracked file to LF: core.autocrlf=true rewrote conformance fixtures and insta snapshots to CRLF at checkout, failing the snapshot suite on Windows while CI stayed green.

Changed

  • no-window-open-blank-noopener is now taint-gated: a provably clean URL (a hardcoded literal, or a value derived only from trusted data) is no longer reported — the reverse-tabnabbing surface requires an attacker-influenced URL. A URL carrying untrusted data is still reported at High, with the source→sink flow path in the diagnostic. This closes the remaining window.open sink from the Phase 2 list.
  • no-watch-with-callback is now scope-aware: watchers created inside a component (<script setup> or Options API) are disposed automatically by Vue, so they are no longer reported. Only watch calls at module scope in a plain <script> block — the one place the watcher has no lifecycle to be torn down with — are flagged, with a corrected message and help text.
  • oxc bumped 0.136/0.143 → 0.144 — the whole cohort moves together (parser, allocator, ast, ast_visit, span, syntax, diagnostics), removing the mixed-generation lockfile. Breaking changes absorbed: Expression::MetaProperty split into ImportMeta/NewTarget, and ArrowFunctionExpression.body became the ArrowFunctionBody enum (FunctionBody | inherited expression) with as_expression() accessors. The conformance, edge-case, offset-integrity, and snapshot suites pass with zero diffs.
  • MSRV lowered 1.97 → 1.95 — oxc 0.144 requires rustc 1.95.0, which is now the highest minimum in the dependency tree; CI pins dtolnay/rust-toolchain 1.95.0 to match.
  • oxc re-bumped 0.144/0.147 → 0.149 — renovate had moved the direct dependencies one at a time, leaving three oxc_allocator generations in the lockfile and mismatched Allocator types at the oxc_parser call sites; the cohort is single-versioned again. No source changes were needed for this step; the conformance, edge-case, offset-integrity, and snapshot suites pass with zero diffs.
  • MSRV raised 1.95 → 1.96 — oxc 0.149 requires rustc 1.96.0, which is again the highest minimum in the dependency tree; CI pins dtolnay/rust-toolchain 1.98.0, which stays above the floor.

[0.2.0] - 2026-08-12

Added

  • Taint analysis engine (src/taint/) — a single-pass, deterministic, intra-file analysis that annotates every script and template expression with its taint state:
    • sources: localStorage/sessionStorage.getItem, fetch/axios/ useFetch, useRoute()/$route, defineProps props, Options API props/data/computed, event/$event, window.location, location.search/hash, document.cookie/referrer, document.* DOM reads, FormData/URLSearchParams;
    • propagators: assignment, concatenation, template literals, ternaries, member writes/reads, destructuring, .map/.filter/.then callbacks, ref/computed/reactive, and bounded inter-procedural flow through local function calls;
    • sanitizers: DOMPurify.sanitize, sanitize, escapeHtml, htmlEscape, escape, xss downgrade taint;
    • results exposed per expression span via TaintResult::status_at / flow_at.
  • Taint-gated rules — no-v-html, no-inner-html, no-dynamic-bind-src, and no-open-redirect now report only when the matched pattern carries untrusted data, cutting false positives while keeping the unsafe path fully reported.
  • Flow paths in diagnostics — pretty output shows = note: taint from <source> reaches <sink> via <ids>; JSON output gains a structured flow field; --list shows the rule kind (taint/syntactic).
  • RuleKind on the Rule trait (defaults to Syntactic) and Rule::check returning Vec<Finding> (diagnostic + optional flows).
  • Determinism property suite (tests/determinism.rs) — repeated scans produce byte-identical JSON/SARIF.

Changed

  • no-dangerous-url stays syntactic by design: the dangerous pattern is the literal javascript:/data:/vbscript: scheme itself (see docs/audits.md).
  • Shared fixtures now seed realistic tainted sources; integration snapshots updated accordingly.

[0.1.0] - 2026-06-21

Added

  • Initial release: SFC extraction, template parser, oxc-based script analysis, 15 rules across security and best-practice, pretty/JSON/ minimal/SARIF output, inline suppression, config discovery, parallel scanning, Phase 1 parser-hardening suites (conformance corpus, edge cases, offset integrity).