Skip to content

Commit 05fbc0e

Browse files
authored
Fix matching of editorConfig sections patterns (#12953)
1 parent 9646722 commit 05fbc0e

File tree

5 files changed

+70
-14
lines changed

5 files changed

+70
-14
lines changed

Diff for: Extension/ThirdPartyNotices.txt

+26
Original file line numberDiff line numberDiff line change
@@ -2429,6 +2429,7 @@ The notices below are from non-npm sources.
24292429
- ANTLR (http://www.antlr2.org/)
24302430
- C++11 Sublime Text Snippets (https://github.com/Rapptz/cpp-sublime-snippet)
24312431
- Clang (https://clang.llvm.org/)
2432+
- editorconfig-core-js (https://github.com/editorconfig/editorconfig-core-js)
24322433
- gcc-11/libgcc (https://packages.ubuntu.com/jammy/gcc-11-base)
24332434
- Guidelines Support Library (https://github.com/Microsoft/GSL)
24342435
- libc++ (https://libcxx.llvm.org/index.html)
@@ -2677,6 +2678,31 @@ mechanisms:
26772678
=========================================
26782679
END OF Clang NOTICES AND INFORMATION
26792680

2681+
%% editorconfig-core-js NOTICES AND INFORMATION BEGIN HERE
2682+
=========================================
2683+
Copyright © 2012 EditorConfig Team
2684+
2685+
Permission is hereby granted, free of charge, to any person obtaining a copy
2686+
of this software and associated documentation files (the “Software”), to deal
2687+
in the Software without restriction, including without limitation the rights
2688+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2689+
copies of the Software, and to permit persons to whom the Software is
2690+
furnished to do so, subject to the following conditions:
2691+
2692+
The above copyright notice and this permission notice shall be included in
2693+
all copies or substantial portions of the Software.
2694+
2695+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2696+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2697+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2698+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2699+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2700+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2701+
THE SOFTWARE.
2702+
2703+
=========================================
2704+
END OF editorconfig-core-js NOTICES AND INFORMATION
2705+
26802706
%% gcc-9/libgcc NOTICES AND INFORMATION BEGIN HERE
26812707
=========================================
26822708
The following runtime libraries are licensed under the terms of the

Diff for: Extension/package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -6517,7 +6517,6 @@
65176517
"devDependencies": {
65186518
"@octokit/rest": "^20.1.1",
65196519
"@types/glob": "^7.2.0",
6520-
"@types/minimatch": "^3.0.5",
65216520
"@types/mocha": "^10.0.6",
65226521
"@types/node": "^20.14.2",
65236522
"@types/node-fetch": "^2.6.11",
@@ -6569,7 +6568,7 @@
65696568
"comment-json": "^4.2.3",
65706569
"escape-string-regexp": "^2.0.0",
65716570
"glob": "^7.2.3",
6572-
"minimatch": "^3.0.5",
6571+
"minimatch": "^4.2.0",
65736572
"mkdirp": "^3.0.1",
65746573
"node-fetch": "^2.7.0",
65756574
"node-loader": "^2.0.0",

Diff for: Extension/src/LanguageServer/client.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2577,7 +2577,8 @@ export class DefaultClient implements Client {
25772577
}
25782578
let foundGlobMatch: boolean = false;
25792579
for (const assoc in assocs) {
2580-
if (minimatch(filePath, assoc)) {
2580+
const matcher = new minimatch.Minimatch(assoc);
2581+
if (matcher.match(filePath)) {
25812582
foundGlobMatch = true;
25822583
break; // Assoc matched a glob pattern.
25832584
}

Diff for: Extension/src/LanguageServer/editorConfig.ts

+33-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
'use strict';
66

77
import * as fs from 'fs';
8+
import { Minimatch } from 'minimatch';
89
import * as path from 'path';
10+
import { isWindows } from '../constants';
911

1012
export const cachedEditorConfigSettings: Map<string, any> = new Map<string, any>();
1113

@@ -61,13 +63,25 @@ export function mapWrapToEditorConfig(value: string | undefined): string {
6163
return "never";
6264
}
6365

64-
function matchesSection(filePath: string, section: string): boolean {
65-
const fileName: string = path.basename(filePath);
66-
// Escape all regex special characters except '*' and '?'.
67-
// Convert wildcards '*' to '.*' and '?' to '.'.
68-
const sectionPattern = section.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.');
69-
const regex: RegExp = new RegExp(`^${sectionPattern}$`);
70-
return regex.test(fileName);
66+
export function matchesSection(pathPrefix: string, filePath: string, section: string): boolean {
67+
// The following code is copied from: https://github.com/editorconfig/editorconfig-core-js
68+
const matchOptions = { matchBase: true, dot: true };
69+
pathPrefix = pathPrefix.replace(/[?*+@!()|[\]{}]/g, '\\$&');
70+
pathPrefix = pathPrefix.replace(/^#/, '\\#');
71+
switch (section.indexOf('/')) {
72+
case -1:
73+
section = `**/${section}`;
74+
break;
75+
case 0:
76+
section = section.substring(1);
77+
break;
78+
default:
79+
break;
80+
}
81+
section = section.replace(/\\\\/g, '\\\\\\\\');
82+
section = section.replace(/\*\*/g, '{*,**/**/**}');
83+
const matcher = new Minimatch(`${pathPrefix}/${section}`, matchOptions);
84+
return matcher.match(filePath);
7185
}
7286

7387
function parseEditorConfigContent(content: string): Record<string, any> {
@@ -95,9 +109,9 @@ function parseEditorConfigContent(content: string): Record<string, any> {
95109
let value: any = values.join('=').trim();
96110

97111
// Convert boolean-like and numeric values.
98-
if (value.toLowerCase() === 'true') {
112+
if (value === 'true') {
99113
value = true;
100-
} else if (value.toLowerCase() === 'false') {
114+
} else if (value === 'false') {
101115
value = false;
102116
} else if (!isNaN(Number(value))) {
103117
value = Number(value);
@@ -123,6 +137,10 @@ function getEditorConfig(filePath: string): any {
123137
let currentDir: string = path.dirname(filePath);
124138
const rootDir: string = path.parse(currentDir).root;
125139

140+
if (isWindows) {
141+
filePath = filePath.replace(/\\/g, '/');
142+
}
143+
126144
// Traverse from the file's directory to the root directory.
127145
for (; ;) {
128146
const editorConfigPath: string = path.join(currentDir, '.editorconfig');
@@ -138,9 +156,14 @@ function getEditorConfig(filePath: string): any {
138156
};
139157
}
140158

159+
let currentDirForwardSlashes: string = currentDir;
160+
if (isWindows) {
161+
currentDirForwardSlashes = currentDir.replace(/\\/g, '/');
162+
}
163+
141164
// Match sections and combine configurations.
142165
Object.keys(configData).forEach((section: string) => {
143-
if (section !== '*' && matchesSection(filePath, section)) {
166+
if (section !== '*' && matchesSection(currentDirForwardSlashes, filePath, section)) {
144167
combinedConfig = {
145168
...combinedConfig,
146169
...configData[section]

Diff for: Extension/yarn.lock

+8-1
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@
448448
resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
449449
integrity sha1-B1CLRXl8uB7D8nMBGwVM0HVe3co=
450450

451-
"@types/minimatch@^3.0.3", "@types/minimatch@^3.0.5":
451+
"@types/minimatch@^3.0.3":
452452
version "3.0.5"
453453
resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
454454
integrity sha1-EAHMXmo3BLg8I2An538vWOoBD0A=
@@ -3278,6 +3278,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
32783278
dependencies:
32793279
brace-expansion "^1.1.7"
32803280

3281+
minimatch@^4.2.0:
3282+
version "4.2.3"
3283+
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.3.tgz#b4dcece1d674dee104bb0fb833ebb85a78cbbca6"
3284+
integrity sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==
3285+
dependencies:
3286+
brace-expansion "^1.1.7"
3287+
32813288
minimatch@^5.0.1, minimatch@^5.1.0, minimatch@^5.1.6:
32823289
version "5.1.6"
32833290
resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"

0 commit comments

Comments
 (0)