fs.globSync() uses process.cwd() when building the root exclude Dirent with withFileTypes
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 76/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- javascript
- Ambito
- operating-systems
Direzione di ricerca
Inizia in lib/internal/fs/glob.js, in #addSubpattern(), confrontando il ramo sincrono di withFileTypes ed exclude con il percorso asincrono. Riproduci il problema con lo script fornito, quindi verifica che il callback di exclude riceva un Dirent per il glob cwd anziché per process.cwd() e che la directory venga esclusa.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Version
v25.8.2
Platform
Darwin arm64
Subsystem
fs
What steps will reproduce the bug?
const { mkdtempSync, mkdirSync, writeFileSync, globSync } = require('node:fs');
const { tmpdir } = require('node:os');
const { join } = require('node:path');
const { chdir, cwd } = require('node:process');
const base = mkdtempSync(join(tmpdir(), 'glob-root-'));
const ambient = join(base, 'ambient');
const root = join(base, 'root');
mkdirSync(ambient, { recursive: true });
mkdirSync(join(root, 'a'), { recursive: true });
writeFileSync(join(ambient, 'a'), 'shadow-file');
writeFileSync(join(root, 'a', 'real.txt'), 'real');
chdir(ambient);
const seen = [];
const result = globSync('a/**', {
cwd: root,
withFileTypes: true,
exclude: (dirent) => {
seen.push({
name: dirent.name,
parentPath: dirent.parentPath,
isDirectory: dirent.isDirectory(),
isFile: dirent.isFile(),
});
return dirent.isDirectory();
},
});
console.log(JSON.stringify({
processCwd: cwd(),
globCwd: root,
seen,
result: result.map((dirent) => ({
name: dirent.name,
parentPath: dirent.parentPath,
isDirectory: dirent.isDirectory(),
isFile: dirent.isFile(),
})),
}, null, 2));
How often does it reproduce? Is there a required condition?
It reproduces consistently in globSync() when all of the following are true:
withFileTypes: truecwd !== process.cwd()- the pattern goes through the root-entry
#addSubpattern()path (for examplea/**)
If the ambient process.cwd() also contains the same relative path, the callback receives a Dirent for the ambient path instead of the glob cwd path. If the ambient cwd does not contain that path, the root entry can skip the callback entirely because statSync(path) returns null.
The async glob path does not seem affected.
What is the expected behavior? Why is that the expected behavior?
The exclude callback should receive a Dirent describing the candidate entry under options.cwd.
For the repro above, the callback should receive a directory dirent for <globCwd>/a, so dirent.isDirectory() should be true and the result should be an empty array because the callback returns true for directories.
What do you see instead?
The callback receives a Dirent for the ambient process.cwd() path instead:
{
"processCwd": "/tmp/.../ambient",
"globCwd": "/tmp/.../root",
"seen": [
{
"name": "a",
"parentPath": ".",
"isDirectory": false,
"isFile": true
},
{
"name": "real.txt",
"parentPath": "/tmp/.../root/a",
"isDirectory": false,
"isFile": true
}
],
"result": [
{
"name": "a",
"parentPath": "/tmp/.../root",
"isDirectory": true,
"isFile": false
},
{
"name": "real.txt",
"parentPath": "/tmp/.../root/a",
"isDirectory": false,
"isFile": true
}
]
}
So the root a entry is not excluded even though the callback logic is meant to exclude directories.
Additional information
This looks like a sync-only regression in the root-path exclude handling added for #56260 / #57420.
In lib/internal/fs/glob.js, #addSubpattern() computes const fullpath = resolve(this.#root, path), but in the withFileTypes + exclude branch it does:
const stat = this.#cache.statSync(path);
That appears to stat a path relative to process.cwd() instead of options.cwd. The async path already uses await this.#cache.stat(fullpath).
- Lingua principale
- JavaScript
- Stelle
- 122k
- Fork
- 37.4k
- Merge medio
- 4g 3h
- PR unite (30g)
- 279
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di nodejs/node
-
doc
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
-
build
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
-
feature request
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
Issue simili
-
awaiting triage bug Causes friction Hop Gui P1 P2 Transforms
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
Improve Title Support Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
georgestephanis/p2026#40 ·
-
Enatega Customer and Rider app: Add-ons price is not visible to customer after order is placed. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
Margaret-Petersen/food-delivery-app-clone-react-native#1981 ·