Skip to content

Commit 1d7c0c9

Browse files
authored
Try and deal with CodeQL reports on replace("*", ...) (#56607)
1 parent 993ffd7 commit 1d7c0c9

File tree

4 files changed

+20
-7
lines changed

4 files changed

+20
-7
lines changed

src/compiler/moduleNameResolver.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ import {
8989
removeExtension,
9090
removeFileExtension,
9191
removePrefix,
92+
replaceFirstStar,
9293
ResolutionMode,
9394
ResolvedModuleWithFailedLookupLocations,
9495
ResolvedProjectReference,
@@ -2286,8 +2287,8 @@ function loadEntrypointsFromExportMap(
22862287
/*excludes*/ undefined,
22872288
[
22882289
isDeclarationFileName(target)
2289-
? target.replace("*", "**/*")
2290-
: changeAnyExtension(target.replace("*", "**/*"), getDeclarationEmitExtensionForPath(target)),
2290+
? replaceFirstStar(target, "**/*")
2291+
: changeAnyExtension(replaceFirstStar(target, "**/*"), getDeclarationEmitExtensionForPath(target)),
22912292
],
22922293
).forEach(entry => {
22932294
entrypoints = appendIfUnique(entrypoints, {
@@ -3096,7 +3097,7 @@ function tryLoadModuleUsingPaths(extensions: Extensions, moduleName: string, bas
30963097
trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
30973098
}
30983099
const resolved = forEach(paths[matchedPatternText], subst => {
3099-
const path = matchedStar ? subst.replace("*", matchedStar) : subst;
3100+
const path = matchedStar ? replaceFirstStar(subst, matchedStar) : subst;
31003101
// When baseUrl is not specified, the command line parser resolves relative paths to the config file location.
31013102
const candidate = normalizePath(combinePaths(baseDirectory, path));
31023103
if (state.traceEnabled) {

src/compiler/moduleSpecifiers.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
removeFileExtension,
9494
removeSuffix,
9595
removeTrailingDirectorySeparator,
96+
replaceFirstStar,
9697
ResolutionMode,
9798
resolvePath,
9899
ScriptKind,
@@ -810,7 +811,7 @@ function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike<rea
810811
) {
811812
const matchedStar = value.substring(prefix.length, value.length - suffix.length);
812813
if (!pathIsRelative(matchedStar)) {
813-
return key.replace("*", matchedStar);
814+
return replaceFirstStar(key, matchedStar);
814815
}
815816
}
816817
}
@@ -864,11 +865,11 @@ function tryGetModuleNameFromExports(options: CompilerOptions, targetFilePath: s
864865
const trailingSlice = pathOrPattern.slice(starPos + 1);
865866
if (startsWith(targetFilePath, leadingSlice) && endsWith(targetFilePath, trailingSlice)) {
866867
const starReplacement = targetFilePath.slice(leadingSlice.length, targetFilePath.length - trailingSlice.length);
867-
return { moduleFileToTry: packageName.replace("*", starReplacement) };
868+
return { moduleFileToTry: replaceFirstStar(packageName, starReplacement) };
868869
}
869870
if (extensionSwappedTarget && startsWith(extensionSwappedTarget, leadingSlice) && endsWith(extensionSwappedTarget, trailingSlice)) {
870871
const starReplacement = extensionSwappedTarget.slice(leadingSlice.length, extensionSwappedTarget.length - trailingSlice.length);
871-
return { moduleFileToTry: packageName.replace("*", starReplacement) };
872+
return { moduleFileToTry: replaceFirstStar(packageName, starReplacement) };
872873
}
873874
break;
874875
}

src/compiler/utilities.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10505,3 +10505,14 @@ export function hasResolutionModeOverride(node: ImportTypeNode | ImportDeclarati
1050510505
}
1050610506
return !!getResolutionModeOverride(node.attributes);
1050710507
}
10508+
10509+
const stringReplace = String.prototype.replace;
10510+
10511+
/** @internal */
10512+
export function replaceFirstStar(s: string, replacement: string): string {
10513+
// `s.replace("*", replacement)` triggers CodeQL as they think it's a potentially incorrect string escaping.
10514+
// See: https://codeql.github.com/codeql-query-help/javascript/js-incomplete-sanitization/
10515+
// But, we really do want to replace only the first star.
10516+
// Attempt to defeat this analysis by indirectly calling the method.
10517+
return stringReplace.call(s, "*", replacement);
10518+
}

src/services/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3393,7 +3393,7 @@ export function quote(sourceFile: SourceFile, preferences: UserPreferences, text
33933393
// Editors can pass in undefined or empty string - we want to infer the preference in those cases.
33943394
const quotePreference = getQuotePreference(sourceFile, preferences);
33953395
const quoted = JSON.stringify(text);
3396-
return quotePreference === QuotePreference.Single ? `'${stripQuotes(quoted).replace(/'/g, "\\'").replace(/\\"/g, '"')}'` : quoted;
3396+
return quotePreference === QuotePreference.Single ? `'${stripQuotes(quoted).replace(/'/g, () => "\\'").replace(/\\"/g, '"')}'` : quoted;
33973397
}
33983398

33993399
/** @internal */

0 commit comments

Comments
 (0)