mirror of
https://github.com/denoland/deno.git
synced 2025-01-21 13:00:36 -05:00
fix(node/fs): add missing stat path argument validation (#27086)
We didn't validate the `path` argument that's passed to `fs.stat()` and `fs.statSync()` which lead to wrong errors being thrown. The `@rollup/plugin-node-resolve` code calls it with `undefined` quite a lot which lead to `nitro` and `nuxt` failing. Fixes https://github.com/denoland/deno/issues/26700 --------- Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
This commit is contained in:
parent
42b71d82db
commit
927352bd4e
3 changed files with 44 additions and 2 deletions
|
@ -6,6 +6,7 @@
|
||||||
import { denoErrorToNodeError } from "ext:deno_node/internal/errors.ts";
|
import { denoErrorToNodeError } from "ext:deno_node/internal/errors.ts";
|
||||||
import { promisify } from "ext:deno_node/internal/util.mjs";
|
import { promisify } from "ext:deno_node/internal/util.mjs";
|
||||||
import { primordials } from "ext:core/mod.js";
|
import { primordials } from "ext:core/mod.js";
|
||||||
|
import { getValidatedPath } from "ext:deno_node/internal/fs/utils.mjs";
|
||||||
|
|
||||||
const { ObjectCreate, ObjectAssign } = primordials;
|
const { ObjectCreate, ObjectAssign } = primordials;
|
||||||
|
|
||||||
|
@ -379,6 +380,7 @@ export function stat(
|
||||||
? optionsOrCallback
|
? optionsOrCallback
|
||||||
: { bigint: false };
|
: { bigint: false };
|
||||||
|
|
||||||
|
path = getValidatedPath(path).toString();
|
||||||
if (!callback) throw new Error("No callback function supplied");
|
if (!callback) throw new Error("No callback function supplied");
|
||||||
|
|
||||||
Deno.stat(path).then(
|
Deno.stat(path).then(
|
||||||
|
@ -409,6 +411,8 @@ export function statSync(
|
||||||
path: string | URL,
|
path: string | URL,
|
||||||
options: statOptions = { bigint: false, throwIfNoEntry: true },
|
options: statOptions = { bigint: false, throwIfNoEntry: true },
|
||||||
): Stats | BigIntStats | undefined {
|
): Stats | BigIntStats | undefined {
|
||||||
|
path = getValidatedPath(path).toString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const origin = Deno.statSync(path);
|
const origin = Deno.statSync(path);
|
||||||
return CFISBIS(origin, options.bigint);
|
return CFISBIS(origin, options.bigint);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
import { assertCallbackErrorUncaught } from "../_test_utils.ts";
|
import { assertCallbackErrorUncaught } from "../_test_utils.ts";
|
||||||
import { BigIntStats, stat, Stats, statSync } from "node:fs";
|
import { BigIntStats, stat, Stats, statSync } from "node:fs";
|
||||||
import { assertEquals, fail } from "@std/assert";
|
import { assert, assertEquals, fail } from "@std/assert";
|
||||||
|
|
||||||
export function assertStats(actual: Stats, expected: Deno.FileInfo) {
|
export function assertStats(actual: Stats, expected: Deno.FileInfo) {
|
||||||
assertEquals(actual.dev, expected.dev);
|
assertEquals(actual.dev, expected.dev);
|
||||||
|
@ -152,3 +152,38 @@ Deno.test({
|
||||||
assertEquals(stats.isSocket(), false);
|
assertEquals(stats.isSocket(), false);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: "[node/fs] stat invalid path error",
|
||||||
|
async fn() {
|
||||||
|
try {
|
||||||
|
await new Promise<Stats>((resolve, reject) => {
|
||||||
|
stat(
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
undefined as any,
|
||||||
|
(err, stats) => err ? reject(err) : resolve(stats),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
fail();
|
||||||
|
} catch (err) {
|
||||||
|
assert(err instanceof TypeError);
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
assertEquals((err as any).code, "ERR_INVALID_ARG_TYPE");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: "[node/fs] statSync invalid path error",
|
||||||
|
fn() {
|
||||||
|
try {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
statSync(undefined as any);
|
||||||
|
fail();
|
||||||
|
} catch (err) {
|
||||||
|
assert(err instanceof TypeError);
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
assertEquals((err as any).code, "ERR_INVALID_ARG_TYPE");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
/// <reference lib="deno.ns" />
|
/// <reference lib="deno.ns" />
|
||||||
import { assert, assertEquals, assertRejects, assertThrows } from "@std/assert";
|
import { assert, assertEquals, assertRejects, assertThrows } from "@std/assert";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import {
|
import {
|
||||||
closeSync,
|
closeSync,
|
||||||
|
@ -160,7 +161,9 @@ Deno.test(
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
`${error}`,
|
`${error}`,
|
||||||
`Error: ENOENT: no such file or directory, stat '${fileUrl.pathname}'`,
|
`Error: ENOENT: no such file or directory, stat '${
|
||||||
|
fileURLToPath(fileUrl)
|
||||||
|
}'`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue