mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-08 19:12:22 +00:00
fix(e2e): bound live plugin transcript scans
This commit is contained in:
@@ -32,6 +32,10 @@ const AGENT_OUTPUT_MAX_BYTES = readPositiveIntEnv(
|
||||
1024 * 1024,
|
||||
);
|
||||
const SESSION_FILE_LIST_LIMIT = 20;
|
||||
const SESSION_SCAN_MAX_ENTRIES = readPositiveIntEnv(
|
||||
"OPENCLAW_LIVE_PLUGIN_TOOL_SESSION_SCAN_MAX_ENTRIES",
|
||||
50_000,
|
||||
);
|
||||
|
||||
function requireEnv(name) {
|
||||
const value = process.env[name];
|
||||
@@ -112,28 +116,38 @@ function scanSessionTranscripts(sessionsDir, needles) {
|
||||
}
|
||||
|
||||
const pendingDirs = [sessionsDir];
|
||||
let scannedEntries = 0;
|
||||
while (pendingDirs.length > 0) {
|
||||
const dir = pendingDirs.pop();
|
||||
const entries = fs
|
||||
.readdirSync(dir, { withFileTypes: true })
|
||||
.toSorted((left, right) => left.name.localeCompare(right.name));
|
||||
for (const entry of entries) {
|
||||
const entryPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
pendingDirs.push(entryPath);
|
||||
continue;
|
||||
}
|
||||
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) {
|
||||
continue;
|
||||
}
|
||||
filesChecked += 1;
|
||||
if (checkedFiles.length < SESSION_FILE_LIST_LIMIT) {
|
||||
checkedFiles.push(path.relative(sessionsDir, entryPath));
|
||||
}
|
||||
if (scanFileForNeedles(entryPath, needles).size === 0) {
|
||||
pendingNeedles.clear();
|
||||
return { checkedFiles, filesChecked, missingDir: false, pendingNeedles };
|
||||
const handle = fs.opendirSync(dir);
|
||||
try {
|
||||
let entry;
|
||||
while ((entry = handle.readSync()) !== null) {
|
||||
scannedEntries += 1;
|
||||
if (scannedEntries > SESSION_SCAN_MAX_ENTRIES) {
|
||||
throw new Error(
|
||||
`session transcript scan exceeded ${SESSION_SCAN_MAX_ENTRIES} filesystem entries`,
|
||||
);
|
||||
}
|
||||
const entryPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
pendingDirs.push(entryPath);
|
||||
continue;
|
||||
}
|
||||
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) {
|
||||
continue;
|
||||
}
|
||||
filesChecked += 1;
|
||||
if (checkedFiles.length < SESSION_FILE_LIST_LIMIT) {
|
||||
checkedFiles.push(path.relative(sessionsDir, entryPath));
|
||||
}
|
||||
if (scanFileForNeedles(entryPath, needles).size === 0) {
|
||||
pendingNeedles.clear();
|
||||
return { checkedFiles, filesChecked, missingDir: false, pendingNeedles };
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
handle.closeSync();
|
||||
}
|
||||
}
|
||||
return { checkedFiles, filesChecked, missingDir: false, pendingNeedles };
|
||||
|
||||
@@ -126,6 +126,30 @@ describe("live plugin tool assertions", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("bounds session transcript traversal before scanning unbounded trees", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-live-plugin-tool-"));
|
||||
const sessionsDir = path.join(root, "state", "agents", "main", "sessions");
|
||||
|
||||
try {
|
||||
writeJson(path.join(root, "agent.json"), {
|
||||
payloads: [{ text: "live-plugin-slug" }],
|
||||
});
|
||||
mkdirSync(sessionsDir, { recursive: true });
|
||||
for (let index = 0; index < 4; index += 1) {
|
||||
writeFileSync(path.join(sessionsDir, `noise-${index}.jsonl`), "noise\n", "utf8");
|
||||
}
|
||||
|
||||
const result = runAssertion(root, {
|
||||
OPENCLAW_LIVE_PLUGIN_TOOL_SESSION_SCAN_MAX_ENTRIES: "2",
|
||||
});
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(result.stderr).toContain("session transcript scan exceeded 2 filesystem entries");
|
||||
} finally {
|
||||
rmSync(root, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects markers that only appear in error payload text", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-live-plugin-tool-"));
|
||||
const sessionsDir = path.join(root, "state", "agents", "main", "sessions");
|
||||
|
||||
Reference in New Issue
Block a user