fix: reject malformed clawhub plugin specs

This commit is contained in:
Peter Steinberger
2026-04-27 10:07:27 +01:00
parent 6c252cc54c
commit 9f450dcf06
3 changed files with 21 additions and 3 deletions

View File

@@ -20,6 +20,7 @@ Docs: https://docs.openclaw.ai
- Agents/Claude CLI: force live-session launches to include `--output-format stream-json` whenever OpenClaw adds `--input-format stream-json`, so new Claude CLI sessions no longer fail immediately while reusable sessions keep working. Fixes #72206. Thanks @kwangwonkoh and @Xivi08.
- CLI/plugins: accept ClawHub plugin API wildcard ranges such as `*` without rejecting compatible plugin installs, while still requiring a valid runtime API version. Fixes #56446; supersedes #56466. Thanks @darconada and @claygeo.
- CLI/plugins: let config-gated bundled plugins install without persisting invalid placeholder config entries, so install/uninstall sweeps can cover plugins such as memory-lancedb before the user configures credentials. Thanks @vincentkoc.
- CLI/plugins: reject malformed ClawHub plugin specs with trailing `@` before registry lookup, so empty-version typos report as invalid specs instead of package-not-found errors. Fixes #56579; supersedes #56582. Thanks @Kansodata.
- Agents/sessions: acquire the session write lock only after cold bootstrap, plugin, and tool setup so fallback runs are not blocked by stalled pre-model startup work. Thanks @codex.
- Browser/plugins: auto-start the bundled browser plugin when root `browser` config is present, including restrictive plugin allowlists, and ignore stale persisted plugin registries whose package paths no longer exist. Thanks @codex.
- Browser: circuit-break repeated managed Chrome launch failures per profile so browser requests stop spawning Chromium indefinitely when CDP cannot start. Fixes #64271. Thanks @TheophilusChinomona.

View File

@@ -14,11 +14,19 @@ export function parseClawHubPluginSpec(raw: string): {
return null;
}
const atIndex = spec.lastIndexOf("@");
if (atIndex <= 0 || atIndex >= spec.length - 1) {
if (atIndex <= 0) {
return { name: spec };
}
if (atIndex >= spec.length - 1) {
return null;
}
const name = spec.slice(0, atIndex).trim();
const version = spec.slice(atIndex + 1).trim();
if (!name || !version) {
return null;
}
return {
name: spec.slice(0, atIndex).trim(),
version: spec.slice(atIndex + 1).trim() || undefined,
name,
version,
};
}

View File

@@ -42,6 +42,15 @@ describe("clawhub helpers", () => {
name: "demo",
version: "1.2.3",
});
expect(parseClawHubPluginSpec("clawhub:@scope/pkg")).toEqual({
name: "@scope/pkg",
});
expect(parseClawHubPluginSpec("clawhub:@scope/pkg@1.2.3")).toEqual({
name: "@scope/pkg",
version: "1.2.3",
});
expect(parseClawHubPluginSpec("clawhub:demo@")).toBeNull();
expect(parseClawHubPluginSpec("clawhub:@scope/pkg@")).toBeNull();
expect(parseClawHubPluginSpec("@scope/pkg")).toBeNull();
});