Skip to content

fix(provider-utils): make URL regex checks stateless - #18570

Merged
n1ckoates merged 3 commits into
vercel:mainfrom
teamleaderleo:fix/url-support-regexp-state
Aug 7, 2026
Merged

fix(provider-utils): make URL regex checks stateless#18570
n1ckoates merged 3 commits into
vercel:mainfrom
teamleaderleo:fix/url-support-regexp-state

Conversation

@teamleaderleo

Copy link
Copy Markdown
Contributor

Background

isUrlSupported() evaluates configured URL patterns with RegExp.test(). Global and sticky regular expressions retain match state in lastIndex, so a shared pattern can make identical URL-support checks depend on previous evaluations and can mutate caller-owned state.

Summary

  • Keep the existing direct .test() path for ordinary regexes.
  • Evaluate global and sticky regexes from index zero.
  • Restore the caller's original lastIndex in finally.
  • Add regression coverage to the existing is-url-supported.test.ts suite for repeated checks, caller-owned state, mismatch and throw paths, and frozen ordinary regexes.
  • Add a patch changeset for @ai-sdk/provider-utils.

The helper uses finally so caller-owned state is restored even if custom RegExp execution mutates lastIndex and then throws.

This does not change URL normalization, media-type matching, wildcard behavior, or the public API.

End-to-End Verification

  • pnpm -C packages/provider build
  • pnpm -C packages/provider-utils test
  • pnpm -C packages/provider-utils type-check

Checklist

  • All commits are signed
  • Tests have been added / updated
  • Documentation has been added / updated
  • A patch changeset for the relevant package has been added
  • I have reviewed this pull request (self-review)

Related Issues

Fixes #18569

@ai-sdk-factory

ai-sdk-factory Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Bugfix review

Outcome: approved

Fixes issue

Status: fully-addresses

Global and sticky patterns are evaluated from index zero and their original lastIndex is restored in finally, making repeated checks deterministic without leaking caller-owned state.

Side effects

Risk: low

Ordinary RegExp evaluation and all URL and media-type matching logic remain unchanged; only the unintended state-dependent semantics of global and sticky patterns change.

Performance

Risk: low

The stateful-pattern path adds constant-time flag checks and lastIndex save, reset, and restore operations without allocations or additional regex evaluations.

Backwards compatibility

Risk: none

No storage code or persisted data format is touched; the change only affects transient RegExp evaluation state.

Breaking changes

Risk: none

Public exports, types, accepted inputs, return shape, defaults, configuration, and persisted formats are unchanged; the observable behavior change corrects nondeterministic global and sticky RegExp matching.

Architecture

Risk: none

The implementation is a private helper colocated with isUrlSupported in provider-utils, with no new dependencies, cross-package source imports, exports, or boundary violations.

Change scope

Status: minimal

The three changed files contain only the localized implementation, targeted regression tests, and the repository-required patch changeset.

Security

Risk: none

The change adds no I/O, URL fetching, parsing, credential handling, or additional regex execution and does not expand the existing attack surface.

Testing

Status: appropriate

Regression coverage includes repeated global and sticky checks, nonzero caller state, mismatches, restoration after custom execution throws, and preservation of frozen ordinary RegExp behavior; the package tests pass in Node and Edge environments.

Verification

Inspected the complete three-file diff and public export boundary. The provider-utils Node and Edge test suites, provider-utils type-check, repository formatting/lint check, and git diff validation all passed; the working tree remained clean.

Relevant Documentation

@teamleaderleo
teamleaderleo force-pushed the fix/url-support-regexp-state branch from ff28fa3 to ad81d2f Compare August 7, 2026 04:03
@n1ckoates
n1ckoates enabled auto-merge (squash) August 7, 2026 15:49
@n1ckoates
n1ckoates merged commit 1937bef into vercel:main Aug 7, 2026
50 of 51 checks passed
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🚀 Published in:

Package Version
ai 7.0.57 github npm
@ai-sdk/alibaba 2.0.28 github npm
@ai-sdk/amazon-bedrock 5.0.49 github npm
@ai-sdk/angular 3.0.57 github npm
@ai-sdk/anthropic 4.0.35 github npm
@ai-sdk/anthropic-aws 2.0.27 github npm
@ai-sdk/assemblyai 3.0.24 github npm
@ai-sdk/azure 4.0.36 github npm
@ai-sdk/baseten 2.1.4 github npm
@ai-sdk/black-forest-labs 2.0.25 github npm
@ai-sdk/bytedance 2.0.26 github npm
@ai-sdk/cartesia 3.0.19 github npm
@ai-sdk/cerebras 3.0.26 github npm
@ai-sdk/code-mode 1.0.14 github npm
@ai-sdk/cohere 4.0.24 github npm
@ai-sdk/deepgram 3.0.24 github npm
@ai-sdk/deepinfra 3.0.26 github npm
@ai-sdk/deepseek 3.0.25 github npm
@ai-sdk/elevenlabs 3.0.25 github npm
@ai-sdk/fal 3.0.25 github npm
@ai-sdk/fireworks 3.0.28 github npm
@ai-sdk/fish-audio 3.0.2 github npm
@ai-sdk/gateway 4.0.45 github npm
@ai-sdk/gladia 3.0.24 github npm
@ai-sdk/google 4.0.38 github npm
@ai-sdk/google-vertex 5.0.46 github npm
@ai-sdk/groq 4.0.25 github npm
@ai-sdk/harness 1.0.63 github npm
@ai-sdk/harness-acp 1.0.0 github npm
@ai-sdk/harness-claude-code 1.0.64 github npm
@ai-sdk/harness-codex 1.0.65 github npm
@ai-sdk/harness-deepagents 1.0.62 github npm
@ai-sdk/harness-opencode 1.0.64 github npm
@ai-sdk/harness-pi 1.0.63 github npm
@ai-sdk/huggingface 2.0.26 github npm
@ai-sdk/hume 3.0.24 github npm
@ai-sdk/klingai 4.0.26 github npm
@ai-sdk/langchain 3.0.57 github npm
@ai-sdk/llamaindex 3.0.57 github npm
@ai-sdk/lmnt 3.0.24 github npm
@ai-sdk/luma 3.0.25 github npm
@ai-sdk/mcp 2.0.28 github npm
@ai-sdk/minimax 3.0.11 github npm
@ai-sdk/mistral 4.0.26 github npm
@ai-sdk/moonshotai 3.0.29 github npm
@ai-sdk/open-responses 2.0.24 github npm
@ai-sdk/openai 4.0.35 github npm
@ai-sdk/openai-compatible 3.0.26 github npm
@ai-sdk/otel 1.0.57 github npm
@ai-sdk/perplexity 4.0.26 github npm
@ai-sdk/policy-opa 1.0.57 github npm
@ai-sdk/prodia 2.0.25 github npm
@ai-sdk/provider-utils 5.0.24 github npm
@ai-sdk/quiverai 2.0.24 github npm
@ai-sdk/react 4.0.60 github npm
@ai-sdk/replicate 3.0.25 github npm
@ai-sdk/revai 3.0.24 github npm
@ai-sdk/rsc 3.0.57 github npm
@ai-sdk/sandbox-just-bash 1.0.63 github npm
@ai-sdk/sandbox-vercel 1.0.63 github npm
@ai-sdk/svelte 5.0.57 github npm
@ai-sdk/togetherai 3.0.27 github npm
@ai-sdk/tui 1.0.58 github npm
@ai-sdk/valibot 3.0.24 github npm
@ai-sdk/vercel 3.0.26 github npm
@ai-sdk/voyage 2.0.24 github npm
@ai-sdk/vue 4.0.57 github npm
@ai-sdk/workflow 1.0.57 github npm
@ai-sdk/workflow-harness 1.0.63 github npm
@ai-sdk/xai 4.0.32 github npm

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isUrlSupported can return inconsistent results for global or sticky RegExp patterns

2 participants