diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-01-17 02:11:31 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-01-17 02:11:31 +0900 |
| commit | deacd0dfc195bca41af631114804d29937337cd8 (patch) | |
| tree | f1f83580e5bc892c0794ac41632bc0cce3498f65 /services/sandbox-exec/lib/exec_standalone.js | |
| parent | 38ddeb28ec846ee966d0fe6873585d697a9ef373 (diff) | |
| download | phperkaigi-2024-albatross-deacd0dfc195bca41af631114804d29937337cd8.tar.gz phperkaigi-2024-albatross-deacd0dfc195bca41af631114804d29937337cd8.tar.zst phperkaigi-2024-albatross-deacd0dfc195bca41af631114804d29937337cd8.zip | |
.
Diffstat (limited to 'services/sandbox-exec/lib/exec_standalone.js')
| -rw-r--r-- | services/sandbox-exec/lib/exec_standalone.js | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/services/sandbox-exec/lib/exec_standalone.js b/services/sandbox-exec/lib/exec_standalone.js new file mode 100644 index 0000000..3b34adb --- /dev/null +++ b/services/sandbox-exec/lib/exec_standalone.js @@ -0,0 +1,67 @@ +import { readFileSync } from 'node:fs'; +import PHPWasm from './php-wasm.js' + +const userCode = ` +while ($l = fgets(STDIN)) { + echo $l, PHP_EOL; +} +`; + +const PRELUDE = ` +define('STDIN', fopen('php://stdin', 'r')); +define('STDOUT', fopen('php://stdout', 'r')); +define('STDERR', fopen('php://stderr', 'r')); + +`; +const BUFFER_MAX = 1024 * 1024 * 1; + +let stdinPos = 0; // bytewise +let stdinBuf = Buffer.from(readFileSync('/dev/stdin')); +let stdoutPos = 0; // bytewise +let stdoutBuf = Buffer.alloc(BUFFER_MAX); +let stderrPos = 0; // bytewise +let stderrBuf = Buffer.alloc(BUFFER_MAX); + +const { ccall } = await PHPWasm({ + stdin: () => { + if (stdinBuf.length <= stdinPos) { + return null; + } + return stdinBuf.readUInt8(stdinPos++); + }, + stdout: (asciiCode) => { + if (asciiCode === null) { + return; // flush + } + if (BUFFER_MAX <= stdoutPos) { + return; // ignore + } + if (asciiCode < 0) { + asciiCode += 256; + } + stdoutBuf.writeUInt8(asciiCode, stdoutPos++); + }, + stderr: (asciiCode) => { + if (asciiCode === null) { + return; // flush + } + if (BUFFER_MAX <= stderrPos) { + return; // ignore + } + if (asciiCode < 0) { + asciiCode += 256; + } + stderrBuf.writeUInt8(asciiCode, stderrPos++); + }, +}); + +const result = ccall( + 'php_wasm_run', + 'number', ['string'], + [PRELUDE + userCode], +); +console.log({ + status: result === 0 ? 'AC' : 'RE', + stdout: stdoutBuf.subarray(0, stdoutPos).toString(), + stderr: stderrBuf.subarray(0, stderrPos).toString(), +}); |
