@ai-sdk/provider-utils 3.0.21 → 3.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -343,7 +343,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
343
343
  }
344
344
 
345
345
  // src/version.ts
346
- var VERSION = true ? "3.0.21" : "0.0.0-test";
346
+ var VERSION = true ? "3.0.22" : "0.0.0-test";
347
347
 
348
348
  // src/get-from-api.ts
349
349
  var getOriginalFetch = () => globalThis.fetch;
@@ -576,8 +576,8 @@ import {
576
576
  } from "@ai-sdk/provider";
577
577
 
578
578
  // src/secure-json-parse.ts
579
- var suspectProtoRx = /"__proto__"\s*:/;
580
- var suspectConstructorRx = /"constructor"\s*:/;
579
+ var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
580
+ var suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
581
581
  function _parse(text) {
582
582
  const obj = JSON.parse(text);
583
583
  if (obj === null || typeof obj !== "object") {
@@ -597,7 +597,7 @@ function filter(obj) {
597
597
  if (Object.prototype.hasOwnProperty.call(node, "__proto__")) {
598
598
  throw new SyntaxError("Object contains forbidden prototype property");
599
599
  }
600
- if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
600
+ if (Object.prototype.hasOwnProperty.call(node, "constructor") && node.constructor !== null && typeof node.constructor === "object" && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
601
601
  throw new SyntaxError("Object contains forbidden prototype property");
602
602
  }
603
603
  for (const key in node) {
@@ -2466,6 +2466,102 @@ function convertToBase64(value) {
2466
2466
  return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value;
2467
2467
  }
2468
2468
 
2469
+ // src/validate-download-url.ts
2470
+ function validateDownloadUrl(url) {
2471
+ let parsed;
2472
+ try {
2473
+ parsed = new URL(url);
2474
+ } catch (e) {
2475
+ throw new DownloadError({
2476
+ url,
2477
+ message: `Invalid URL: ${url}`
2478
+ });
2479
+ }
2480
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
2481
+ throw new DownloadError({
2482
+ url,
2483
+ message: `URL scheme must be http or https, got ${parsed.protocol}`
2484
+ });
2485
+ }
2486
+ const hostname = parsed.hostname;
2487
+ if (!hostname) {
2488
+ throw new DownloadError({
2489
+ url,
2490
+ message: `URL must have a hostname`
2491
+ });
2492
+ }
2493
+ if (hostname === "localhost" || hostname.endsWith(".local") || hostname.endsWith(".localhost")) {
2494
+ throw new DownloadError({
2495
+ url,
2496
+ message: `URL with hostname ${hostname} is not allowed`
2497
+ });
2498
+ }
2499
+ if (hostname.startsWith("[") && hostname.endsWith("]")) {
2500
+ const ipv6 = hostname.slice(1, -1);
2501
+ if (isPrivateIPv6(ipv6)) {
2502
+ throw new DownloadError({
2503
+ url,
2504
+ message: `URL with IPv6 address ${hostname} is not allowed`
2505
+ });
2506
+ }
2507
+ return;
2508
+ }
2509
+ if (isIPv4(hostname)) {
2510
+ if (isPrivateIPv4(hostname)) {
2511
+ throw new DownloadError({
2512
+ url,
2513
+ message: `URL with IP address ${hostname} is not allowed`
2514
+ });
2515
+ }
2516
+ return;
2517
+ }
2518
+ }
2519
+ function isIPv4(hostname) {
2520
+ const parts = hostname.split(".");
2521
+ if (parts.length !== 4) return false;
2522
+ return parts.every((part) => {
2523
+ const num = Number(part);
2524
+ return Number.isInteger(num) && num >= 0 && num <= 255 && String(num) === part;
2525
+ });
2526
+ }
2527
+ function isPrivateIPv4(ip) {
2528
+ const parts = ip.split(".").map(Number);
2529
+ const [a, b] = parts;
2530
+ if (a === 0) return true;
2531
+ if (a === 10) return true;
2532
+ if (a === 127) return true;
2533
+ if (a === 169 && b === 254) return true;
2534
+ if (a === 172 && b >= 16 && b <= 31) return true;
2535
+ if (a === 192 && b === 168) return true;
2536
+ return false;
2537
+ }
2538
+ function isPrivateIPv6(ip) {
2539
+ const normalized = ip.toLowerCase();
2540
+ if (normalized === "::1") return true;
2541
+ if (normalized === "::") return true;
2542
+ if (normalized.startsWith("::ffff:")) {
2543
+ const mappedPart = normalized.slice(7);
2544
+ if (isIPv4(mappedPart)) {
2545
+ return isPrivateIPv4(mappedPart);
2546
+ }
2547
+ const hexParts = mappedPart.split(":");
2548
+ if (hexParts.length === 2) {
2549
+ const high = parseInt(hexParts[0], 16);
2550
+ const low = parseInt(hexParts[1], 16);
2551
+ if (!isNaN(high) && !isNaN(low)) {
2552
+ const a = high >> 8 & 255;
2553
+ const b = high & 255;
2554
+ const c = low >> 8 & 255;
2555
+ const d = low & 255;
2556
+ return isPrivateIPv4(`${a}.${b}.${c}.${d}`);
2557
+ }
2558
+ }
2559
+ }
2560
+ if (normalized.startsWith("fc") || normalized.startsWith("fd")) return true;
2561
+ if (normalized.startsWith("fe80")) return true;
2562
+ return false;
2563
+ }
2564
+
2469
2565
  // src/without-trailing-slash.ts
2470
2566
  function withoutTrailingSlash(url) {
2471
2567
  return url == null ? void 0 : url.replace(/\/$/, "");
@@ -2556,6 +2652,7 @@ export {
2556
2652
  safeValidateTypes,
2557
2653
  standardSchemaValidator,
2558
2654
  tool,
2655
+ validateDownloadUrl,
2559
2656
  validateTypes,
2560
2657
  validator,
2561
2658
  withUserAgentSuffix,