mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
fix(deps): patch vulnerable Zod collections in mobile and docs (#32941)
This commit is contained in:
@@ -50,5 +50,31 @@
|
||||
"path": "patches/node-forge@1.4.0.patch",
|
||||
"sha256": "2798686e4488058ad81c3b8e32eb763c0feff21f4c717ce4d13b6ef2432cd5b8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"workspace": "mobile",
|
||||
"package": "zod",
|
||||
"version": "3.25.76",
|
||||
"advisory": "GHSA-mrhx-c7xc-m3w5",
|
||||
"owner": "Orca maintainers",
|
||||
"reason": "Expo and Vercel require Zod 3, which has no fixed upstream release. Backport the upper collection-size gate from colinhacks/zod#6652 for the v3 and bundled v4 entrypoints; installed-dependency regression tests cover sync and async parsing. Remove when a fixed Zod 3 release or compatible consumer upgrade is available.",
|
||||
"expires": "2026-11-20",
|
||||
"patch": {
|
||||
"path": "patches/zod@3.25.76.patch",
|
||||
"sha256": "8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec"
|
||||
}
|
||||
},
|
||||
{
|
||||
"workspace": "docs/site",
|
||||
"package": "zod",
|
||||
"version": "3.25.76",
|
||||
"advisory": "GHSA-mrhx-c7xc-m3w5",
|
||||
"owner": "Orca maintainers",
|
||||
"reason": "Expo and Vercel require Zod 3, which has no fixed upstream release. Backport the upper collection-size gate from colinhacks/zod#6652 for the v3 and bundled v4 entrypoints; installed-dependency regression tests cover sync and async parsing. Remove when a fixed Zod 3 release or compatible consumer upgrade is available.",
|
||||
"expires": "2026-11-20",
|
||||
"patch": {
|
||||
"path": "../../config/patches/zod@3.25.76.patch",
|
||||
"sha256": "8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
diff --git a/src/v3/types.ts b/src/v3/types.ts
|
||||
--- a/src/v3/types.ts
|
||||
+++ b/src/v3/types.ts
|
||||
@@ -2263,6 +2263,7 @@
|
||||
exact: true,
|
||||
message: def.exactLength.message,
|
||||
});
|
||||
+ if (tooBig) return INVALID;
|
||||
status.dirty();
|
||||
}
|
||||
}
|
||||
@@ -2291,7 +2292,7 @@
|
||||
exact: false,
|
||||
message: def.maxLength.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3723,7 +3724,7 @@
|
||||
exact: false,
|
||||
message: def.maxSize.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/v3/types.js b/v3/types.js
|
||||
--- a/v3/types.js
|
||||
+++ b/v3/types.js
|
||||
@@ -1769,6 +1769,7 @@
|
||||
exact: true,
|
||||
message: def.exactLength.message,
|
||||
});
|
||||
+ if (tooBig) return INVALID;
|
||||
status.dirty();
|
||||
}
|
||||
}
|
||||
@@ -1795,7 +1796,7 @@
|
||||
exact: false,
|
||||
message: def.maxLength.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return INVALID;
|
||||
}
|
||||
}
|
||||
if (ctx.common.async) {
|
||||
@@ -2814,7 +2815,7 @@
|
||||
exact: false,
|
||||
message: def.maxSize.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return INVALID;
|
||||
}
|
||||
}
|
||||
const valueType = this._def.valueType;
|
||||
diff --git a/v3/types.cjs b/v3/types.cjs
|
||||
--- a/v3/types.cjs
|
||||
+++ b/v3/types.cjs
|
||||
@@ -1790,6 +1790,7 @@
|
||||
exact: true,
|
||||
message: def.exactLength.message,
|
||||
});
|
||||
+ if (tooBig) return parseUtil_js_1.INVALID;
|
||||
status.dirty();
|
||||
}
|
||||
}
|
||||
@@ -1816,7 +1817,7 @@
|
||||
exact: false,
|
||||
message: def.maxLength.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return parseUtil_js_1.INVALID;
|
||||
}
|
||||
}
|
||||
if (ctx.common.async) {
|
||||
@@ -2843,7 +2844,7 @@
|
||||
exact: false,
|
||||
message: def.maxSize.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return parseUtil_js_1.INVALID;
|
||||
}
|
||||
}
|
||||
const valueType = this._def.valueType;
|
||||
diff --git a/src/v4/core/schemas.ts b/src/v4/core/schemas.ts
|
||||
--- a/src/v4/core/schemas.ts
|
||||
+++ b/src/v4/core/schemas.ts
|
||||
@@ -242,6 +242,26 @@
|
||||
};
|
||||
|
||||
inst._zod.run = (payload, ctx) => {
|
||||
+ const value = payload.value;
|
||||
+ const size = def.type === "array" && Array.isArray(value) ? value.length
|
||||
+ : (def.type === "map" && value instanceof Map) || (def.type === "set" && value instanceof Set) ? value.size : -1;
|
||||
+ if (size >= 0) {
|
||||
+ for (const ch of checks) {
|
||||
+ const checkDef = ch._zod.def;
|
||||
+ if (!["min_length", "max_length", "length_equals", "min_size", "max_size", "size_equals"].includes(checkDef.check)) break;
|
||||
+ const maximum = "maximum" in checkDef ? checkDef.maximum
|
||||
+ : "length" in checkDef ? checkDef.length : "size" in checkDef ? checkDef.size : undefined;
|
||||
+ if (typeof maximum === "number" && size > maximum && (!checkDef.when || checkDef.when(payload))) {
|
||||
+ const start = payload.issues.length;
|
||||
+ // SAFETY: Built-in size checks run only after the matching collection type guard.
|
||||
+ ch._zod.check(payload as ParsePayload<never>);
|
||||
+ for (let i = start; i < payload.issues.length; i++) {
|
||||
+ payload.issues[i] = { ...payload.issues[i], continue: false };
|
||||
+ }
|
||||
+ return payload;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
const result = inst._zod.parse(payload, ctx);
|
||||
|
||||
if (result instanceof Promise) {
|
||||
diff --git a/v4/core/schemas.js b/v4/core/schemas.js
|
||||
--- a/v4/core/schemas.js
|
||||
+++ b/v4/core/schemas.js
|
||||
@@ -74,6 +74,25 @@
|
||||
return payload;
|
||||
};
|
||||
inst._zod.run = (payload, ctx) => {
|
||||
+ const value = payload.value;
|
||||
+ const size = def.type === "array" && Array.isArray(value) ? value.length
|
||||
+ : (def.type === "map" && value instanceof Map) || (def.type === "set" && value instanceof Set) ? value.size : -1;
|
||||
+ if (size >= 0) {
|
||||
+ for (const ch of checks) {
|
||||
+ const checkDef = ch._zod.def;
|
||||
+ if (!["min_length", "max_length", "length_equals", "min_size", "max_size", "size_equals"].includes(checkDef.check)) break;
|
||||
+ const maximum = "maximum" in checkDef ? checkDef.maximum
|
||||
+ : "length" in checkDef ? checkDef.length : "size" in checkDef ? checkDef.size : undefined;
|
||||
+ if (typeof maximum === "number" && size > maximum && (!checkDef.when || checkDef.when(payload))) {
|
||||
+ const start = payload.issues.length;
|
||||
+ ch._zod.check(payload);
|
||||
+ for (let i = start; i < payload.issues.length; i++) {
|
||||
+ payload.issues[i] = { ...payload.issues[i], continue: false };
|
||||
+ }
|
||||
+ return payload;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
const result = inst._zod.parse(payload, ctx);
|
||||
if (result instanceof Promise) {
|
||||
if (ctx.async === false)
|
||||
diff --git a/v4/core/schemas.cjs b/v4/core/schemas.cjs
|
||||
--- a/v4/core/schemas.cjs
|
||||
+++ b/v4/core/schemas.cjs
|
||||
@@ -104,6 +104,25 @@
|
||||
return payload;
|
||||
};
|
||||
inst._zod.run = (payload, ctx) => {
|
||||
+ const value = payload.value;
|
||||
+ const size = def.type === "array" && Array.isArray(value) ? value.length
|
||||
+ : (def.type === "map" && value instanceof Map) || (def.type === "set" && value instanceof Set) ? value.size : -1;
|
||||
+ if (size >= 0) {
|
||||
+ for (const ch of checks) {
|
||||
+ const checkDef = ch._zod.def;
|
||||
+ if (!["min_length", "max_length", "length_equals", "min_size", "max_size", "size_equals"].includes(checkDef.check)) break;
|
||||
+ const maximum = "maximum" in checkDef ? checkDef.maximum
|
||||
+ : "length" in checkDef ? checkDef.length : "size" in checkDef ? checkDef.size : undefined;
|
||||
+ if (typeof maximum === "number" && size > maximum && (!checkDef.when || checkDef.when(payload))) {
|
||||
+ const start = payload.issues.length;
|
||||
+ ch._zod.check(payload);
|
||||
+ for (let i = start; i < payload.issues.length; i++) {
|
||||
+ payload.issues[i] = { ...payload.issues[i], continue: false };
|
||||
+ }
|
||||
+ return payload;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
const result = inst._zod.parse(payload, ctx);
|
||||
if (result instanceof Promise) {
|
||||
if (ctx.async === false)
|
||||
@@ -23,7 +23,7 @@
|
||||
"react-dom": "19.2.8",
|
||||
"tailwind-merge": "^3.7.0",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"zod": "^4"
|
||||
"zod": "~4.6.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
|
||||
Generated
+32
-34
@@ -163,6 +163,8 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
zod@>=3 <4: 3.25.76
|
||||
zod@>=4 <4.6.6: 4.6.7
|
||||
path-to-regexp@>=4.0.0 <6.3.0: 6.3.0
|
||||
'@vercel/node>undici': 6.28.1
|
||||
'@vercel/python-analysis>js-yaml': 4.3.2
|
||||
@@ -180,6 +182,7 @@ overrides:
|
||||
|
||||
patchedDependencies:
|
||||
braces@3.0.3: c07bb14cec04bc891e1fe529720444cc9729a25117f9aaf24253cfe3132a34fd
|
||||
zod@3.25.76: 8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec
|
||||
|
||||
importers:
|
||||
|
||||
@@ -190,13 +193,13 @@ importers:
|
||||
version: 2.1.1
|
||||
fumadocs-core:
|
||||
specifier: ^16.8.4
|
||||
version: 16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3)
|
||||
version: 16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.6.7)
|
||||
fumadocs-mdx:
|
||||
specifier: ^14.3.1
|
||||
version: 14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.18)(fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
||||
version: 14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.18)(fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.6.7))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
||||
fumadocs-ui:
|
||||
specifier: ^16.8.4
|
||||
version: 16.12.1(@types/mdx@2.0.14)(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.3.3)
|
||||
version: 16.12.1(@types/mdx@2.0.14)(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.6.7))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.3.3)
|
||||
lucide-react:
|
||||
specifier: ^1.6.0
|
||||
version: 1.26.0(react@19.2.8)
|
||||
@@ -216,8 +219,8 @@ importers:
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
zod:
|
||||
specifier: ^4
|
||||
version: 4.4.3
|
||||
specifier: ~4.6.7
|
||||
version: 4.6.7
|
||||
devDependencies:
|
||||
'@tailwindcss/postcss':
|
||||
specifier: ^4
|
||||
@@ -2604,7 +2607,7 @@ packages:
|
||||
react-dom: ^19.2.0
|
||||
react-router: 7.x.x || 8.x.x
|
||||
waku: '*'
|
||||
zod: 4.x.x
|
||||
zod: 4.6.7
|
||||
peerDependenciesMeta:
|
||||
'@mdx-js/mdx':
|
||||
optional: true
|
||||
@@ -3875,14 +3878,11 @@ packages:
|
||||
yauzl@2.10.0:
|
||||
resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
|
||||
|
||||
zod@3.22.4:
|
||||
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
|
||||
zod@3.25.76:
|
||||
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
|
||||
|
||||
zod@4.1.11:
|
||||
resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==}
|
||||
|
||||
zod@4.4.3:
|
||||
resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
|
||||
zod@4.6.7:
|
||||
resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==}
|
||||
|
||||
zwitch@2.0.4:
|
||||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||
@@ -5166,7 +5166,7 @@ snapshots:
|
||||
srvx: 0.11.16
|
||||
ts-morph: 12.0.0
|
||||
tsx: 4.21.0
|
||||
zod: 3.22.4
|
||||
zod: 3.25.76(patch_hash=8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec)
|
||||
transitivePeerDependencies:
|
||||
- '@emnapi/core'
|
||||
- '@emnapi/runtime'
|
||||
@@ -5205,17 +5205,17 @@ snapshots:
|
||||
'@vercel/cli-config': 0.3.1
|
||||
async-listen: 3.0.0
|
||||
open: 8.4.0
|
||||
zod: 4.1.11
|
||||
zod: 4.6.7
|
||||
|
||||
'@vercel/cli-config@0.2.4':
|
||||
dependencies:
|
||||
xdg-app-paths: 5.1.0
|
||||
zod: 4.1.11
|
||||
zod: 4.6.7
|
||||
|
||||
'@vercel/cli-config@0.3.1':
|
||||
dependencies:
|
||||
xdg-app-paths: 5.1.0
|
||||
zod: 4.1.11
|
||||
zod: 4.6.7
|
||||
|
||||
'@vercel/cli-exec@1.0.1':
|
||||
dependencies:
|
||||
@@ -5253,7 +5253,7 @@ snapshots:
|
||||
fs-extra: 11.1.0
|
||||
path-to-regexp: 8.4.0
|
||||
ts-morph: 12.0.0
|
||||
zod: 3.22.4
|
||||
zod: 3.25.76(patch_hash=8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec)
|
||||
transitivePeerDependencies:
|
||||
- '@emnapi/core'
|
||||
- '@emnapi/runtime'
|
||||
@@ -5332,7 +5332,7 @@ snapshots:
|
||||
fs-extra: 11.1.0
|
||||
path-to-regexp: 8.4.0
|
||||
ts-morph: 12.0.0
|
||||
zod: 3.22.4
|
||||
zod: 3.25.76(patch_hash=8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec)
|
||||
transitivePeerDependencies:
|
||||
- '@emnapi/core'
|
||||
- '@emnapi/runtime'
|
||||
@@ -5450,7 +5450,7 @@ snapshots:
|
||||
js-yaml: 4.3.2
|
||||
minimatch: 10.2.6
|
||||
smol-toml: 1.9.1
|
||||
zod: 3.22.4
|
||||
zod: 3.25.76(patch_hash=8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec)
|
||||
|
||||
'@vercel/python@25.0.0(@vercel/build-utils@14.21.0)':
|
||||
dependencies:
|
||||
@@ -5511,7 +5511,7 @@ snapshots:
|
||||
tar-stream: 3.1.7
|
||||
undici: 7.29.1
|
||||
xdg-app-paths: 5.1.0
|
||||
zod: 4.4.3
|
||||
zod: 4.6.7
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
@@ -5950,7 +5950,7 @@ snapshots:
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3):
|
||||
fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.6.7):
|
||||
dependencies:
|
||||
'@orama/orama': 3.1.18
|
||||
estree-util-value-to-estree: 3.5.0
|
||||
@@ -5980,18 +5980,18 @@ snapshots:
|
||||
next: 16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
react: 19.2.8
|
||||
react-dom: 19.2.8(react@19.2.8)
|
||||
zod: 4.4.3
|
||||
zod: 4.6.7
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
fumadocs-mdx@14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.18)(fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8):
|
||||
fumadocs-mdx@14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.18)(fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.6.7))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8):
|
||||
dependencies:
|
||||
'@mdx-js/mdx': 3.1.1
|
||||
'@standard-schema/spec': 1.1.0
|
||||
chokidar: 5.0.0
|
||||
esbuild: 0.28.1
|
||||
estree-util-value-to-estree: 3.5.0
|
||||
fumadocs-core: 16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3)
|
||||
fumadocs-core: 16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.6.7)
|
||||
js-yaml: 4.3.2
|
||||
mdast-util-mdx: 3.0.0
|
||||
mdast-util-to-markdown: 2.1.2
|
||||
@@ -6003,7 +6003,7 @@ snapshots:
|
||||
unist-util-remove-position: 5.0.0
|
||||
unist-util-visit: 5.1.0
|
||||
vfile: 6.0.3
|
||||
zod: 4.4.3
|
||||
zod: 4.6.7
|
||||
optionalDependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
'@types/mdx': 2.0.14
|
||||
@@ -6013,7 +6013,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
fumadocs-ui@16.12.1(@types/mdx@2.0.14)(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.3.3):
|
||||
fumadocs-ui@16.12.1(@types/mdx@2.0.14)(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(fumadocs-core@16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.6.7))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.3.3):
|
||||
dependencies:
|
||||
'@fuma-translate/react': 1.0.2(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@fumadocs/tailwind': 0.1.1(tailwindcss@4.3.3)
|
||||
@@ -6029,7 +6029,7 @@ snapshots:
|
||||
'@radix-ui/react-tabs': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
class-variance-authority: 0.7.1
|
||||
cnfast: 0.0.8
|
||||
fumadocs-core: 16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3)
|
||||
fumadocs-core: 16.12.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.26.0(react@19.2.8))(next@16.4.2(@types/node@24.19.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.6.7)
|
||||
lucide-react: 1.26.0(react@19.2.8)
|
||||
motion: 12.42.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
next-themes: 0.4.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
@@ -7259,7 +7259,7 @@ snapshots:
|
||||
async-retry: 1.3.3
|
||||
debug: 4.4.3
|
||||
ws: 8.21.3
|
||||
zod: 4.4.3
|
||||
zod: 4.6.7
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bufferutil
|
||||
@@ -7570,7 +7570,7 @@ snapshots:
|
||||
smol-toml: 1.9.1
|
||||
undici: 6.28.1
|
||||
uuid: 14.0.1
|
||||
zod: 4.1.11
|
||||
zod: 4.6.7
|
||||
optionalDependencies:
|
||||
'@vercel/vc-native-darwin-arm64': 64.0.2
|
||||
'@vercel/vc-native-darwin-x64': 64.0.2
|
||||
@@ -7651,10 +7651,8 @@ snapshots:
|
||||
buffer-crc32: 0.2.13
|
||||
fd-slicer: 1.1.0
|
||||
|
||||
zod@3.22.4: {}
|
||||
zod@3.25.76(patch_hash=8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec): {}
|
||||
|
||||
zod@4.1.11: {}
|
||||
|
||||
zod@4.4.3: {}
|
||||
zod@4.6.7: {}
|
||||
|
||||
zwitch@2.0.4: {}
|
||||
|
||||
@@ -5,6 +5,9 @@ allowBuilds:
|
||||
sharp: true
|
||||
|
||||
overrides:
|
||||
# Vercel still requires Zod 3; pin the version with our security backport.
|
||||
zod@>=3 <4: 3.25.76
|
||||
zod@>=4 <4.6.6: 4.6.7
|
||||
path-to-regexp@>=4.0.0 <6.3.0: 6.3.0
|
||||
'@vercel/node>undici': 6.28.1
|
||||
'@vercel/python-analysis>js-yaml': 4.3.2
|
||||
@@ -21,4 +24,5 @@ overrides:
|
||||
'@vercel/container>smol-toml': 1.9.1
|
||||
|
||||
patchedDependencies:
|
||||
zod@3.25.76: ../../config/patches/zod@3.25.76.patch
|
||||
braces@3.0.3: ../../config/patches/braces@3.0.3.patch
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { createRequire } from 'node:module'
|
||||
import { dirname, join } from 'node:path'
|
||||
import test from 'node:test'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const vercelRequire = createRequire(require.resolve('vercel/package.json'))
|
||||
const backendsRequire = createRequire(vercelRequire.resolve('@vercel/backends/package.json'))
|
||||
const zodRoot = dirname(backendsRequire.resolve('zod/package.json'))
|
||||
|
||||
for (const extension of ['cjs', 'js']) {
|
||||
for (const entry of ['index', 'v3/index', 'v4/index']) {
|
||||
test(`Vercel Zod rejects oversized collections before parsing elements (${entry}.${extension})`, async () => {
|
||||
const path = join(zodRoot, `${entry}.${extension}`)
|
||||
const z = extension === 'cjs' ? require(path) : await import(pathToFileURL(path).href)
|
||||
let parsed = 0
|
||||
const element = z.preprocess((value) => {
|
||||
parsed += 1
|
||||
return value
|
||||
}, z.string())
|
||||
for (const [schema, value, valid] of [
|
||||
[z.array(element).max(2), Array(1_000).fill(0), ['a']],
|
||||
[z.array(element).length(2), Array(1_000).fill(0), ['a', 'b']],
|
||||
[z.set(element).max(2), new Set([1, 2, 3]), new Set(['a'])],
|
||||
[z.set(element).size(2), new Set([1, 2, 3]), new Set(['a', 'b'])]
|
||||
]) {
|
||||
parsed = 0
|
||||
for (const result of [schema.safeParse(value), await schema.safeParseAsync(value)]) {
|
||||
assert.equal(result.success, false)
|
||||
assert.deepEqual(
|
||||
result.error.issues.map((issue) => issue.code),
|
||||
['too_big']
|
||||
)
|
||||
}
|
||||
assert.equal(parsed, 0)
|
||||
assert.deepEqual(schema.parse(valid), valid)
|
||||
assert.deepEqual(await schema.parseAsync(valid), valid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
test('docs Zod 4 keeps valid schemas working after the security upgrade', async () => {
|
||||
const { z } = await import('zod')
|
||||
const schema = z.array(z.string()).max(2)
|
||||
assert.deepEqual(schema.parse(['a']), ['a'])
|
||||
assert.deepEqual(
|
||||
schema.safeParse([1, 2, 3]).error.issues.map((issue) => issue.code),
|
||||
['too_big']
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1,175 @@
|
||||
diff --git a/src/v3/types.ts b/src/v3/types.ts
|
||||
--- a/src/v3/types.ts
|
||||
+++ b/src/v3/types.ts
|
||||
@@ -2263,6 +2263,7 @@
|
||||
exact: true,
|
||||
message: def.exactLength.message,
|
||||
});
|
||||
+ if (tooBig) return INVALID;
|
||||
status.dirty();
|
||||
}
|
||||
}
|
||||
@@ -2291,7 +2292,7 @@
|
||||
exact: false,
|
||||
message: def.maxLength.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3723,7 +3724,7 @@
|
||||
exact: false,
|
||||
message: def.maxSize.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/v3/types.js b/v3/types.js
|
||||
--- a/v3/types.js
|
||||
+++ b/v3/types.js
|
||||
@@ -1769,6 +1769,7 @@
|
||||
exact: true,
|
||||
message: def.exactLength.message,
|
||||
});
|
||||
+ if (tooBig) return INVALID;
|
||||
status.dirty();
|
||||
}
|
||||
}
|
||||
@@ -1795,7 +1796,7 @@
|
||||
exact: false,
|
||||
message: def.maxLength.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return INVALID;
|
||||
}
|
||||
}
|
||||
if (ctx.common.async) {
|
||||
@@ -2814,7 +2815,7 @@
|
||||
exact: false,
|
||||
message: def.maxSize.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return INVALID;
|
||||
}
|
||||
}
|
||||
const valueType = this._def.valueType;
|
||||
diff --git a/v3/types.cjs b/v3/types.cjs
|
||||
--- a/v3/types.cjs
|
||||
+++ b/v3/types.cjs
|
||||
@@ -1790,6 +1790,7 @@
|
||||
exact: true,
|
||||
message: def.exactLength.message,
|
||||
});
|
||||
+ if (tooBig) return parseUtil_js_1.INVALID;
|
||||
status.dirty();
|
||||
}
|
||||
}
|
||||
@@ -1816,7 +1817,7 @@
|
||||
exact: false,
|
||||
message: def.maxLength.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return parseUtil_js_1.INVALID;
|
||||
}
|
||||
}
|
||||
if (ctx.common.async) {
|
||||
@@ -2843,7 +2844,7 @@
|
||||
exact: false,
|
||||
message: def.maxSize.message,
|
||||
});
|
||||
- status.dirty();
|
||||
+ return parseUtil_js_1.INVALID;
|
||||
}
|
||||
}
|
||||
const valueType = this._def.valueType;
|
||||
diff --git a/src/v4/core/schemas.ts b/src/v4/core/schemas.ts
|
||||
--- a/src/v4/core/schemas.ts
|
||||
+++ b/src/v4/core/schemas.ts
|
||||
@@ -242,6 +242,26 @@
|
||||
};
|
||||
|
||||
inst._zod.run = (payload, ctx) => {
|
||||
+ const value = payload.value;
|
||||
+ const size = def.type === "array" && Array.isArray(value) ? value.length
|
||||
+ : (def.type === "map" && value instanceof Map) || (def.type === "set" && value instanceof Set) ? value.size : -1;
|
||||
+ if (size >= 0) {
|
||||
+ for (const ch of checks) {
|
||||
+ const checkDef = ch._zod.def;
|
||||
+ if (!["min_length", "max_length", "length_equals", "min_size", "max_size", "size_equals"].includes(checkDef.check)) break;
|
||||
+ const maximum = "maximum" in checkDef ? checkDef.maximum
|
||||
+ : "length" in checkDef ? checkDef.length : "size" in checkDef ? checkDef.size : undefined;
|
||||
+ if (typeof maximum === "number" && size > maximum && (!checkDef.when || checkDef.when(payload))) {
|
||||
+ const start = payload.issues.length;
|
||||
+ // SAFETY: Built-in size checks run only after the matching collection type guard.
|
||||
+ ch._zod.check(payload as ParsePayload<never>);
|
||||
+ for (let i = start; i < payload.issues.length; i++) {
|
||||
+ payload.issues[i] = { ...payload.issues[i], continue: false };
|
||||
+ }
|
||||
+ return payload;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
const result = inst._zod.parse(payload, ctx);
|
||||
|
||||
if (result instanceof Promise) {
|
||||
diff --git a/v4/core/schemas.js b/v4/core/schemas.js
|
||||
--- a/v4/core/schemas.js
|
||||
+++ b/v4/core/schemas.js
|
||||
@@ -74,6 +74,25 @@
|
||||
return payload;
|
||||
};
|
||||
inst._zod.run = (payload, ctx) => {
|
||||
+ const value = payload.value;
|
||||
+ const size = def.type === "array" && Array.isArray(value) ? value.length
|
||||
+ : (def.type === "map" && value instanceof Map) || (def.type === "set" && value instanceof Set) ? value.size : -1;
|
||||
+ if (size >= 0) {
|
||||
+ for (const ch of checks) {
|
||||
+ const checkDef = ch._zod.def;
|
||||
+ if (!["min_length", "max_length", "length_equals", "min_size", "max_size", "size_equals"].includes(checkDef.check)) break;
|
||||
+ const maximum = "maximum" in checkDef ? checkDef.maximum
|
||||
+ : "length" in checkDef ? checkDef.length : "size" in checkDef ? checkDef.size : undefined;
|
||||
+ if (typeof maximum === "number" && size > maximum && (!checkDef.when || checkDef.when(payload))) {
|
||||
+ const start = payload.issues.length;
|
||||
+ ch._zod.check(payload);
|
||||
+ for (let i = start; i < payload.issues.length; i++) {
|
||||
+ payload.issues[i] = { ...payload.issues[i], continue: false };
|
||||
+ }
|
||||
+ return payload;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
const result = inst._zod.parse(payload, ctx);
|
||||
if (result instanceof Promise) {
|
||||
if (ctx.async === false)
|
||||
diff --git a/v4/core/schemas.cjs b/v4/core/schemas.cjs
|
||||
--- a/v4/core/schemas.cjs
|
||||
+++ b/v4/core/schemas.cjs
|
||||
@@ -104,6 +104,25 @@
|
||||
return payload;
|
||||
};
|
||||
inst._zod.run = (payload, ctx) => {
|
||||
+ const value = payload.value;
|
||||
+ const size = def.type === "array" && Array.isArray(value) ? value.length
|
||||
+ : (def.type === "map" && value instanceof Map) || (def.type === "set" && value instanceof Set) ? value.size : -1;
|
||||
+ if (size >= 0) {
|
||||
+ for (const ch of checks) {
|
||||
+ const checkDef = ch._zod.def;
|
||||
+ if (!["min_length", "max_length", "length_equals", "min_size", "max_size", "size_equals"].includes(checkDef.check)) break;
|
||||
+ const maximum = "maximum" in checkDef ? checkDef.maximum
|
||||
+ : "length" in checkDef ? checkDef.length : "size" in checkDef ? checkDef.size : undefined;
|
||||
+ if (typeof maximum === "number" && size > maximum && (!checkDef.when || checkDef.when(payload))) {
|
||||
+ const start = payload.issues.length;
|
||||
+ ch._zod.check(payload);
|
||||
+ for (let i = start; i < payload.issues.length; i++) {
|
||||
+ payload.issues[i] = { ...payload.issues[i], continue: false };
|
||||
+ }
|
||||
+ return payload;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
const result = inst._zod.parse(payload, ctx);
|
||||
if (result instanceof Promise) {
|
||||
if (ctx.async === false)
|
||||
Generated
+4
-2
@@ -163,6 +163,7 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
zod@>=3 <4: 3.25.76
|
||||
dompurify@<3.4.17: 3.4.17
|
||||
sprintf-js@<1.1.3: 1.1.3
|
||||
markdown-it@>=14.0.0 <14.3.3: 14.3.3
|
||||
@@ -179,6 +180,7 @@ patchedDependencies:
|
||||
react-native-webview@13.16.2: 55b7bce35c78ee1a50c4b99ad65b52982f3cfa73da6f61d0853c4d03219eec06
|
||||
react-native@0.83.10: 22bc31f0a057b1f96d9949b38a7ccde81225f617c0f243820dc8a455c91debfb
|
||||
sprintf-js@1.1.3: 05316a8b01f155fe19a1e0cb4042c81d43d798a76755c407684e1199a18b1e08
|
||||
zod@3.25.76: 8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec
|
||||
|
||||
importers:
|
||||
|
||||
@@ -8769,7 +8771,7 @@ snapshots:
|
||||
toqr: 0.1.1
|
||||
wrap-ansi: 7.0.0
|
||||
ws: 8.22.0
|
||||
zod: 3.25.76
|
||||
zod: 3.25.76(patch_hash=8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec)
|
||||
optionalDependencies:
|
||||
expo-router: 55.0.18(589555b6d8c5573172d9947cbca71959)
|
||||
react-native: 0.83.10(patch_hash=22bc31f0a057b1f96d9949b38a7ccde81225f617c0f243820dc8a455c91debfb)(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.85.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.8)(supports-color@8.1.1)
|
||||
@@ -15524,7 +15526,7 @@ snapshots:
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
zod@3.25.76: {}
|
||||
zod@3.25.76(patch_hash=8f57d8e7910df51ec3c40c412b4f8fb3d01fd65e1889c057aae0e4a15483bcec): {}
|
||||
|
||||
zod@4.6.7: {}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ allowBuilds:
|
||||
minimumReleaseAge: 4320
|
||||
|
||||
overrides:
|
||||
# Expo still requires Zod 3; pin the version with our security backport.
|
||||
zod@>=3 <4: 3.25.76
|
||||
dompurify@<3.4.17: 3.4.17
|
||||
sprintf-js@<1.1.3: 1.1.3
|
||||
markdown-it@>=14.0.0 <14.3.3: 14.3.3
|
||||
@@ -17,6 +19,7 @@ overrides:
|
||||
query-string: 9.5.1
|
||||
|
||||
patchedDependencies:
|
||||
zod@3.25.76: patches/zod@3.25.76.patch
|
||||
sprintf-js@1.1.3: patches/sprintf-js@1.1.3.patch
|
||||
'@xterm/addon-webgl@0.20.0-beta.300': patches/@xterm__addon-webgl@0.20.0-beta.300.patch
|
||||
expo-notifications@55.0.27: patches/expo-notifications@55.0.27.patch
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
import { createRequire } from 'node:module'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const expoRequire = createRequire(require.resolve('expo'))
|
||||
const cliRequire = createRequire(expoRequire.resolve('@expo/cli'))
|
||||
const zodRoot = dirname(cliRequire.resolve('zod/package.json'))
|
||||
|
||||
describe.each(['cjs', 'js'])('installed Expo Zod (%s)', (extension) => {
|
||||
it.each(['index', 'v3/index', 'v4/index'])(
|
||||
'rejects oversized collections before parsing elements in %s',
|
||||
async (entry) => {
|
||||
const path = join(zodRoot, `${entry}.${extension}`)
|
||||
const z = extension === 'cjs' ? require(path) : await import(pathToFileURL(path).href)
|
||||
let parsed = 0
|
||||
let refined = 0
|
||||
const element = z.preprocess((value: unknown) => {
|
||||
parsed += 1
|
||||
return value
|
||||
}, z.string())
|
||||
const cases = [
|
||||
{
|
||||
schema: z.array(element).max(2, 'too many'),
|
||||
oversized: Array(1_000).fill(0),
|
||||
valid: ['a', 'b']
|
||||
},
|
||||
{
|
||||
schema: z.array(element).length(2, 'too many'),
|
||||
oversized: Array(1_000).fill(0),
|
||||
valid: ['a', 'b']
|
||||
},
|
||||
{
|
||||
schema: z.set(element).max(2, 'too many'),
|
||||
oversized: new Set(Array.from({ length: 1_000 }, (_, i) => i)),
|
||||
valid: new Set(['a', 'b'])
|
||||
},
|
||||
{
|
||||
schema: z.set(element).size(2, 'too many'),
|
||||
oversized: new Set(Array.from({ length: 1_000 }, (_, i) => i)),
|
||||
valid: new Set(['a', 'b'])
|
||||
}
|
||||
]
|
||||
for (const { schema, oversized, valid } of cases) {
|
||||
const parent = z.object({ items: schema }).refine(() => {
|
||||
refined += 1
|
||||
return true
|
||||
})
|
||||
parsed = 0
|
||||
refined = 0
|
||||
for (const result of [
|
||||
parent.safeParse({ items: oversized }),
|
||||
await parent.safeParseAsync({ items: oversized })
|
||||
]) {
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error.issues).toEqual([
|
||||
expect.objectContaining({ code: 'too_big', path: ['items'], message: 'too many' })
|
||||
])
|
||||
}
|
||||
expect([parsed, refined]).toEqual([0, 0])
|
||||
expect(parent.parse({ items: valid })).toEqual({ items: valid })
|
||||
expect(await parent.parseAsync({ items: valid })).toEqual({ items: valid })
|
||||
expect(parsed).toBe(4)
|
||||
}
|
||||
expect(z.array(z.string()).max(2).safeParse([1]).success).toBe(false)
|
||||
expect(z.array(z.string()).length(2).safeParse(['a']).success).toBe(false)
|
||||
expect(
|
||||
z
|
||||
.set(z.string())
|
||||
.size(2)
|
||||
.safeParse(new Set(['a'])).success
|
||||
).toBe(false)
|
||||
if (entry === 'v4/index') {
|
||||
expect(
|
||||
z
|
||||
.array(z.number())
|
||||
.overwrite((items: number[]) => items.slice(0, 2))
|
||||
.max(2)
|
||||
.parse([1, 2, 3])
|
||||
).toEqual([1, 2])
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
it('protects the bundled Zod mini entrypoint', async () => {
|
||||
const path = join(zodRoot, `v4/mini/index.${extension}`)
|
||||
const z = extension === 'cjs' ? require(path) : await import(pathToFileURL(path).href)
|
||||
const schema = z.array(z.string()).check(z.maxLength(2))
|
||||
expect(z.safeParse(schema, [1, 2, 3]).error.issues).toEqual([
|
||||
expect.objectContaining({ code: 'too_big' })
|
||||
])
|
||||
expect((await z.safeParseAsync(schema, [1, 2, 3])).error.issues).toHaveLength(1)
|
||||
expect(z.parse(schema, ['a'])).toEqual(['a'])
|
||||
const map = z.map(z.string(), z.string()).check(z.maxSize(1))
|
||||
const oversized = new Map([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
])
|
||||
expect(z.safeParse(map, oversized).error.issues).toEqual([
|
||||
expect.objectContaining({ code: 'too_big' })
|
||||
])
|
||||
expect((await z.safeParseAsync(map, oversized)).error.issues).toHaveLength(1)
|
||||
expect(z.parse(map, new Map([['a', 'b']]))).toEqual(new Map([['a', 'b']]))
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user