From a1aa1472cb59cfee1b0123950367e5f30e01390b Mon Sep 17 00:00:00 2001 From: louiellan Date: Thu, 21 May 2026 06:09:43 +0800 Subject: [PATCH] fs: fix `glob` case-sensitivity inconsistencies where the `exclude` option is case sensitive but the `pattern` is a case insensitive operation (on Windows and MacOS), thus results to any casing difference in matched list not to be filtered out and does not return the true casing of a matched directory / file Signed-off-by: louiellan --- lib/internal/fs/glob.js | 2 +- test/parallel/test-fs-glob.mjs | 53 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/internal/fs/glob.js b/lib/internal/fs/glob.js index c5bbdb9813c0d1..64c1fb596f7522 100644 --- a/lib/internal/fs/glob.js +++ b/lib/internal/fs/glob.js @@ -118,7 +118,7 @@ function createMatcher(pattern, options = kEmptyObject) { nocomment: true, optimizationLevel: 2, platform: process.platform, - nocaseMagicOnly: true, + nocaseMagicOnly: (!isWindows && !isMacOS), ...options, }; return new (lazyMinimatch().Minimatch)(pattern, opts); diff --git a/test/parallel/test-fs-glob.mjs b/test/parallel/test-fs-glob.mjs index 560b4e72e4adec..d091304151d549 100644 --- a/test/parallel/test-fs-glob.mjs +++ b/test/parallel/test-fs-glob.mjs @@ -484,6 +484,59 @@ const patterns2 = [ [ 'a/**', [ '*' ], [] ], [ 'a/**', [ '**' ], [] ], [ 'a/**', [ 'a/**' ], [] ], + ...((common.isWindows || common.isMacOS) ? + // on Windows or MacOS + [ + ['a/b', ['A/B'], []], + ['a/b*', ['A/B'], ['a/bc']], + ['A*/B', ['A/B'], []], + ['a*/B', ['A/B'], []], + ['a*/b', ['A/B'], []], + + ['A/B', ['a/b'], []], + ['A/B*', ['a/b'], ['a/bc']], + ['A*/B', ['a/b'], []], + ['a*/B', ['a/b'], []], + ['A*/b', ['a/b'], []], + + ['a/b', ['A/B*'], []], + ['a/b*', ['A/B*'], []], + ['A*/B', ['A/B*'], []], + ['a*/B', ['A/B*'], []], + ['a*/b', ['A/B*'], []], + + ['A/B', ['a/b*'], []], + ['A/B*', ['a/b*'], []], + ['A*/B', ['a/b*'], []], + ['a*/B', ['a/b*'], []], + ['A*/b', ['a/b*'], []], + + ['a/b', ['A*/B'], []], + ['a/b*', ['A*/B'], ['a/bc']], + ['A*/B', ['A*/B'], []], + ['a*/B', ['A*/B'], []], + ['a*/b', ['A*/B'], []], + + ['A/B', ['a*/b'], []], + ['A/B*', ['a*/b'], ['a/bc']], + ['A*/B', ['a*/b'], []], + ['a*/B', ['a*/b'], []], + ['A*/b', ['a*/b'], []], + + ['a/b', ['A/{B,C}'], []], + ['a/b*', ['A/{B,C}'], ['a/bc']], + ['A*/B', ['A/{B,C}'], []], + ['a*/B', ['A/{B,C}'], []], + ['a*/b', ['A/{B,C}'], []], + + ['A/B', ['a/{b,c}'], []], + ['A/B*', ['a/{b,c}'], ['a/bc']], + ['A*/B', ['a/{b,c}'], []], + ['a*/B', ['a/{b,c}'], []], + ['A*/b', ['a/{b,c}'], []], + + ] : [] + ), ]; describe('globSync - exclude', function() {