fs: fix glob TypeError on restricted dirs

When a directory cannot be read due to permission issues, the async
version of fs.glob() returns null from readdir(), while the sync
version returns an empty array. This causes a TypeError when trying
to access the 'length' property of null.

PR-URL: https://github.com/nodejs/node/pull/58674
Fixes: https://github.com/nodejs/node/issues/58670
Fixes: https://github.com/nodejs/node/issues/58276
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ethan-Arrowood <ethan@arrowood.dev>
Reviewed-By: Juan José <soyjuanarbol@gmail.com>
This commit is contained in:
Sylphy-0xd3ac 2025-08-01 08:06:56 +08:00 committed by James M Snell
parent 5f5f9cb015
commit 5794e644b7
2 changed files with 23 additions and 2 deletions

View file

@ -143,7 +143,7 @@ class Cache {
if (cached) { if (cached) {
return cached; return cached;
} }
const promise = PromisePrototypeThen(readdir(path, { __proto__: null, withFileTypes: true }), null, () => null); const promise = PromisePrototypeThen(readdir(path, { __proto__: null, withFileTypes: true }), null, () => []);
this.#readdirCache.set(path, promise); this.#readdirCache.set(path, promise);
return promise; return promise;
} }

View file

@ -2,7 +2,7 @@ import * as common from '../common/index.mjs';
import tmpdir from '../common/tmpdir.js'; import tmpdir from '../common/tmpdir.js';
import { resolve, dirname, sep, relative, join, isAbsolute } from 'node:path'; import { resolve, dirname, sep, relative, join, isAbsolute } from 'node:path';
import { mkdir, writeFile, symlink, glob as asyncGlob } from 'node:fs/promises'; import { mkdir, writeFile, symlink, glob as asyncGlob } from 'node:fs/promises';
import { glob, globSync, Dirent } from 'node:fs'; import { glob, globSync, Dirent, chmodSync } from 'node:fs';
import { test, describe } from 'node:test'; import { test, describe } from 'node:test';
import { pathToFileURL } from 'node:url'; import { pathToFileURL } from 'node:url';
import { promisify } from 'node:util'; import { promisify } from 'node:util';
@ -518,3 +518,24 @@ describe('fsPromises glob - exclude', function() {
}); });
} }
}); });
describe('glob - with restricted directory', function() {
test('*', async () => {
const restrictedDir = tmpdir.resolve('restricted');
await mkdir(restrictedDir, { recursive: true });
chmodSync(restrictedDir, 0o000);
try {
const results = [];
for await (const match of asyncGlob('*', { cwd: restrictedDir })) {
results.push(match);
}
assert.ok(true, 'glob completed without throwing on readdir error');
} finally {
try {
chmodSync(restrictedDir, 0o755);
} catch {
// ignore
}
}
});
});