"""보존된 Chrome 원문 argv와 Playwright JSON으로 sandbox/전체 실행 결과를 요약한다.""" import json from pathlib import Path import re EVIDENCE = Path(__file__).resolve().parent def sandbox_summary(processes): """이 환경의 /proc는 전체 명령을 argv[0] 하나로도 반환한다. 정확한 flag 경계를 검사한다.""" def flag(row, value): return bool(re.search(r"(?:^|\s)" + re.escape(value) + r"(?:\s|$)", " ".join(row["argv"]))) renderers = [row for row in processes if flag(row, "--type=renderer")] browser = [row for row in processes if not re.search(r"(?:^|\s)--type=", " ".join(row["argv"]))] return { "browserObserved": bool(browser), "rendererObserved": bool(renderers), "browserProcessCount": len(browser), "rendererProcessCount": len(renderers), "noSandboxFlagAbsent": bool(processes) and all(not flag(row, "--no-sandbox") for row in processes), "rendererSeccompEnabled": bool(renderers) and all(row["seccomp"] == "2" for row in renderers), "rendererNoNewPrivs": bool(renderers) and all(row["noNewPrivs"] == "1" for row in renderers), } if __name__ == "__main__": original = json.loads((EVIDENCE / "chrome-process-observations.json").read_text()) sandbox = sandbox_summary(original["processes"]) # 1요소 argv와 NUL로 분리된 argv 모두 flag를 검출하며 --no-zygote-sandbox와 혼동하지 않는다. for args in (["chrome", "--type=renderer", "--no-sandbox"], ["chrome --type=renderer --no-sandbox"]): negative = sandbox_summary([{"argv": args, "seccomp": "0", "noNewPrivs": "0"}]) if negative["noSandboxFlagAbsent"] or not negative["rendererObserved"]: raise ValueError("Sandbox flag parser regression") if not all(sandbox[key] for key in ("browserObserved", "rendererObserved", "noSandboxFlagAbsent", "rendererSeccompEnabled", "rendererNoNewPrivs")): raise ValueError(sandbox) corrected = { "source": "chrome-process-observations.json", "correction": "Original parser used argv list membership; this /proc capture contains the whole command in argv[0]. Raw process observations are unchanged. Corrected flag-boundary parsing detects browser and sandboxed renderers.", "playwrightExitCode": original["exitCode"], "initialCollectorExitCode": 1, "chromeVersion": original["chromeVersion"], "chromiumSandbox": original["chromiumSandbox"], **sandbox, } (EVIDENCE / "chrome-sandbox.json").write_text(json.dumps(corrected, indent=2) + "\n") results = json.loads((EVIDENCE / "browser-results.json").read_text()) stats = results["stats"] if stats["expected"] != 36 or any(stats[key] for key in ("unexpected", "skipped", "flaky")) or results["errors"]: raise ValueError("Full browser suite did not pass cleanly") summary = {"stats": stats, "errors": results["errors"], "sandbox": corrected} (EVIDENCE / "browser-summary.json").write_text(json.dumps(summary, indent=2) + "\n") print(json.dumps(summary, indent=2))