<?php session_name("a3e0f0ee-9f5a-4be2-88cb-3b7ceb626d00"); session_start(); function get(string $id, string $name): ?string { $file = __DIR__ . "/../_runners/$id/results/" . $name; if (!is_file($file)) return null; return file_get_contents($file); } function csrf_token(): string { return $_SESSION["csrf-token"] = base64_encode(random_bytes(30)); } function getid(): string { return str_pad(bin2hex(random_bytes(16)), 32, "0", STR_PAD_LEFT); } function delTree($dir) { foreach (scandir($dir) as $ent) { if ($ent === "." || $ent === "..") continue; $path = $dir . DIRECTORY_SEPARATOR . $ent; if (is_dir($path)) delTree($path); else unlink($path); } return rmdir($dir); } function file_cachebuster(string $filename): string { return htmlentities(urlencode(md5( strval(filemtime($filename)) . strval(filesize($filename)) ))); } $defaultCode = <<<java public class Program { public static void main(String[] args) { // Your code here System.out.println("Hello, world!"); } } java; const CODE_MAXLENGTH = 16383; $code = null; if (!empty($_GET["c"])) { $compressedCode = @base64_decode($_GET["c"], true); if ($compressedCode !== false) { $uncompressedCode = @gzinflate($compressedCode, CODE_MAXLENGTH); if ($compressedCode !== false) { $code = &$uncompressedCode; } } } $result = null; if (isset($_POST["code"]) && strlen($_POST["code"]) <= CODE_MAXLENGTH) { header("Content-Type: application/json"); $code = $_POST["code"]; $csrf = $_POST["csrf"] ?? null; if ($csrf === null || $csrf !== $_SESSION["csrf-token"]) { echo json_encode([ "ok" => false, "message" => "CSRF token mismatch", "csrf" => csrf_token(), ]); exit; } if (($_POST["permalink"] ?? "") === "1") { echo json_encode([ "ok" => true, "data" => base64_encode(gzdeflate($code, 9, ZLIB_ENCODING_RAW)), ]); exit; } $id = getid(); $runnerDir = __DIR__ . "/../_runners/$id"; $srcDir = $runnerDir . "/src"; mkdir($srcDir, recursive: true); file_put_contents($srcDir . "/Program.java", $code); $isInDocker = getenv("IS_IN_DOCKER") === "1"; if ($isInDocker) file_put_contents("php://stderr", "[debug] In Docker\n"); chdir(__DIR__ . "/.."); $stderrFile = sys_get_temp_dir() . "/tmp{$id}.2"; exec( ($isInDocker ? "su-exec root " : "") . "./compile-and-run.sh '$id' Program 2>'$stderrFile'", $resultStr, $code); $resultStr = implode("\n", $resultStr); if (is_file($stderrFile)) { $stderrContents = file_get_contents($stderrFile); unlink($stderrFile); if (!empty($stderrContents)) { file_put_contents("php://stderr", "compile-and-run.sh failed: $stderrContents\n"); if ($code != 0) { echo json_encode([ "ok" => false, "message" => "Execution failed:\n$stderrContents", "csrf" => csrf_token(), ]); delTree($runnerDir); exit; } } } chdir(__DIR__); file_put_contents("php://stderr", "result: $result\n"); $csrf = csrf_token(); $result = [ "compile" => [ "status" => get($id, "c.s"), "stdout" => get($id, "c.0"), "stderr" => get($id, "c.1"), ], "run" => [ "status" => get($id, "r.s"), "stdout" => get($id, "r.0"), "stderr" => get($id, "r.1"), ], "runner" => $id, "ok" => true, "csrf" => $csrf, ]; if ($isInDocker) exec("su-exec root rm -rf '$runnerDir'"); else delTree($runnerDir); echo json_encode($result); exit; } $csrf = csrf_token(); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Java</title> <link rel="stylesheet" href="dist/codemirror.css"> <link rel="stylesheet" href="dist/eclipse.css"> <link rel="stylesheet" href="site.css?_=<?= file_cachebuster(__DIR__ . "/site.css") ?>"> <script src="dist/jquery-1.12.4.min.js"></script> <script src="dist/codemirror.js"></script> <script src="dist/clike.js"></script> <script src="site.js?_=<?= file_cachebuster(__DIR__ . "/site.js") ?>"></script> </head> <body> <div id="loader" style="display: none;"> <div id="spinner"></div> </div> <h1>☕️ Java Compiler</h1> <p>Powered by Eclipse Temurin</p> <form method="POST"> <input name="csrf" id="csrf-token" type="hidden" value="<?= htmlentities($csrf) ?>"> <textarea maxlength="<?= CODE_MAXLENGTH ?>" id="editor" name="code" rows="20"><?= htmlentities($code ?? $defaultCode) ?></textarea> <div id="toolbar"> <button type="submit">▶️ Compile & run</button> <button type="button" id="dlCodeButton">💾️ Download code as file</button> <button type="button" id="permalink">🔗️ Permalink</button> </div> </form> <div id="output" style="display: none;"></div> <div id="footer"> © <?= date("Y") ?> <a href="https://jkohl.link/" target="_blank">Jonas Kohl</a>. <a href="https://git.jkohl.link/online-java-compiler.git" target="_blank">Source code</a>. <a href="javascript:;" id="toggleFullWidth">Toggle full width</a> </div> </body> </html>