mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-08 19:12:22 +00:00
fix(e2e): bound kitchen sink log traversal
This commit is contained in:
@@ -9,6 +9,7 @@ const scratchRoot = process.env.KITCHEN_SINK_TMP_DIR || os.tmpdir();
|
||||
|
||||
const LOG_SCAN_CHUNK_BYTES = 64 * 1024;
|
||||
const LOG_SCAN_FINDING_CONTEXT_CHARS = 2048;
|
||||
const LOG_SCAN_MAX_ENTRIES = readPositiveIntEnv("KITCHEN_SINK_LOG_SCAN_MAX_ENTRIES", 20_000);
|
||||
const LOG_SCAN_MAX_FILES = 5000;
|
||||
const LOG_SCAN_MAX_FINDINGS = 100;
|
||||
const LOG_SCAN_MAX_LINE_CHARS = 16 * 1024;
|
||||
@@ -18,6 +19,22 @@ const readJson = (file) => JSON.parse(fs.readFileSync(file, "utf8"));
|
||||
const scratchFile = (name) => path.join(scratchRoot, name);
|
||||
const normalizedPath = (filePath) => filePath.replaceAll("\\", "/");
|
||||
|
||||
function readPositiveIntEnv(name, fallback) {
|
||||
const raw = process.env[name];
|
||||
if (raw === undefined || raw === "") {
|
||||
return fallback;
|
||||
}
|
||||
const text = raw.trim();
|
||||
if (!/^\d+$/u.test(text)) {
|
||||
throw new Error(`${name} must be a positive integer; got: ${raw}`);
|
||||
}
|
||||
const parsed = Number(text);
|
||||
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
||||
throw new Error(`${name} must be a positive integer; got: ${raw}`);
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function resolveHomePath(value) {
|
||||
if (value === "~") {
|
||||
return process.env.HOME;
|
||||
@@ -115,6 +132,7 @@ function shouldScanLogFile(entry) {
|
||||
|
||||
function scanLogFiles(roots, onFile) {
|
||||
let scannedFiles = 0;
|
||||
let visitedEntries = 0;
|
||||
for (const root of roots) {
|
||||
const pending = [root];
|
||||
while (pending.length > 0) {
|
||||
@@ -122,6 +140,12 @@ function scanLogFiles(roots, onFile) {
|
||||
if (!entry || !fs.existsSync(entry)) {
|
||||
continue;
|
||||
}
|
||||
visitedEntries += 1;
|
||||
if (visitedEntries > LOG_SCAN_MAX_ENTRIES) {
|
||||
throw new Error(
|
||||
`kitchen-sink log scan exceeded ${LOG_SCAN_MAX_ENTRIES} filesystem entries`,
|
||||
);
|
||||
}
|
||||
const stat = fs.lstatSync(entry);
|
||||
if (stat.isSymbolicLink()) {
|
||||
continue;
|
||||
|
||||
@@ -193,11 +193,20 @@ function runAssertClawhubInstalled({
|
||||
}
|
||||
}
|
||||
|
||||
function runScanLogs({ home, scratchRoot }: { home: string; scratchRoot: string }) {
|
||||
function runScanLogs({
|
||||
env = {},
|
||||
home,
|
||||
scratchRoot,
|
||||
}: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
home: string;
|
||||
scratchRoot: string;
|
||||
}) {
|
||||
return spawnSync(process.execPath, [ASSERTIONS_SCRIPT, "scan-logs"], {
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
...env,
|
||||
HOME: home,
|
||||
KITCHEN_SINK_TMP_DIR: scratchRoot,
|
||||
},
|
||||
@@ -291,6 +300,35 @@ describe("kitchen-sink plugin assertions", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("bounds irrelevant OpenClaw home traversal during log scans", () => {
|
||||
const parent = mkdtempSync(path.join(tmpdir(), "openclaw-kitchen-sink-scan-"));
|
||||
const home = path.join(parent, "home");
|
||||
const scratchRoot = path.join(parent, "scratch");
|
||||
try {
|
||||
mkdirSync(path.join(home, ".openclaw"), { recursive: true });
|
||||
mkdirSync(scratchRoot, { recursive: true });
|
||||
writeFileSync(path.join(scratchRoot, "scenario.log"), "0 errors\n");
|
||||
for (let index = 0; index < 20; index += 1) {
|
||||
const dir = path.join(home, ".openclaw", `cache-${index}`);
|
||||
mkdirSync(dir, { recursive: true });
|
||||
writeFileSync(path.join(dir, "state.txt"), "not a log\n");
|
||||
}
|
||||
|
||||
const result = runScanLogs({
|
||||
env: { KITCHEN_SINK_LOG_SCAN_MAX_ENTRIES: "8" },
|
||||
home,
|
||||
scratchRoot,
|
||||
});
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(`${result.stdout}\n${result.stderr}`).toContain(
|
||||
"kitchen-sink log scan exceeded 8 filesystem entries",
|
||||
);
|
||||
} finally {
|
||||
rmSync(parent, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("does not allow dirty error lines just because they mention zero errors", () => {
|
||||
const parent = mkdtempSync(path.join(tmpdir(), "openclaw-kitchen-sink-scan-"));
|
||||
const home = path.join(parent, "home");
|
||||
|
||||
Reference in New Issue
Block a user