fix(clawhub): sanitize archive temp filenames#56779
Conversation
Greptile SummaryThis PR fixes a targeted Changes:
The fix reuses the existing Confidence Score: 5/5Safe to merge — minimal, well-tested fix with no side effects outside the temp archive filename. The change is two one-line substitutions that apply the already-established safeDirName() helper to the two archive-path construction sites. safeDirName() is already tested and used elsewhere in the codebase for the same purpose. The new regression tests cover both failure modes directly, and all other PR scope (resolution, extraction, install dir, manifest) is explicitly unchanged. No P0 or P1 issues found. No files require special attention.
|
| Filename | Overview |
|---|---|
| src/infra/clawhub.ts | Both archive-path constructions now wrap the raw identifier with safeDirName(), replacing / and \ with __ before the filename is passed to fs.writeFile. The fix is minimal, correctly scoped, and consistent with how the rest of the plugin-install code already handles identifier encoding. |
| src/infra/clawhub.test.ts | Two new regression tests added: one for scoped package names (@soimy/dingtalk → @soimy__dingtalk.zip) and one for slash-containing skill slugs (ops/calendar → ops__calendar.zip). Both tests assert the sanitized basename and the file contents, and clean up the temp directory in a finally block. |
| CHANGELOG.md | One-line entry added to the unreleased section, accurately describing the user-visible fix and linking the issue number. |
Reviews (1): Last reviewed commit: "fix(clawhub): sanitize archive temp file..." | Re-trigger Greptile
8974b68 to
37e3991
Compare
37e3991 to
de12876
Compare
|
Merged in eee8e96 after verification with pnpm build, pnpm check, and pnpm test. I rebased the PR branch onto current main, carried the ClawHub temp-filename fix and its focused tests through two unreleased changelog conflicts, and pushed the refreshed head before merge. The changelog entry is in CHANGELOG.md under ### Fixes. |
Verified: - pnpm build - pnpm check - pnpm test Co-authored-by: soimy <1550237+soimy@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Verified: - pnpm build - pnpm check - pnpm test Co-authored-by: soimy <1550237+soimy@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Verified: - pnpm build - pnpm check - pnpm test Co-authored-by: soimy <1550237+soimy@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Verified: - pnpm build - pnpm check - pnpm test Co-authored-by: soimy <1550237+soimy@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Verified: - pnpm build - pnpm check - pnpm test Co-authored-by: soimy <1550237+soimy@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Verified: - pnpm build - pnpm check - pnpm test Co-authored-by: soimy <1550237+soimy@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Verified: - pnpm build - pnpm check - pnpm test Co-authored-by: soimy <1550237+soimy@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Summary
downloadClawHubPackageArchive()built the temp zip path from the raw package name, so scoped names like@soimy/dingtalkturned into<tmp>/@soimy/dingtalk.zipand failed withENOENTbefore extraction.openclaw plugins install <package>flow was blocked for scoped plugin packages.safeDirName()for ClawHub package and skill archive temp filenames, add focused unit coverage for slash-containing package names and slugs, and note the user-visible fix inCHANGELOG.md.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause / Regression History (if applicable)
src/infra/clawhub.tsusedpath.join(tmpDir,${params.name}.zip)andpath.join(tmpDir,${params.slug}.zip), so slash-containing identifiers were treated as nested directories instead of temp file basenames.git blame, prior PR, issue, or refactor if known): OpenClaw already usedsafeDirName()insrc/plugins/install.tsfor install-directory naming, but the ClawHub temp archive path missed that normalization.fs.writeFile()call.Regression Test Plan (if applicable)
src/infra/clawhub.test.tsUser-visible / Behavior Changes
openclaw plugins install @scope/nameno longer fails during the ClawHub archive download step just because the package name contains/.Diagram (if applicable)
Security Impact (required)
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) NoYes, explain risk + mitigation: N/ARepro + Verification
Environment
Steps
openclaw plugins install @soimy/dingtalk.Expected
Actual
ENOENTduringfs.writeFile().Evidence
Attach at least one:
Human Verification (required)
@soimy/dingtalkandops/calendar; confirmed they fail before the fix withENOENTand pass after the fix./now map to safe temp zip basenames using the repo's existingsafeDirName()convention.Review Conversations
If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.
Compatibility / Migration
Yes/No) YesYes/No) NoYes/No) NoRisks and Mitigations