mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix: repair bundled plugin dirs after npm install
This commit is contained in:
@@ -328,6 +328,35 @@ describe("discoverOpenClawPlugins", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it.runIf(process.platform !== "win32")(
|
||||
"repairs world-writable bundled plugin dirs before loading them",
|
||||
async () => {
|
||||
const stateDir = makeTempDir();
|
||||
const bundledDir = path.join(stateDir, "bundled");
|
||||
const packDir = path.join(bundledDir, "demo-pack");
|
||||
fs.mkdirSync(packDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(packDir, "index.ts"), "export default function () {}", "utf-8");
|
||||
fs.chmodSync(packDir, 0o777);
|
||||
|
||||
const result = await withEnvAsync(
|
||||
{
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
CLAWDBOT_STATE_DIR: undefined,
|
||||
OPENCLAW_BUNDLED_PLUGINS_DIR: bundledDir,
|
||||
},
|
||||
async () => discoverOpenClawPlugins({}),
|
||||
);
|
||||
|
||||
expect(result.candidates.some((candidate) => candidate.idHint === "demo-pack")).toBe(true);
|
||||
expect(
|
||||
result.diagnostics.some(
|
||||
(diag) => diag.source === packDir && diag.message.includes("world-writable path"),
|
||||
),
|
||||
).toBe(false);
|
||||
expect(fs.statSync(packDir).mode & 0o777).toBe(0o755);
|
||||
},
|
||||
);
|
||||
|
||||
it.runIf(process.platform !== "win32" && typeof process.getuid === "function")(
|
||||
"blocks suspicious ownership when uid mismatch is detected",
|
||||
async () => {
|
||||
|
||||
@@ -153,7 +153,7 @@ function checkPathStatAndPermissions(params: {
|
||||
continue;
|
||||
}
|
||||
seen.add(normalized);
|
||||
const stat = safeStatSync(targetPath);
|
||||
let stat = safeStatSync(targetPath);
|
||||
if (!stat) {
|
||||
return {
|
||||
reason: "path_stat_failed",
|
||||
@@ -162,7 +162,28 @@ function checkPathStatAndPermissions(params: {
|
||||
targetPath,
|
||||
};
|
||||
}
|
||||
const modeBits = stat.mode & 0o777;
|
||||
let modeBits = stat.mode & 0o777;
|
||||
if ((modeBits & 0o002) !== 0 && params.origin === "bundled") {
|
||||
// npm/global installs can create package-managed extension dirs without
|
||||
// directory entries in the tarball, which may widen them to 0777.
|
||||
// Tighten bundled dirs in place before applying the normal safety gate.
|
||||
try {
|
||||
fs.chmodSync(targetPath, modeBits & ~0o022);
|
||||
const repairedStat = safeStatSync(targetPath);
|
||||
if (!repairedStat) {
|
||||
return {
|
||||
reason: "path_stat_failed",
|
||||
sourcePath: params.source,
|
||||
rootPath: params.rootDir,
|
||||
targetPath,
|
||||
};
|
||||
}
|
||||
stat = repairedStat;
|
||||
modeBits = repairedStat.mode & 0o777;
|
||||
} catch {
|
||||
// Fall through to the normal block path below when repair is not possible.
|
||||
}
|
||||
}
|
||||
if ((modeBits & 0o002) !== 0) {
|
||||
return {
|
||||
reason: "path_world_writable",
|
||||
|
||||
Reference in New Issue
Block a user