fix(sandbox): clamp unsafe stat sizes · openclaw/openclaw@d9db23d
steipete
·
2026-05-29
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { parseStrictNonNegativeInteger } from "../../infra/parse-finite-number.js"; |
| 2 | + |
1 | 3 | export function parseSandboxStatSize(value: string | undefined): number { |
2 | 4 | const raw = value ?? "0"; |
3 | | -if (!/^\d+$/.test(raw)) { |
4 | | -return 0; |
| 5 | +const parsed = parseStrictNonNegativeInteger(raw); |
| 6 | +if (parsed !== undefined) { |
| 7 | +return parsed; |
5 | 8 | } |
6 | | -const size = Number(raw); |
7 | | -return Number.isFinite(size) ? size : 0; |
| 9 | +return /^\d+$/.test(raw) ? Number.MAX_SAFE_INTEGER : 0; |
8 | 10 | } |
9 | 11 | |
10 | 12 | export function parseSandboxStatMtimeMs(value: string | undefined): number { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -217,7 +217,7 @@ describe("sandbox fs bridge anchored ops", () => {
|
217 | 217 | }); |
218 | 218 | }); |
219 | 219 | |
220 | | -it("does not accept partial stat size output", async () => { |
| 220 | +it("saturates unsafe stat size output", async () => { |
221 | 221 | await withTempDir("openclaw-fs-bridge-stat-parse-", async (stateDir) => { |
222 | 222 | const workspaceDir = path.join(stateDir, "workspace"); |
223 | 223 | await fs.mkdir(workspaceDir, { recursive: true }); |
@@ -228,7 +228,7 @@ describe("sandbox fs bridge anchored ops", () => {
|
228 | 228 | return dockerExecResult(`${getDockerArg(args, 1)}\n`); |
229 | 229 | } |
230 | 230 | if (script.includes('stat -c "%F|%s|%y"')) { |
231 | | -return dockerExecResult("regular file|12oops|not-a-date\n"); |
| 231 | +return dockerExecResult("regular file|9007199254740992|not-a-date\n"); |
232 | 232 | } |
233 | 233 | return dockerExecResult(""); |
234 | 234 | }); |
@@ -242,7 +242,7 @@ describe("sandbox fs bridge anchored ops", () => {
|
242 | 242 | |
243 | 243 | await expect(bridge.stat({ filePath: "note.txt" })).resolves.toMatchObject({ |
244 | 244 | type: "file", |
245 | | -size: 0, |
| 245 | +size: Number.MAX_SAFE_INTEGER, |
246 | 246 | mtimeMs: 0, |
247 | 247 | }); |
248 | 248 | }); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -182,7 +182,7 @@ describe("remote sandbox fs bridge", () => {
|
182 | 182 | }, |
183 | 183 | ); |
184 | 184 | |
185 | | -it("does not return NaN or partial values for malformed stat output", async () => { |
| 185 | +it("saturates unsafe stat size output without returning NaN", async () => { |
186 | 186 | await withTempDir("openclaw-remote-fs-bridge-stat-", async (stateDir) => { |
187 | 187 | const workspaceDir = path.join(stateDir, "workspace"); |
188 | 188 | await fs.mkdir(workspaceDir, { recursive: true }); |
@@ -209,7 +209,7 @@ describe("remote sandbox fs bridge", () => {
|
209 | 209 | } |
210 | 210 | if (command.script.includes('stat -c "%F|%s|%y"')) { |
211 | 211 | return { |
212 | | -stdout: Buffer.from("regular file|12oops|not-a-date\n"), |
| 212 | +stdout: Buffer.from("regular file|9007199254740992|not-a-date\n"), |
213 | 213 | stderr: Buffer.alloc(0), |
214 | 214 | code: 0, |
215 | 215 | }; |
@@ -227,7 +227,7 @@ describe("remote sandbox fs bridge", () => {
|
227 | 227 | |
228 | 228 | await expect(bridge.stat({ filePath: "note.txt" })).resolves.toEqual({ |
229 | 229 | type: "file", |
230 | | -size: 0, |
| 230 | +size: Number.MAX_SAFE_INTEGER, |
231 | 231 | mtimeMs: 0, |
232 | 232 | }); |
233 | 233 | }); |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。