Fix configuration path regex escaping (#14674)
This commit is contained in:
@@ -14,6 +14,7 @@ import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as which from 'which';
|
||||
import { logAndReturn, returns } from '../Utility/Async/returns';
|
||||
import { escapePathForSquiggles } from '../Utility/Text/escape';
|
||||
import * as util from '../common';
|
||||
import { isWindows } from '../constants';
|
||||
import { getOutputChannelLogger } from '../logger';
|
||||
@@ -2119,10 +2120,8 @@ export class CppProperties {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Escape the path string for literal use in a regular expression
|
||||
// Need to escape any quotes to match the original text
|
||||
let escapedPath: string = curPath.replace(/"/g, '\\"');
|
||||
escapedPath = escapedPath.replace(/[-\"\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
// Escape the parsed path for a literal regex match against its JSON spelling.
|
||||
const escapedPath: string = escapePathForSquiggles(curPath);
|
||||
|
||||
// Create a pattern to search for the path with either a quote or semicolon immediately before and after,
|
||||
// and extend that pattern to the next quote before and next quote after it.
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All Rights Reserved.
|
||||
* See 'LICENSE' in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
export function escapePathForSquiggles(s: string): string {
|
||||
return s.replace(/[-"\/\\^$*+?.()|[\]{}]/g, (character: string): string =>
|
||||
character === '"' ? '\\\\"' : `\\${character}`);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All Rights Reserved.
|
||||
* See 'LICENSE' in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import { describe, it } from 'mocha';
|
||||
import { doesNotMatch, match, strictEqual } from 'node:assert';
|
||||
import { escapePathForSquiggles } from '../../src/Utility/Text/escape';
|
||||
|
||||
describe('Text escaping', () => {
|
||||
it('escapes paths for matching their JSON spelling', () => {
|
||||
strictEqual(escapePathForSquiggles('"'), '\\\\"');
|
||||
strictEqual(escapePathForSquiggles('\\'), '\\\\');
|
||||
strictEqual(escapePathForSquiggles('.*'), '\\.\\*');
|
||||
|
||||
const parsedPath: string = String.raw`C:\src"quoted"`;
|
||||
const sourcePath: string = String.raw`C:\src\"quoted\"`;
|
||||
const pattern: RegExp = new RegExp(`^${escapePathForSquiggles(parsedPath)}$`);
|
||||
match(sourcePath, pattern);
|
||||
doesNotMatch(parsedPath, pattern);
|
||||
});
|
||||
|
||||
it('handles repeated backslashes and regex metacharacters', () => {
|
||||
const parsedPath: string = String.raw`C:\\sdk\\[headers]+(x)?.h\\say"hello"and"goodbye`;
|
||||
const sourcePath: string = String.raw`C:\\sdk\\[headers]+(x)?.h\\say\"hello\"and\"goodbye`;
|
||||
const pattern: RegExp = new RegExp(`^${escapePathForSquiggles(parsedPath)}$`);
|
||||
|
||||
match(sourcePath, pattern);
|
||||
doesNotMatch(String.raw`C:\sdk\[headers]+(x)?.h\say\"hello\"and\"goodbye`, pattern);
|
||||
doesNotMatch(String.raw`C:\\sdk\\headers+(x)?.h\\say\"hello\"and\"goodbye`, pattern);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user