Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit594eb0e

Browse files
authored
fix: do not crash on error infs.walk filter (#18295)
* fix: do not crash on error in `fs.walk` filter* `wrapCallback` → `wrapFilter`* do not avoid multiple resolves
1 parent751b518 commit594eb0e

File tree

2 files changed

+114
-45
lines changed

2 files changed

+114
-45
lines changed

‎lib/eslint/eslint-helpers.js‎

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ const fsp = fs.promises;
1515
constisGlob=require("is-glob");
1616
consthash=require("../cli-engine/hash");
1717
constminimatch=require("minimatch");
18-
constutil=require("util");
1918
constfswalk=require("@nodelib/fs.walk");
2019
constglobParent=require("glob-parent");
2120
constisPathInside=require("is-path-inside");
@@ -24,7 +23,6 @@ const isPathInside = require("is-path-inside");
2423
// Fixup references
2524
//-----------------------------------------------------------------------------
2625

27-
constdoFsWalk=util.promisify(fswalk.walk);
2826
constMinimatch=minimatch.Minimatch;
2927
constMINIMATCH_OPTIONS={dot:true};
3028

@@ -280,56 +278,92 @@ async function globSearch({
280278
*/
281279
constunmatchedPatterns=newSet([...relativeToPatterns.keys()]);
282280

283-
constfilePaths=(awaitdoFsWalk(basePath,{
281+
constfilePaths=(awaitnewPromise((resolve,reject)=>{
284282

285-
deepFilter(entry){
286-
constrelativePath=normalizeToPosix(path.relative(basePath,entry.path));
287-
constmatchesPattern=matchers.some(matcher=>matcher.match(relativePath,true));
288-
289-
returnmatchesPattern&&!configs.isDirectoryIgnored(entry.path);
290-
},
291-
entryFilter(entry){
292-
constrelativePath=normalizeToPosix(path.relative(basePath,entry.path));
283+
letpromiseRejected=false;
293284

294-
// entries may be directories or files so filter out directories
295-
if(entry.dirent.isDirectory()){
285+
/**
286+
* Wraps a boolean-returning filter function. The wrapped function will reject the promise if an error occurs.
287+
*@param {Function} filter A filter function to wrap.
288+
*@returns {Function} A function similar to the wrapped filter that rejects the promise if an error occurs.
289+
*/
290+
functionwrapFilter(filter){
291+
return(...args)=>{
292+
293+
// No need to run the filter if an error has been thrown.
294+
if(!promiseRejected){
295+
try{
296+
returnfilter(...args);
297+
}catch(error){
298+
promiseRejected=true;
299+
reject(error);
300+
}
301+
}
296302
returnfalse;
297-
}
303+
};
304+
}
298305

299-
/*
300-
* Optimization: We need to track when patterns are left unmatched
301-
* and so we use `unmatchedPatterns` to do that. There is a bit of
302-
* complexity here because the same file can be matched by more than
303-
* one pattern. So, when we start, we actually need to test every
304-
* pattern against every file. Once we know there are no remaining
305-
* unmatched patterns, then we can switch to just looking for the
306-
* first matching pattern for improved speed.
307-
*/
308-
constmatchesPattern=unmatchedPatterns.size>0
309-
?matchers.reduce((previousValue,matcher)=>{
310-
constpathMatches=matcher.match(relativePath);
306+
fswalk.walk(
307+
basePath,
308+
{
309+
deepFilter:wrapFilter(entry=>{
310+
constrelativePath=normalizeToPosix(path.relative(basePath,entry.path));
311+
constmatchesPattern=matchers.some(matcher=>matcher.match(relativePath,true));
312+
313+
returnmatchesPattern&&!configs.isDirectoryIgnored(entry.path);
314+
}),
315+
entryFilter:wrapFilter(entry=>{
316+
constrelativePath=normalizeToPosix(path.relative(basePath,entry.path));
317+
318+
// entries may be directories or files so filter out directories
319+
if(entry.dirent.isDirectory()){
320+
returnfalse;
321+
}
311322

312323
/*
313-
* We updated the unmatched patterns set only if the path
314-
* matches and the file isn't ignored. If the file is
315-
* ignored, that means there wasn't a match for the
316-
* pattern so it should not be removed.
317-
*
318-
* Performance note: isFileIgnored() aggressively caches
319-
* results so there is no performance penalty for calling
320-
* it twice with the same argument.
324+
* Optimization: We need to track when patterns are left unmatched
325+
* and so we use `unmatchedPatterns` to do that. There is a bit of
326+
* complexity here because the same file can be matched by more than
327+
* one pattern. So, when we start, we actually need to test every
328+
* pattern against every file. Once we know there are no remaining
329+
* unmatched patterns, then we can switch to just looking for the
330+
* first matching pattern for improved speed.
321331
*/
322-
if(pathMatches&&!configs.isFileIgnored(entry.path)){
323-
unmatchedPatterns.delete(matcher.pattern);
324-
}
325-
326-
returnpathMatches||previousValue;
327-
},false)
328-
:matchers.some(matcher=>matcher.match(relativePath));
329-
330-
returnmatchesPattern&&!configs.isFileIgnored(entry.path);
331-
}
332-
332+
constmatchesPattern=unmatchedPatterns.size>0
333+
?matchers.reduce((previousValue,matcher)=>{
334+
constpathMatches=matcher.match(relativePath);
335+
336+
/*
337+
* We updated the unmatched patterns set only if the path
338+
* matches and the file isn't ignored. If the file is
339+
* ignored, that means there wasn't a match for the
340+
* pattern so it should not be removed.
341+
*
342+
* Performance note: isFileIgnored() aggressively caches
343+
* results so there is no performance penalty for calling
344+
* it twice with the same argument.
345+
*/
346+
if(pathMatches&&!configs.isFileIgnored(entry.path)){
347+
unmatchedPatterns.delete(matcher.pattern);
348+
}
349+
350+
returnpathMatches||previousValue;
351+
},false)
352+
:matchers.some(matcher=>matcher.match(relativePath));
353+
354+
returnmatchesPattern&&!configs.isFileIgnored(entry.path);
355+
})
356+
},
357+
(error,entries)=>{
358+
359+
// If the promise is already rejected, calling `resolve` or `reject` will do nothing.
360+
if(error){
361+
reject(error);
362+
}else{
363+
resolve(entries);
364+
}
365+
}
366+
);
333367
})).map(entry=>entry.path);
334368

335369
// now check to see if we have any unmatched patterns

‎tests/lib/eslint/eslint.js‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4515,6 +4515,41 @@ describe("ESLint", () => {
45154515
assert.strictEqual(createCallCount,1);
45164516
});
45174517

4518+
describe("Error while globbing",()=>{
4519+
4520+
it("should throw an error with a glob pattern if an invalid config was provided",async()=>{
4521+
4522+
constcwd=getFixturePath("files");
4523+
4524+
eslint=newESLint({
4525+
cwd,
4526+
overrideConfig:[{invalid:"foobar"}]
4527+
});
4528+
4529+
awaitassert.rejects(eslint.lintFiles("*.js"));
4530+
});
4531+
4532+
it("should throw an error with a glob pattern if an error occurs traversing a directory",async()=>{
4533+
4534+
constfsWalk=require("@nodelib/fs.walk");
4535+
consterror=newError("Boom!");
4536+
4537+
sinon
4538+
.stub(fsWalk,"walk")
4539+
.value(sinon.stub().yieldsRight(error));// call the callback passed to `fs.walk` with an error
4540+
4541+
constcwd=getFixturePath("files");
4542+
4543+
eslint=newESLint({
4544+
cwd,
4545+
overrideConfigFile:true
4546+
});
4547+
4548+
awaitassert.rejects(eslint.lintFiles("*.js"),error);
4549+
});
4550+
4551+
});
4552+
45184553
});
45194554

45204555
describe("Fix Types",()=>{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp