mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-14 04:18:35 +00:00
refactor: split inbound and reload pipelines into staged modules
This commit is contained in:
83
src/infra/exec-allowlist-pattern.ts
Normal file
83
src/infra/exec-allowlist-pattern.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import fs from "node:fs";
|
||||
import { expandHomePrefix } from "./home-dir.js";
|
||||
|
||||
const GLOB_REGEX_CACHE_LIMIT = 512;
|
||||
const globRegexCache = new Map<string, RegExp>();
|
||||
|
||||
function normalizeMatchTarget(value: string): string {
|
||||
if (process.platform === "win32") {
|
||||
const stripped = value.replace(/^\\\\[?.]\\/, "");
|
||||
return stripped.replace(/\\/g, "/").toLowerCase();
|
||||
}
|
||||
return value.replace(/\\\\/g, "/").toLowerCase();
|
||||
}
|
||||
|
||||
function tryRealpath(value: string): string | null {
|
||||
try {
|
||||
return fs.realpathSync(value);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function escapeRegExpLiteral(input: string): string {
|
||||
return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
function compileGlobRegex(pattern: string): RegExp {
|
||||
const cached = globRegexCache.get(pattern);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
let regex = "^";
|
||||
let i = 0;
|
||||
while (i < pattern.length) {
|
||||
const ch = pattern[i];
|
||||
if (ch === "*") {
|
||||
const next = pattern[i + 1];
|
||||
if (next === "*") {
|
||||
regex += ".*";
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
regex += "[^/]*";
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (ch === "?") {
|
||||
regex += ".";
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
regex += escapeRegExpLiteral(ch);
|
||||
i += 1;
|
||||
}
|
||||
regex += "$";
|
||||
|
||||
const compiled = new RegExp(regex, "i");
|
||||
if (globRegexCache.size >= GLOB_REGEX_CACHE_LIMIT) {
|
||||
globRegexCache.clear();
|
||||
}
|
||||
globRegexCache.set(pattern, compiled);
|
||||
return compiled;
|
||||
}
|
||||
|
||||
export function matchesExecAllowlistPattern(pattern: string, target: string): boolean {
|
||||
const trimmed = pattern.trim();
|
||||
if (!trimmed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const expanded = trimmed.startsWith("~") ? expandHomePrefix(trimmed) : trimmed;
|
||||
const hasWildcard = /[*?]/.test(expanded);
|
||||
let normalizedPattern = expanded;
|
||||
let normalizedTarget = target;
|
||||
if (process.platform === "win32" && !hasWildcard) {
|
||||
normalizedPattern = tryRealpath(expanded) ?? expanded;
|
||||
normalizedTarget = tryRealpath(target) ?? target;
|
||||
}
|
||||
normalizedPattern = normalizeMatchTarget(normalizedPattern);
|
||||
normalizedTarget = normalizeMatchTarget(normalizedTarget);
|
||||
return compileGlobRegex(normalizedPattern).test(normalizedTarget);
|
||||
}
|
||||
Reference in New Issue
Block a user