Skip to content

Parser/scanner divergence: CR-spanning single-quote character constants; fail-open, low practical impact #883

Open

Description

@jsavin

Rationale

Residual strip-scanner divergence for CR-spanning single-quote character constants. The real tokenizer (parsepopcharconst) accepts a raw CR inside 'x' constants (legal 1-char or 4-char OSType consts spanning lines); the strip scanner is per-line (flinstring resets each line), so on the continuation line the closing quote OPENS a phantom literal — literal-state inversion. Near-zero practical occurrence (authors write '\r'), not a smuggling vector, fail-open only for round-trip fidelity. Also two fail-closed divergences: stripper accepts empty '' and >4-char runs the tokenizer rejects.

Current State

Strip-scanner divergence identified (2026-08-10):

Fail-open case (CR-spanning character constants):

  • Real tokenizer (parsepopcharconst): accepts raw CR inside 'x' constants (e.g., 'FOO\r' or multi-line constants)
  • Strip scanner: per-line processing (flinstring resets each line)
  • On continuation line: closing quote OPENS a phantom literal
  • Result: literal-state inversion, different parse state
  • Practical occurrence: near-zero (authors write '\r' escape, not raw CR)
  • Not a smuggling vector; fail-open only for round-trip fidelity

Fail-closed cases:

  1. Stripper accepts empty '' — tokenizer rejects
  2. Stripper accepts >4-char runs — tokenizer rejects

Impact:

Desired Outcome

Fix options:

  1. Document limitation: Note that strip scanner has per-line scope; CR-spanning constants may diverge
  2. Fix scanner: Carry unterminated-single-quote state across lines in scanner
  3. Both: Document + fix for full fidelity

Recommendation

Option A (minimal, documentation):

Option B (fix):

  • Modify flinstring to carry quote state across lines
  • Handle CR-spanning character constants correctly
  • Stripper matches tokenizer behavior (fail-closed for empty '' and >4-char)

Recommended: Option A (documentation) + flag for future Option B (if round-trip fidelity becomes critical)

Exit Criteria

Related Context

Fail Cases Summary

Case Stripper Tokenizer Practical
CR-spanning 'x' diverges accepts near-zero
empty '' accepts rejects low
>4-char 'ABCDE' accepts rejects low

All three are edge cases; practical impact is minimal. The CR-spanning case is the most exotic (authors rarely use raw CR inside constants).

Activity

  1. added
    priority/p2Medium priority - nice to have
    type/bugDefect in existing functionality, needs fix
    workstream/runtime-coreRuntime architecture, memory, lifecycle, and global context
    on Aug 11, 2026
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

    priority/p2Medium priority - nice to havescope/quick-win< 4 hours, obvious solutiontype/bugDefect in existing functionality, needs fixworkstream/runtime-coreRuntime architecture, memory, lifecycle, and global context

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions