Skip to content

Commit 2ed6d85

Browse files
committed
fix: escape spaces in executable path
for #1, #15
1 parent 77a3554 commit 2ed6d85

File tree

9 files changed

+1875
-15
lines changed

9 files changed

+1875
-15
lines changed

.github/workflows/CI.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ jobs:
2525

2626
- name: check with prettier
2727
run: yarn prettier . --check
28+
29+
- name: test
30+
run: yarn test

__tests__/index.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import {escapeExecutablePath} from "../src/utils/escapePath"
2+
3+
describe("test path escape", () => {
4+
it("should escape Windows path with space", () => {
5+
const originalPath = "C:\\Program Files\\processing\\processing-java"
6+
7+
expect(escapeExecutablePath(originalPath)).toBe(
8+
"C:\\Program` Files\\processing\\processing-java",
9+
)
10+
})
11+
12+
it("should escape Unix path with space", () => {
13+
const originalPath = "/usr/bin/something else/processing-java"
14+
15+
expect(escapeExecutablePath(originalPath)).toBe(
16+
"/usr/bin/something\\ else/processing-java",
17+
)
18+
})
19+
20+
it("should leave Windows path without spaces as is", () => {
21+
const originalPath = ".\\processing\\processing-java"
22+
23+
expect(escapeExecutablePath(originalPath)).toBe(".\\processing\\processing-java")
24+
})
25+
26+
it("should leave Unix path without spaces as is", () => {
27+
const originalPath = "/usr/bin/processing-java"
28+
29+
expect(escapeExecutablePath(originalPath)).toBe("/usr/bin/processing-java")
30+
})
31+
32+
it("should not escape already escaped spaces on Windows", () => {
33+
const originalPath = "C:\\Program` Files\\processing\\processing java"
34+
35+
expect(escapeExecutablePath(originalPath)).toBe(
36+
"C:\\Program` Files\\processing\\processing` java",
37+
)
38+
})
39+
40+
it("should not escape already escaped spaces on Unix", () => {
41+
const originalPath = "/usr/bin/something else/processing\\ java"
42+
43+
expect(escapeExecutablePath(originalPath)).toBe(
44+
"/usr/bin/something\\ else/processing\\ java",
45+
)
46+
})
47+
48+
it("should detect platform if no path seperators available", () => {
49+
const originalPath = "processing java"
50+
51+
if (process.platform === "win32") {
52+
expect(escapeExecutablePath(originalPath)).toBe("processing` java")
53+
} else {
54+
expect(escapeExecutablePath(originalPath)).toBe("processing\\ java")
55+
}
56+
})
57+
58+
it("should leave single path as is", () => {
59+
const originalPath = "processing-java"
60+
61+
expect(escapeExecutablePath(originalPath)).toBe("processing-java")
62+
})
63+
})

__tests__/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"type": "module"
3+
}

jest.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* @type {import("ts-jest/dist/types").InitialOptionsTsJest}
3+
*/
4+
module.exports = {
5+
preset: "ts-jest",
6+
testEnvironment: "node",
7+
}

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"vscode": "^1.48.0"
1616
},
1717
"scripts": {
18+
"test": "node --experimental-vm-modules --experimental-specifier-resolution=node node_modules/.bin/jest",
1819
"build": "rollup -c rollup.config.js",
1920
"deploy": "vsce publish",
2021
"format": "prettier . --write && eslint --ext ts --fix --cache",
@@ -35,6 +36,7 @@
3536
"@rollup/plugin-node-resolve": "^13.0.0",
3637
"@rollup/plugin-typescript": "^8.2.1",
3738
"@types/glob": "^7.1.4",
39+
"@types/jest": "^27.0.3",
3840
"@types/jsdom": "^16.2.13",
3941
"@types/node": "^16.3.1",
4042
"@types/node-fetch": "^2.5.11",
@@ -44,6 +46,7 @@
4446
"eslint": "^7.30.0",
4547
"eslint-plugin-prefer-arrow": "^1.2.3",
4648
"glob": "^7.1.7",
49+
"jest": "^27.4.5",
4750
"jsdom": "^16.6.0",
4851
"node-fetch": "^2.6.1",
4952
"prettier": "^2.3.2",
@@ -52,6 +55,7 @@
5255
"rollup": "^2.53.0",
5356
"rollup-plugin-progress": "^1.1.2",
5457
"rollup-plugin-terser": "^7.0.2",
58+
"ts-jest": "^27.1.2",
5559
"tslib": "^2.3.0",
5660
"typescript": "~4.3.5",
5761
"vsce": "^1.95.1",

src/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import vscode from "vscode"
8+
import {escapeExecutablePath} from "./utils"
89

910
const getProcessingCommand = (): string => {
1011
// Look for processing.processingPath, then processing.path, then default to processing-java
@@ -23,7 +24,7 @@ const getProcessingCommand = (): string => {
2324
return "processing-java"
2425
}
2526

26-
return config
27+
return escapeExecutablePath(config)
2728
}
2829

2930
const getJavaCommand = (): string => {

src/utils/escapePath.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Processing-vscode - Processing Language Support for VSCode
3+
*
4+
* @copyright (C) 2021 Luke Zhang
5+
*/
6+
7+
export const escapeExecutablePath = (pathName: string): string => {
8+
if (!/ /gu.test(pathName)) {
9+
return pathName
10+
}
11+
12+
let isWindowsPath = /[a-zA-Z]:[\\\/](?:[a-zA-Z0-9]+[\\\/])*([a-zA-Z0-9]+)/gu.test(pathName)
13+
14+
if (!/[\\/]/gu.test(pathName)) {
15+
isWindowsPath = process.platform === "win32"
16+
}
17+
18+
if (isWindowsPath) {
19+
// Windows path
20+
return pathName.replace(/(?<!`) /gu, "` ")
21+
}
22+
23+
return pathName.replace(/(?<!\\) /gu, "\\ ")
24+
}

src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
export * as search from "./search"
8+
export {escapeExecutablePath} from "./escapePath"
89

910
export const isValidProcessingProject = (path?: string): boolean =>
1011
path !== undefined && /^[/_$a-z][/\w$]*$/iu.test(path)

0 commit comments

Comments
 (0)