mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-14 08:00:28 +00:00
fix(plugins): guard setup backend metadata
This commit is contained in:
@@ -155,6 +155,81 @@ describe("setup-registry runtime fallback", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("skips unreadable bundled setup backend metadata in runtime fallback lookups", async () => {
|
||||
const poisonedPlugin = Object.defineProperty({}, "origin", {
|
||||
get() {
|
||||
throw new Error("setup backend origin exploded");
|
||||
},
|
||||
});
|
||||
loadPluginMetadataSnapshotMock.mockReturnValue({
|
||||
index: {
|
||||
diagnostics: [],
|
||||
plugins: [
|
||||
{
|
||||
pluginId: "openai",
|
||||
origin: "bundled",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
poisonedPlugin,
|
||||
{
|
||||
id: "openai",
|
||||
origin: "bundled",
|
||||
cliBackends: ["Codex-CLI"],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { testing, resolvePluginSetupCliBackendRuntime } =
|
||||
await import("./setup-registry.runtime.js");
|
||||
testing.resetRuntimeState();
|
||||
testing.setRuntimeModuleForTest(null);
|
||||
|
||||
expect(resolvePluginSetupCliBackendRuntime({ backend: "codex-cli" })).toEqual({
|
||||
pluginId: "openai",
|
||||
backend: { id: "Codex-CLI" },
|
||||
});
|
||||
});
|
||||
|
||||
it("skips unreadable setup backend metadata in descriptor lookups", async () => {
|
||||
const poisonedPlugin = Object.defineProperty({}, "id", {
|
||||
get() {
|
||||
throw new Error("setup backend id exploded");
|
||||
},
|
||||
});
|
||||
loadPluginMetadataSnapshotMock.mockReturnValue({
|
||||
index: {
|
||||
diagnostics: [],
|
||||
plugins: [
|
||||
{
|
||||
pluginId: "openai",
|
||||
origin: "bundled",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
poisonedPlugin,
|
||||
{
|
||||
id: "openai",
|
||||
origin: "bundled",
|
||||
cliBackends: ["Codex-CLI"],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { testing, resolvePluginSetupCliBackendDescriptor } =
|
||||
await import("./setup-registry.runtime.js");
|
||||
testing.resetRuntimeState();
|
||||
|
||||
expect(resolvePluginSetupCliBackendDescriptor({ backend: "codex-cli" })).toEqual({
|
||||
pluginId: "openai",
|
||||
backend: { id: "Codex-CLI" },
|
||||
});
|
||||
});
|
||||
|
||||
it("refreshes bundled registry cliBackends when the current metadata snapshot changes", async () => {
|
||||
const { testing, resolvePluginSetupCliBackendRuntime } =
|
||||
await import("./setup-registry.runtime.js");
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createRequire } from "node:module";
|
||||
import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { isInstalledPluginEnabled } from "./installed-plugin-index.js";
|
||||
import type { PluginManifestRecord } from "./manifest-registry.js";
|
||||
import {
|
||||
resolvePluginMetadataSnapshot,
|
||||
type PluginMetadataSnapshot,
|
||||
@@ -87,16 +88,7 @@ function resolveBundledSetupCliBackends(
|
||||
return cachedBundledSetupCliBackends.entries;
|
||||
}
|
||||
const entries = snapshot.plugins.flatMap((plugin) => {
|
||||
if (plugin.origin !== "bundled" || !isInstalledPluginEnabled(snapshot.index, plugin.id)) {
|
||||
return [];
|
||||
}
|
||||
return [...plugin.cliBackends, ...(plugin.setup?.cliBackends ?? [])].map(
|
||||
(backendId) =>
|
||||
({
|
||||
pluginId: plugin.id,
|
||||
backend: { id: backendId },
|
||||
}) satisfies SetupCliBackendRuntimeEntry,
|
||||
);
|
||||
return readSetupCliBackendRuntimeEntries({ plugin, snapshot, bundledOnly: true });
|
||||
});
|
||||
if (cacheable && configFingerprint) {
|
||||
cachedBundledSetupCliBackends = { configFingerprint, entries };
|
||||
@@ -117,16 +109,7 @@ function resolveSetupCliBackendDescriptors(
|
||||
return cachedSetupCliBackendDescriptors.entries;
|
||||
}
|
||||
const entries = snapshot.plugins.flatMap((plugin) => {
|
||||
if (!isInstalledPluginEnabled(snapshot.index, plugin.id)) {
|
||||
return [];
|
||||
}
|
||||
return [...plugin.cliBackends, ...(plugin.setup?.cliBackends ?? [])].map(
|
||||
(backendId) =>
|
||||
({
|
||||
pluginId: plugin.id,
|
||||
backend: { id: backendId },
|
||||
}) satisfies SetupCliBackendRuntimeEntry,
|
||||
);
|
||||
return readSetupCliBackendRuntimeEntries({ plugin, snapshot });
|
||||
});
|
||||
if (cacheable && configFingerprint) {
|
||||
cachedSetupCliBackendDescriptors = { configFingerprint, entries };
|
||||
@@ -134,6 +117,31 @@ function resolveSetupCliBackendDescriptors(
|
||||
return entries;
|
||||
}
|
||||
|
||||
function readSetupCliBackendRuntimeEntries(params: {
|
||||
plugin: PluginManifestRecord;
|
||||
snapshot: PluginMetadataSnapshot;
|
||||
bundledOnly?: boolean;
|
||||
}): SetupCliBackendRuntimeEntry[] {
|
||||
try {
|
||||
if (params.bundledOnly && params.plugin.origin !== "bundled") {
|
||||
return [];
|
||||
}
|
||||
const pluginId = params.plugin.id;
|
||||
if (!isInstalledPluginEnabled(params.snapshot.index, pluginId)) {
|
||||
return [];
|
||||
}
|
||||
return [...params.plugin.cliBackends, ...(params.plugin.setup?.cliBackends ?? [])].map(
|
||||
(backendId) =>
|
||||
({
|
||||
pluginId,
|
||||
backend: { id: backendId },
|
||||
}) satisfies SetupCliBackendRuntimeEntry,
|
||||
);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function loadSetupRegistryRuntime(): SetupRegistryRuntimeModule | null {
|
||||
if (setupRegistryRuntimeModule !== undefined) {
|
||||
return setupRegistryRuntimeModule;
|
||||
|
||||
Reference in New Issue
Block a user