fix(provider-utils): make URL regex checks stateless - #18570
Conversation
Bugfix reviewOutcome: approved Fixes issueStatus: 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 effectsRisk: 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. PerformanceRisk: low The stateful-pattern path adds constant-time flag checks and lastIndex save, reset, and restore operations without allocations or additional regex evaluations. Backwards compatibilityRisk: none No storage code or persisted data format is touched; the change only affects transient RegExp evaluation state. Breaking changesRisk: 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. ArchitectureRisk: 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 scopeStatus: minimal The three changed files contain only the localized implementation, targeted regression tests, and the repository-required patch changeset. SecurityRisk: none The change adds no I/O, URL fetching, parsing, credential handling, or additional regex execution and does not expand the existing attack surface. TestingStatus: 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. VerificationInspected 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 |
ff28fa3 to
ad81d2f
Compare
|
🚀 Published in:
|
Background
isUrlSupported()evaluates configured URL patterns withRegExp.test(). Global and sticky regular expressions retain match state inlastIndex, so a shared pattern can make identical URL-support checks depend on previous evaluations and can mutate caller-owned state.Summary
.test()path for ordinary regexes.lastIndexinfinally.is-url-supported.test.tssuite for repeated checks, caller-owned state, mismatch and throw paths, and frozen ordinary regexes.@ai-sdk/provider-utils.The helper uses
finallyso caller-owned state is restored even if custom RegExp execution mutateslastIndexand 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 buildpnpm -C packages/provider-utils testpnpm -C packages/provider-utils type-checkChecklist
Related Issues
Fixes #18569