Allow plugins to be loaded from package subpaths (#57266)

Co-authored-by: Sheetal Nandi <sheetalkamat@users.noreply.github.com>
This commit is contained in:
Phil Pluckthun
2024-02-21 13:55:47 -08:00
committed by GitHub
co-authored by Sheetal Nandi
parent 1c0fd31223
commit ef091bf755
4 changed files with 122 additions and 6 deletions
+6 -2
View File
@@ -66,6 +66,7 @@ import {
IncompleteCompletionsCache,
IndentStyle,
isArray,
isExternalModuleNameRelative,
isIgnoredFileFromWildCardWatching,
isInsideNodeModules,
isJsonEqual,
@@ -90,7 +91,6 @@ import {
ParsedCommandLine,
parseJsonSourceFileConfigFileContent,
parseJsonText,
parsePackageName,
Path,
PerformanceEvent,
PluginImport,
@@ -4474,7 +4474,11 @@ export class ProjectService {
}
this.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`);
if (!pluginConfigEntry.name || parsePackageName(pluginConfigEntry.name).rest) {
if (
!pluginConfigEntry.name ||
isExternalModuleNameRelative(pluginConfigEntry.name) ||
/[\\/]\.\.?($|[\\/])/.test(pluginConfigEntry.name)
) {
this.logger.info(`Skipped loading plugin ${pluginConfigEntry.name || JSON.stringify(pluginConfigEntry)} because only package name is allowed plugin name`);
return;
}
+28 -4
View File
@@ -45,8 +45,20 @@ describe("unittests:: tsserver:: plugins:: loading", () => {
}
it("With local plugins", () => {
const expectedToLoad = ["@myscoped/plugin", "unscopedPlugin"];
const notToLoad = ["../myPlugin", "myPlugin/../malicious"];
const expectedToLoad = [
"@myscoped/plugin",
"@myscoped/plugin/subpath",
"@myscoped/plugin/sub/path",
"unscopedPlugin",
"unscopedPlugin/subpath",
"unscopedPlugin/sub/path",
];
const notToLoad = [
"../myPlugin",
"@myscoped/plugin/../malicious",
"myPlugin/../malicious",
"myPlugin/subpath/../../malicious",
];
const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` };
const tsconfig: File = {
path: "/tsconfig.json",
@@ -65,8 +77,20 @@ describe("unittests:: tsserver:: plugins:: loading", () => {
});
it("With global plugins", () => {
const expectedToLoad = ["@myscoped/plugin", "unscopedPlugin"];
const notToLoad = ["../myPlugin", "myPlugin/../malicious"];
const expectedToLoad = [
"@myscoped/plugin",
"@myscoped/plugin/subpath",
"@myscoped/plugin/sub/path",
"unscopedPlugin",
"unscopedPlugin/subpath",
"unscopedPlugin/sub/path",
];
const notToLoad = [
"../myPlugin",
"@myscoped/plugin/../malicious",
"myPlugin/../malicious",
"myPlugin/subpath/../../malicious",
];
const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` };
const tsconfig: File = {
path: "/tsconfig.json",