Repository navigation
Expand file tree
/
Copy pathExec.ts
More file actions
71 lines (63 loc) · 2.5 KB
/
Copy pathExec.ts
File metadata and controls
71 lines (63 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { exec } from "child_process";
import { promisify } from "util";
import type { PHPContext } from "../PHPContext.js";
import type { PHPEngine } from "../PHPEngine.js";
import { PHPVariable, PHPReference } from "./PHPVariable.js";
import { defineFunction } from "./Reflection.js";
const execAsync = promisify(exec);
export class ExecRuntime {
/**
* Execute an external program.
* @param outputArray Output variable passed by reference to receive output lines.
* @param returnVarObj Output variable passed by reference to receive exit status code.
*/
public static async exec(ctx: PHPContext, commandArg?: PHPReference, outputArray?: PHPReference, returnVarObj?: PHPReference): Promise<string> {
const command = String(await commandArg?.get() ?? "");
try {
const { stdout } = await execAsync(command, { cwd: ctx.cwd });
const lines = stdout.trimEnd().split(/\r?\n/);
if (outputArray && typeof outputArray.set === "function") {
await outputArray.set(lines);
}
if (returnVarObj && typeof returnVarObj.set === "function") {
await returnVarObj.set(0);
}
return lines[lines.length - 1] || "";
} catch (err: any) {
if (returnVarObj && typeof returnVarObj.set === "function") {
await returnVarObj.set(err.status || 1);
}
return "";
}
}
public static async shell_exec(ctx: PHPContext, commandArg?: PHPReference): Promise<string | null> {
const command = String(await commandArg?.get() ?? "");
try {
const { stdout } = await execAsync(command, { cwd: ctx.cwd });
return stdout;
} catch {
return null;
}
}
public static async escapeshellarg(ctx: PHPContext, argParam?: PHPReference): Promise<string> {
const arg = String(await argParam?.get() ?? "");
return `'${arg.replace(/'/g, "'\\''")}'`;
}
public static async escapeshellcmd(ctx: PHPContext, cmdParam?: PHPReference): Promise<string> {
const cmd = String(await cmdParam?.get() ?? "");
return cmd.replace(/([#&;`|*?~<>^()\[\]{}$\\\x0A\xFF])/g, "\\$1");
}
static functions = {
"exec": ExecRuntime.exec,
"shell_exec": ExecRuntime.shell_exec,
"escapeshellarg": ExecRuntime.escapeshellarg,
"escapeshellcmd": ExecRuntime.escapeshellcmd,
};
public static register(engine: PHPEngine): void {
engine.registerFunctions(ExecRuntime.functions);
}
}
defineFunction(ExecRuntime.exec, {
name: "exec",
parameters: [{ name: "command" }, { name: "output", byref: true }, { name: "result_code", byref: true }],
});