Skip to content

fix(schema): validate canonical base64 without a backtracking regex - #51272

Closed
darellchua2 wants to merge 1 commit into
anomalyco:devfrom
darellchua2:base64-pattern-overflow
Closed

darellchua2 wants to merge 1 commit into
anomalyco:devfrom
darellchua2:base64-pattern-overflow

Conversation

@darellchua2

@darellchua2 darellchua2 commented Sep 25, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #45558
Closes #50336

Type of change

  • Bug fix

What does this PR do?

In the wild this surfaces as Error: Schema validation failed ... Prompt.Base64 ... InvalidValue with POST /api/session/<id>/prompt http.status=500 in the server log.

Prompt.Base64 used a (?:X{4})* regex, which regex engines evaluate with per-group recursion. Past a few MB the check stops working: on Bun/JSC (the runtime the shipped binary embeds) it silently returns false for canonical base64, and on V8 it throws RangeError. Since materializeAttachment base64-encodes attachments up to 20 MB, any @-attached file over ~5 MB failed POST /api/session/:id/prompt with a 500 before reaching the provider.

The check is now a length preflight, a single-pass alphabet pattern, and a padding/length consistency test. Canonical base64 always has length ≡ 0 (mod 4), alphabet chars with at most two trailing pads, and 0, 2, or 3 data chars in the final quantum, so accept/reject behavior is unchanged for every input.

How did you verify your code works?

cd packages/schema && bun test — new tests cover the padding edge cases and a 20 MB payload (passes in ~32 ms; the old pattern returned false on it). I also fuzzed 20k mutated canonical strings against the old pattern with zero accept/reject mismatches, checked on Bun 1.4.2 (JSC) and Node 24 (V8). bun run check passes.

Screenshots / recordings

Not a UI change.

Checklist

(The needs:issue label from the bot is stale — Closes #45558 / Closes #50336 are above; GitHub doesn't record closing references for PRs targeting non-default branches, which is why the GraphQL check comes up empty.)

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@darellchua2

Copy link
Copy Markdown
Author

Heads-up on the needs:issue label: the body does link the issues (Closes #45558, Closes #50336), but closingIssuesReferences stays empty for PRs targeting non-default branches (as noted in the pr-standards.yml comment), and the body-regex fallback also doesn't seem to clear it at runtime. Happy to adjust the description format if there's a form that satisfies the check.

@thdxr
thdxr changed the base branch from v2 to dev October 10, 2026 19:18
@github-actions

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

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

Projects

None yet

1 participant