diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 38e26461ee8..51c68c631ef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,13 @@ -# Note +# Notes on Contributing 🚨 **Important** 🚨: All code changes should be submitted to the https://github.com/microsoft/typescript-go repo. Development in this codebase [is winding down](https://devblogs.microsoft.com/typescript/progress-on-typescript-7-december-2025/#typescript-6.0-is-the-last-javascript-based-release) and PRs will only be merged if they fix **critical** 6.0 issues (at minimum, any bug that existed in 5.9 is not critical unless it's a security issue). +## Use of AI Assistance + +It is acceptable to use AI tools to assist in developing PRs. However, we ask that you disclose this in the PR description. If your PR appears AI-authored and you do not include this disclosure, your PR will be closed without review. Repeated violation of this will be considered disruptive conduct, which may result in being blocked from interaction with the organization. + # Instructions for Logging Issues ## 1. Read the FAQ diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index a573536255a..db699d5b32c 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -327,7 +327,8 @@ export const enum NameValidationResult { NameTooLong, NameStartsWithDot, NameStartsWithUnderscore, - NameContainsNonURISafeCharacters, + NameContainsInvalidCharacters, + NameContainsNonURISafeCharacters = NameContainsInvalidCharacters, // for backward compatibility } const maxPackageNameLength = 214; @@ -381,8 +382,8 @@ function validatePackageNameWorker(packageName: string, supportScopedPackage: bo return NameValidationResult.Ok; } } - if (encodeURIComponent(packageName) !== packageName) { - return NameValidationResult.NameContainsNonURISafeCharacters; + if (!/^[\w.-]+$/.test(packageName)) { + return NameValidationResult.NameContainsInvalidCharacters; } return NameValidationResult.Ok; } @@ -405,8 +406,8 @@ function renderPackageNameValidationFailureWorker(typing: string, result: NameVa return `'${typing}':: ${kind} name '${name}' cannot start with '.'`; case NameValidationResult.NameStartsWithUnderscore: return `'${typing}':: ${kind} name '${name}' cannot start with '_'`; - case NameValidationResult.NameContainsNonURISafeCharacters: - return `'${typing}':: ${kind} name '${name}' contains non URI safe characters`; + case NameValidationResult.NameContainsInvalidCharacters: + return `'${typing}':: ${kind} name '${name}' contains invalid characters`; case NameValidationResult.Ok: return Debug.fail(); // Shouldn't have called this. default: diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 43ff5837a95..ced21a6d72a 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -400,8 +400,8 @@ interface String { charAt(pos: number): string; /** - * Returns the Unicode value of the character at the specified location. - * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned. + * Returns the Unicode value of the character at the specified location, or NaN if the index is out of bounds. + * @param index The zero-based index of the desired character. */ charCodeAt(index: number): number; diff --git a/src/testRunner/unittests/tsserver/codeFix.ts b/src/testRunner/unittests/tsserver/codeFix.ts index 481441b7cd1..007d835ca48 100644 --- a/src/testRunner/unittests/tsserver/codeFix.ts +++ b/src/testRunner/unittests/tsserver/codeFix.ts @@ -56,4 +56,24 @@ describe("unittests:: tsserver:: codeFix::", () => { }); baselineTsserverLogs("codeFix", "install package when serialized", session); }); + + it("install package rejects invalid package names", () => { + const { host, session } = setup(); + // A client could craft an applyCodeActionCommand with arbitrary package names. + // The server must validate and reject names with invalid characters to prevent shell injection. + for (const packageName of ["; echo 'hello' #", "react'test", "a/b/c"]) { + session.executeCommandSeq({ + command: ts.server.protocol.CommandTypes.ApplyCodeActionCommand, + arguments: { + command: { + type: "install package", + file: "/home/src/projects/project/src/file.ts", + packageName, + }, + }, + }); + } + host.runPendingInstalls(); + baselineTsserverLogs("codeFix", "install package rejects invalid package names", session); + }); }); diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index 1c7e77ae403..a832f3f2fcf 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -1524,10 +1524,11 @@ describe("unittests:: tsserver:: typingsInstaller:: Validate package name:", () it("package name cannot start with underscore", () => { assert.equal(validatePackageName("_foo"), NameValidationResult.NameStartsWithUnderscore); }); - it("package non URI safe characters are not supported", () => { - assert.equal(validatePackageName(" scope "), NameValidationResult.NameContainsNonURISafeCharacters); - assert.equal(validatePackageName("; say ‘Hello from TypeScript!’ #"), NameValidationResult.NameContainsNonURISafeCharacters); - assert.equal(validatePackageName("a/b/c"), NameValidationResult.NameContainsNonURISafeCharacters); + it("package invalid characters are not supported", () => { + assert.equal(validatePackageName(" scope "), NameValidationResult.NameContainsInvalidCharacters); + assert.equal(validatePackageName("; say ‘Hello from TypeScript!’ #"), NameValidationResult.NameContainsInvalidCharacters); + assert.equal(validatePackageName("a/b/c"), NameValidationResult.NameContainsInvalidCharacters); + assert.equal(validatePackageName("react'test"), NameValidationResult.NameContainsInvalidCharacters); }); it("scoped package name is supported", () => { assert.equal(validatePackageName("@scope/bar"), NameValidationResult.Ok); @@ -1540,10 +1541,10 @@ describe("unittests:: tsserver:: typingsInstaller:: Validate package name:", () assert.deepEqual(validatePackageName("@_scope/bar"), { name: "_scope", isScopeName: true, result: NameValidationResult.NameStartsWithUnderscore }); assert.deepEqual(validatePackageName("@_scope/_bar"), { name: "_scope", isScopeName: true, result: NameValidationResult.NameStartsWithUnderscore }); }); - it("scope name in scoped package name with non URI safe characters are not supported", () => { - assert.deepEqual(validatePackageName("@ scope /bar"), { name: " scope ", isScopeName: true, result: NameValidationResult.NameContainsNonURISafeCharacters }); - assert.deepEqual(validatePackageName("@; say ‘Hello from TypeScript!’ #/bar"), { name: "; say ‘Hello from TypeScript!’ #", isScopeName: true, result: NameValidationResult.NameContainsNonURISafeCharacters }); - assert.deepEqual(validatePackageName("@ scope / bar "), { name: " scope ", isScopeName: true, result: NameValidationResult.NameContainsNonURISafeCharacters }); + it("scope name in scoped package name with invalid characters are not supported", () => { + assert.deepEqual(validatePackageName("@ scope /bar"), { name: " scope ", isScopeName: true, result: NameValidationResult.NameContainsInvalidCharacters }); + assert.deepEqual(validatePackageName("@; say ‘Hello from TypeScript!’ #/bar"), { name: "; say ‘Hello from TypeScript!’ #", isScopeName: true, result: NameValidationResult.NameContainsInvalidCharacters }); + assert.deepEqual(validatePackageName("@ scope / bar "), { name: " scope ", isScopeName: true, result: NameValidationResult.NameContainsInvalidCharacters }); }); it("package name in scoped package name cannot start with dot", () => { assert.deepEqual(validatePackageName("@scope/.bar"), { name: ".bar", isScopeName: false, result: NameValidationResult.NameStartsWithDot }); @@ -1551,9 +1552,9 @@ describe("unittests:: tsserver:: typingsInstaller:: Validate package name:", () it("package name in scoped package name cannot start with underscore", () => { assert.deepEqual(validatePackageName("@scope/_bar"), { name: "_bar", isScopeName: false, result: NameValidationResult.NameStartsWithUnderscore }); }); - it("package name in scoped package name with non URI safe characters are not supported", () => { - assert.deepEqual(validatePackageName("@scope/ bar "), { name: " bar ", isScopeName: false, result: NameValidationResult.NameContainsNonURISafeCharacters }); - assert.deepEqual(validatePackageName("@scope/; say ‘Hello from TypeScript!’ #"), { name: "; say ‘Hello from TypeScript!’ #", isScopeName: false, result: NameValidationResult.NameContainsNonURISafeCharacters }); + it("package name in scoped package name with invalid characters are not supported", () => { + assert.deepEqual(validatePackageName("@scope/ bar "), { name: " bar ", isScopeName: false, result: NameValidationResult.NameContainsInvalidCharacters }); + assert.deepEqual(validatePackageName("@scope/; say ‘Hello from TypeScript!’ #"), { name: "; say ‘Hello from TypeScript!’ #", isScopeName: false, result: NameValidationResult.NameContainsInvalidCharacters }); }); }); diff --git a/src/typingsInstallerCore/typingsInstaller.ts b/src/typingsInstallerCore/typingsInstaller.ts index 25f583513a5..aaafeaa4774 100644 --- a/src/typingsInstallerCore/typingsInstaller.ts +++ b/src/typingsInstallerCore/typingsInstaller.ts @@ -239,6 +239,22 @@ export abstract class TypingsInstaller { /** @internal */ installPackage(req: InstallPackageRequest): void { const { fileName, packageName, projectName, projectRootPath, id } = req; + const validationResult = JsTyping.validatePackageName(packageName); + if (validationResult !== JsTyping.NameValidationResult.Ok) { + const message = JsTyping.renderPackageNameValidationFailure(validationResult, packageName); + if (this.log.isEnabled()) { + this.log.writeLine(message); + } + const response: PackageInstalledResponse = { + kind: ActionPackageInstalled, + projectName, + id, + success: false, + message, + }; + this.sendResponse(response); + return; + } const cwd = forEachAncestorDirectory(getDirectoryPath(fileName), directory => { if (this.installTypingHost.fileExists(combinePaths(directory, "package.json"))) { return directory; diff --git a/tests/baselines/reference/completionsStringMethods.baseline b/tests/baselines/reference/completionsStringMethods.baseline index e7e9cf31bfb..a5a65ab5022 100644 --- a/tests/baselines/reference/completionsStringMethods.baseline +++ b/tests/baselines/reference/completionsStringMethods.baseline @@ -209,7 +209,7 @@ ], "documentation": [ { - "text": "Returns the Unicode value of the character at the specified location.", + "text": "Returns the Unicode value of the character at the specified location, or NaN if the index is out of bounds.", "kind": "text" } ], @@ -226,7 +226,7 @@ "kind": "space" }, { - "text": "The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.", + "text": "The zero-based index of the desired character.", "kind": "text" } ] diff --git a/tests/baselines/reference/tsserver/codeFix/install-package-rejects-invalid-package-names.js b/tests/baselines/reference/tsserver/codeFix/install-package-rejects-invalid-package-names.js new file mode 100644 index 00000000000..14acc9d58c6 --- /dev/null +++ b/tests/baselines/reference/tsserver/codeFix/install-package-rejects-invalid-package-names.js @@ -0,0 +1,438 @@ +Info seq [hh:mm:ss:mss] currentDirectory:: /home/src/Vscode/Projects/bin useCaseSensitiveFileNames:: false +Info seq [hh:mm:ss:mss] libs Location:: /home/src/tslibs/TS/Lib +Info seq [hh:mm:ss:mss] globalTypingsCacheLocation:: /home/src/Library/Caches/typescript +Info seq [hh:mm:ss:mss] Provided types map file "/home/src/tslibs/TS/Lib/typesMap.json" doesn't exist +Before request +//// [/home/src/projects/project/src/file.ts] +import * as os from "os"; +import * as https from "https"; +import * as vscode from "vscode"; + + +//// [/home/src/projects/project/tsconfig.json] +{ } + +//// [/home/src/projects/project/node_modules/vscode/index.js] +export const x = 10; + +//// [/home/src/tslibs/TS/Lib/lib.d.ts] +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + + +Info seq [hh:mm:ss:mss] request: + { + "command": "open", + "arguments": { + "file": "/home/src/projects/project/src/file.ts" + }, + "seq": 1, + "type": "request" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /home/src/projects/project/src/file.ts ProjectRootPath: undefined:: Result: /home/src/projects/project/tsconfig.json +Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /home/src/projects/project/tsconfig.json, currentDirectory: /home/src/projects/project +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/projects/project/tsconfig.json 2000 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] Config: /home/src/projects/project/tsconfig.json : { + "rootNames": [ + "/home/src/projects/project/src/file.ts" + ], + "options": { + "configFilePath": "/home/src/projects/project/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/home/src/projects/project/tsconfig.json", + "reason": "Creating possible configured project for /home/src/projects/project/src/file.ts to open" + } + } +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project 1 undefined Config: /home/src/projects/project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project 1 undefined Config: /home/src/projects/project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /home/src/projects/project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.es2025.full.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/src 1 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/src 1 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects 0 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects 0 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/node_modules 1 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/node_modules 1 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project 0 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project 0 undefined Project: /home/src/projects/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /home/src/projects/project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/home/src/projects/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + /home/src/tslibs/TS/Lib/lib.es2025.full.d.ts Text-1 "interface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };" + /home/src/projects/project/src/file.ts SVC-1-0 "import * as os from \"os\";\nimport * as https from \"https\";\nimport * as vscode from \"vscode\";\n" + + + ../../tslibs/TS/Lib/lib.es2025.full.d.ts + Default library for target 'es2025' + src/file.ts + Matched by default include pattern '**/*' + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/home/src/projects/project/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "telemetry", + "body": { + "telemetryEventName": "projectInfo", + "payload": { + "projectId": "1097a5f82e8323ba7aba7567ec06402f7ad4ea74abce44ec5efd223ac77ff169", + "fileStats": { + "js": 0, + "jsSize": 0, + "jsx": 0, + "jsxSize": 0, + "ts": 1, + "tsSize": 92, + "tsx": 0, + "tsxSize": 0, + "dts": 1, + "dtsSize": 374, + "deferred": 0, + "deferredSize": 0 + }, + "compilerOptions": {}, + "typeAcquisition": { + "enable": false, + "include": false, + "exclude": false + }, + "extends": false, + "files": false, + "include": false, + "exclude": false, + "compileOnSave": false, + "configFileName": "tsconfig.json", + "projectType": "configured", + "languageServiceEnabled": true, + "version": "FakeVersion" + } + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/home/src/projects/project/src/file.ts", + "configFile": "/home/src/projects/project/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/home/src/projects/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /home/src/projects/project/src/file.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /home/src/projects/project/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 1, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After request +//// [/home/src/tslibs/TS/Lib/lib.es2025.full.d.ts] *Lib* + + +PolledWatches:: +/home/src/projects/node_modules: *new* + {"pollingInterval":500} + +FsWatches:: +/home/src/projects: *new* + {} +/home/src/projects/project: *new* + {} +/home/src/projects/project/tsconfig.json: *new* + {} +/home/src/tslibs/TS/Lib/lib.es2025.full.d.ts: *new* + {} + +FsWatchesRecursive:: +/home/src/projects/project: *new* + {} +/home/src/projects/project/node_modules: *new* + {} +/home/src/projects/project/src: *new* + {} + +Projects:: +/home/src/projects/project/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/projects/project/src/file.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /home/src/projects/project/tsconfig.json *default* +/home/src/tslibs/TS/Lib/lib.es2025.full.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/projects/project/tsconfig.json + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "getCombinedCodeFix", + "arguments": { + "scope": { + "type": "file", + "args": { + "file": "/home/src/projects/project/src/file.ts" + } + }, + "fixId": "installTypesPackage" + }, + "seq": 2, + "type": "request" + } +TI:: Creating typing installer + +TI:: [hh:mm:ss:mss] Global cache location '/home/src/Library/Caches/typescript', safe file path '/home/src/tslibs/TS/Lib/typingSafeList.json', types map path /home/src/tslibs/TS/Lib/typesMap.json +TI:: [hh:mm:ss:mss] Processing cache location '/home/src/Library/Caches/typescript' +TI:: [hh:mm:ss:mss] Trying to find '/home/src/Library/Caches/typescript/package.json'... +TI:: [hh:mm:ss:mss] Finished processing cache location '/home/src/Library/Caches/typescript' +TI:: [hh:mm:ss:mss] Npm config file: /home/src/Library/Caches/typescript/package.json +TI:: [hh:mm:ss:mss] Npm config file: '/home/src/Library/Caches/typescript/package.json' is missing, creating new one... +TI:: [hh:mm:ss:mss] Updating types-registry npm package... +TI:: [hh:mm:ss:mss] npm install --ignore-scripts types-registry@latest +TI:: [hh:mm:ss:mss] Updated types-registry npm package +TI:: typing installer creation complete +//// [/home/src/Library/Caches/typescript/package.json] +{ "private": true } + +//// [/home/src/Library/Caches/typescript/node_modules/types-registry/index.json] +{ + "entries": { + "vscode": { + "latest": "1.3.0", + "ts2.0": "1.0.0", + "ts2.1": "1.0.0", + "ts2.2": "1.2.0", + "ts2.3": "1.3.0", + "ts2.4": "1.3.0", + "ts2.5": "1.3.0", + "ts2.6": "1.3.0", + "ts2.7": "1.3.0" + } + } +} + + +TI:: [hh:mm:ss:mss] Sending response: + { + "kind": "event::typesRegistry", + "typesRegistry": { + "vscode": { + "latest": "1.3.0", + "ts2.0": "1.0.0", + "ts2.1": "1.0.0", + "ts2.2": "1.2.0", + "ts2.3": "1.3.0", + "ts2.4": "1.3.0", + "ts2.5": "1.3.0", + "ts2.6": "1.3.0", + "ts2.7": "1.3.0" + } + } + } +Info seq [hh:mm:ss:mss] response: + { + "response": { + "changes": [], + "commands": [ + { + "type": "install package", + "file": "/home/src/projects/project/src/file.ts", + "packageName": "@types/node" + }, + { + "type": "install package", + "file": "/home/src/projects/project/src/file.ts", + "packageName": "@types/node" + }, + { + "type": "install package", + "file": "/home/src/projects/project/src/file.ts", + "packageName": "@types/vscode" + } + ] + }, + "responseRequired": true + } +After request + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "applyCodeActionCommand", + "arguments": { + "command": { + "type": "install package", + "file": "/home/src/projects/project/src/file.ts", + "packageName": "; echo 'hello' #" + } + }, + "seq": 3, + "type": "request" + } +TI:: [hh:mm:ss:mss] '; echo 'hello' #':: Package name '; echo 'hello' #' contains invalid characters +TI:: [hh:mm:ss:mss] Sending response: + { + "kind": "action::packageInstalled", + "projectName": "/home/src/projects/project/tsconfig.json", + "id": 1, + "success": false, + "message": "'; echo 'hello' #':: Package name '; echo 'hello' #' contains invalid characters" + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "setTypings", + "body": { + "kind": "action::packageInstalled", + "projectName": "/home/src/projects/project/tsconfig.json", + "id": 1, + "success": false, + "message": "'; echo 'hello' #':: Package name '; echo 'hello' #' contains invalid characters" + } + } +Info seq [hh:mm:ss:mss] response: + { + "response": {}, + "responseRequired": true + } +After request + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "applyCodeActionCommand", + "arguments": { + "command": { + "type": "install package", + "file": "/home/src/projects/project/src/file.ts", + "packageName": "react'test" + } + }, + "seq": 4, + "type": "request" + } +TI:: [hh:mm:ss:mss] 'react'test':: Package name 'react'test' contains invalid characters +TI:: [hh:mm:ss:mss] Sending response: + { + "kind": "action::packageInstalled", + "projectName": "/home/src/projects/project/tsconfig.json", + "id": 2, + "success": false, + "message": "'react'test':: Package name 'react'test' contains invalid characters" + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "setTypings", + "body": { + "kind": "action::packageInstalled", + "projectName": "/home/src/projects/project/tsconfig.json", + "id": 2, + "success": false, + "message": "'react'test':: Package name 'react'test' contains invalid characters" + } + } +Info seq [hh:mm:ss:mss] response: + { + "response": {}, + "responseRequired": true + } +After request + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "applyCodeActionCommand", + "arguments": { + "command": { + "type": "install package", + "file": "/home/src/projects/project/src/file.ts", + "packageName": "a/b/c" + } + }, + "seq": 5, + "type": "request" + } +TI:: [hh:mm:ss:mss] 'a/b/c':: Package name 'a/b/c' contains invalid characters +TI:: [hh:mm:ss:mss] Sending response: + { + "kind": "action::packageInstalled", + "projectName": "/home/src/projects/project/tsconfig.json", + "id": 3, + "success": false, + "message": "'a/b/c':: Package name 'a/b/c' contains invalid characters" + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "setTypings", + "body": { + "kind": "action::packageInstalled", + "projectName": "/home/src/projects/project/tsconfig.json", + "id": 3, + "success": false, + "message": "'a/b/c':: Package name 'a/b/c' contains invalid characters" + } + } +Info seq [hh:mm:ss:mss] response: + { + "response": {}, + "responseRequired": true + } +After request + +Before running PendingInstalls callback:: count: 0 + +After running PendingInstalls callback:: count: 0 diff --git a/tests/baselines/reference/tsserver/typingsInstaller/malformed-packagejson.js b/tests/baselines/reference/tsserver/typingsInstaller/malformed-packagejson.js index b32a3c36b76..27c9be5bd0c 100644 --- a/tests/baselines/reference/tsserver/typingsInstaller/malformed-packagejson.js +++ b/tests/baselines/reference/tsserver/typingsInstaller/malformed-packagejson.js @@ -200,7 +200,7 @@ Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/projects/pro Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer TI:: [hh:mm:ss:mss] Installing typings ["co } }"] -TI:: [hh:mm:ss:mss] 'co } }':: Package name 'co } }' contains non URI safe characters +TI:: [hh:mm:ss:mss] 'co } }':: Package name 'co } }' contains invalid characters TI:: [hh:mm:ss:mss] All typings are known to be missing or invalid - no need to install more typings TI:: [hh:mm:ss:mss] Sending response: { diff --git a/tests/baselines/reference/tsserver/typingsInstaller/should-handle-node-core-modules.js b/tests/baselines/reference/tsserver/typingsInstaller/should-handle-node-core-modules.js index 3bc84f2df7c..29afbcf6922 100644 --- a/tests/baselines/reference/tsserver/typingsInstaller/should-handle-node-core-modules.js +++ b/tests/baselines/reference/tsserver/typingsInstaller/should-handle-node-core-modules.js @@ -654,7 +654,7 @@ TI:: [hh:mm:ss:mss] Sending response: "projectName": "/dev/null/inferredProject1*" } TI:: [hh:mm:ss:mss] Installing typings ["s tream"] -TI:: [hh:mm:ss:mss] 's tream':: Package name 's tream' contains non URI safe characters +TI:: [hh:mm:ss:mss] 's tream':: Package name 's tream' contains invalid characters TI:: [hh:mm:ss:mss] All typings are known to be missing or invalid - no need to install more typings TI:: [hh:mm:ss:mss] Sending response: { diff --git a/tests/baselines/reference/tsserver/typingsInstaller/should-not-initialize-invaalid-package-names.js b/tests/baselines/reference/tsserver/typingsInstaller/should-not-initialize-invaalid-package-names.js index 499d7ad5544..d29fb6696c6 100644 --- a/tests/baselines/reference/tsserver/typingsInstaller/should-not-initialize-invaalid-package-names.js +++ b/tests/baselines/reference/tsserver/typingsInstaller/should-not-initialize-invaalid-package-names.js @@ -160,7 +160,7 @@ Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/projects/pro Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer TI:: [hh:mm:ss:mss] Installing typings ["; say ‘Hello from TypeScript!’ #"] -TI:: [hh:mm:ss:mss] '; say ‘Hello from TypeScript!’ #':: Package name '; say ‘Hello from TypeScript!’ #' contains non URI safe characters +TI:: [hh:mm:ss:mss] '; say ‘Hello from TypeScript!’ #':: Package name '; say ‘Hello from TypeScript!’ #' contains invalid characters TI:: [hh:mm:ss:mss] All typings are known to be missing or invalid - no need to install more typings TI:: [hh:mm:ss:mss] Sending response: {