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")(
|
it.runIf(process.platform !== "win32" && typeof process.getuid === "function")(
|
||||||
"blocks suspicious ownership when uid mismatch is detected",
|
"blocks suspicious ownership when uid mismatch is detected",
|
||||||
async () => {
|
async () => {
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ function checkPathStatAndPermissions(params: {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
seen.add(normalized);
|
seen.add(normalized);
|
||||||
const stat = safeStatSync(targetPath);
|
let stat = safeStatSync(targetPath);
|
||||||
if (!stat) {
|
if (!stat) {
|
||||||
return {
|
return {
|
||||||
reason: "path_stat_failed",
|
reason: "path_stat_failed",
|
||||||
@@ -162,7 +162,28 @@ function checkPathStatAndPermissions(params: {
|
|||||||
targetPath,
|
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) {
|
if ((modeBits & 0o002) !== 0) {
|
||||||
return {
|
return {
|
||||||
reason: "path_world_writable",
|
reason: "path_world_writable",
|
||||||
|
|||||||
Reference in New Issue
Block a user