From 59b82bb72fb6d9889caedf9c64bd25bd2867616b Mon Sep 17 00:00:00 2001 From: Sylphy-0xd3ac Date: Fri, 1 Aug 2025 08:06:56 +0800 Subject: [PATCH] fs: fix glob TypeError on restricted dirs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-By: James M Snell Reviewed-By: Ethan-Arrowood Reviewed-By: Juan José --- lib/internal/fs/glob.js | 2 +- test/parallel/test-fs-glob.mjs | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/internal/fs/glob.js b/lib/internal/fs/glob.js index 14180f936ac1c8..05252348daee7a 100644 --- a/lib/internal/fs/glob.js +++ b/lib/internal/fs/glob.js @@ -143,7 +143,7 @@ class Cache { if (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); return promise; } diff --git a/test/parallel/test-fs-glob.mjs b/test/parallel/test-fs-glob.mjs index b3708f466379fa..490ea2478232ae 100644 --- a/test/parallel/test-fs-glob.mjs +++ b/test/parallel/test-fs-glob.mjs @@ -2,7 +2,7 @@ import * as common from '../common/index.mjs'; import tmpdir from '../common/tmpdir.js'; import { resolve, dirname, sep, relative, join, isAbsolute } from 'node:path'; 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 { pathToFileURL } from 'node:url'; 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 + } + } + }); +});