Skip to content

[Medium][view] Compiler emits ok:true for unterminated/invalid literals → poisons whole compiled module #170

Description

@JosunLP

Severity: 🟡 Medium (correctness — build-breaking)

Location

src/view/compiler/expression.ts:120-128 (scanStringLiteral), surfaced at :380-386; emitted at src/view/compiler/emit.ts:35.

Description

scanStringLiteral returns i + 1 unconditionally and never verifies the closing quote was found:

const scanStringLiteral = (src, start) => {
  const quote = src[start];
  let i = start + 1;
  while (i < src.length && src[i] !== quote) {
    if (src[i] === '\\') i += 1;
    i += 1;
  }
  return i + 1;   // returns past end-of-input if quote never closed
};

An unterminated string literal in a directive expression is therefore copied verbatim and rewrite returns normally, so compileExpression reports { ok: true, code } with a syntactically broken body. Because emitModule writes every expression into one module, a single malformed expression throws at import time and takes down all precompiled expressions in that file — and unlike the runtime path, there is no per-expression try/catch fallback.

Repro: template <p bq-text="'oops"></p> compiles to:

registerCompiledExpressions({
  "'oops": (__bq_ctx) => ('oops),   // SyntaxError → whole module fails to import
});

The same class of bug produces invalid emitted code for malformed numeric literals (e.g. 1ex), since scanNumericLiteral (:135-153) will also happily consume an invalid run.

Suggested fix

In scanStringLiteral, detect reaching end-of-input without the matching quote and throw new Bail('unterminated string literal') so the build falls back to the runtime evaluator for that expression. Add a post-scan validity check for numeric literals, or wrap emitted expressions so one bad entry cannot break the whole module.


Filed as part of a full-codebase security & correctness audit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmedium-priorityMedium severityviewChanges to the view module

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions