Bound plugin bundle command file reads with size cap#110594
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 18, 2026, 5:43 PM ET / 21:43 UTC. Summary PR surface: Source +9, Tests +48. Total +57 across 2 files. Reproducibility: yes. from source and supplied after-fix evidence: current Review metrics: none identified. Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Keep the bounded-read hardening, but have the plugin owner explicitly accept the 1 MiB installed-command limit (or choose a documented, supportable alternative) and retain the warning-plus-sibling-continuation behavior before merge. Do we have a high-confidence way to reproduce the issue? Yes from source and supplied after-fix evidence: current Is this the best way to solve the issue? Unclear: using the shared bounded regular-file primitive is the narrowest maintainable technical mechanism, but the 1 MiB installed-plugin compatibility contract needs explicit owner acceptance before it can be called the best product solution. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against fa9ae68c3423. Label changesLabel justifications:
Evidence reviewedPR surface: Source +9, Tests +48. Total +57 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (9 earlier review cycles; latest 8 shown)
|
Behavior Proof — Bounded Bundle Command File ReadTest Coverage运行 Live Bounded-Read Validation直接验证 两种场景全部通过:
CI Gate
|
The catch block now captures the error and emits a console.warn with the file path and error detail, so upgrades do not silently remove oversized installed commands.
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
PR body updated with behavioral proof and compatibility contract. @clawsweeper re-review |
|
PR body updated with full bundle-loader path proof (normal loads, oversized warns with diagnostic, sibling continues). @clawsweeper re-review |
…ntinue PR openclaw#110594: Add focused regression coverage: - Test: an oversized bundle command markdown file (>1 MB) is skipped via catch + continue - Test: normal sibling command files still load correctly - Verifies console.warn diagnostic is emitted for the oversized file
Co-authored-by: 陈宪彪0668000387 <[email protected]>
Co-authored-by: 陈宪彪0668000387 <[email protected]>
|
Merged via squash.
|
* Bound bundle command file reads with size cap * fix: use buffer.toString for readRegularFileSync result * fix: log oversized bundle command file diagnostic instead of silent skip The catch block now captures the error and emits a console.warn with the file path and error detail, so upgrades do not silently remove oversized installed commands. * test: verify oversized bundle command file is skipped and siblings continue PR openclaw#110594: Add focused regression coverage: - Test: an oversized bundle command markdown file (>1 MB) is skipped via catch + continue - Test: normal sibling command files still load correctly - Verifies console.warn diagnostic is emitted for the oversized file * refactor(plugins): log rejected bundle commands Co-authored-by: 陈宪彪0668000387 <[email protected]> * style(plugins): format bundle warning Co-authored-by: 陈宪彪0668000387 <[email protected]> --------- Co-authored-by: Peter Steinberger <[email protected]>
What Problem This Solves
loadBundleCommandsFromRootcallsfs.readFileSync(filePath, "utf-8")on user-installed plugin bundle command markdown files with no size limit. A corrupted, enormous, or malicious command file can OOM the process during plugin bundle load.Why This Change Was Made
PR #101472 established
readRegularFileSync/readRegularFilefrom@openclaw/fs-safe/advancedas the standard bounded-read primitive. This applies the same pattern to plugin bundle command file reads — since bundle commands are user-installed content that should not be trusted to have reasonable size.User Impact
No user-visible change under normal conditions. Plugin bundle command files under 1 MB load identically to before. Files exceeding 1 MB produce an actionable
console.warndiagnostic naming the oversized file path and error detail, then skip that file and continue loading sibling commands — instead of crashing the load path with an OOM or hang.Compatibility Contract
The 1 MB cap is documented via the
BUNDLE_COMMAND_MAX_BYTES = 1 * 1024 * 1024constant (line 36). Oversized existing command files are skipped with a diagnostic warning (not silently dropped). Theconsole.warnoutput includes the file path ([bundle-commands] skipping unreadable command file: <path>) and the error detail, so if an upgrade causes a previously-loadable command to be skipped, the operator sees exactly which file and why.Evidence
Code changes
src/plugins/bundle-commands.ts:112-123: Replacedfs.readFileSync(filePath, "utf-8")withreadRegularFileSync({ filePath, maxBytes: BUNDLE_COMMAND_MAX_BYTES }).buffer.toString("utf-8")inside a try/catch that logs a diagnostic warning before continuingsrc/plugins/bundle-commands.ts:36: AddedBUNDLE_COMMAND_MAX_BYTES = 1 * 1024 * 1024constantreadRegularFileSyncimport from../infra/regular-file.jscatch (error)block logs[bundle-commands] skipping unreadable command file: <path>with the error detail, making oversized files observable rather than silently skippedBehavioral proof — full loader path with oversized rejection + sibling continuation
The proof demonstrates the complete changed behavior of
loadBundleCommandsFromRoot:[bundle-commands] skipping unreadable command file: <path> File exceeds 1048576 bytes: <path>diagnostic viaconsole.warn, then continuesUnit tests
src/plugins/bundle-commands.test.ts: 1 test passed (under|plugins|Vitest shard) — exercisesloadEnabledClaudeBundleCommandsfull loader path with mocked plugin registryFull proof commands
Related
readRegularFileSyncbounded-read pattern insrc/cron/store.ts)