fix(updater): fail-closed patch error handling + redirect-safe releases fetch#174
Conversation
…es fetch Follow-ups from the PR #172 review, verified against current code (locale keys, sidecar guard, digest full-hex regex and scrape-hooks read were already done). - applyPreUpdatePatch: a PRESENT, digest-verified patch that then fails to stage, parses to a non-array, or throws mid-apply used to return success=true (fail-open) — letting the install proceed half/un-patched. Now fail-closed (success=false) so the caller aborts; nothing is committed yet, retry is clean. - applyPostInstallPatch catch: a runtime error set only error but left success=true, hiding it as "no patch". Now success=false so it surfaces through the caller's non-fatal warning branch (core update already done → warning). - fetchReleasesRaw cURL branch (primary + token-retry): FOLLOWLOCATION=false / MAXREDIRS=0 and success gated to 2xx, matching makeGitHubRequest's stance. Token was already protected by UNRESTRICTED_AUTH=false; this is defense-in-depth. The asset-download paths keep FOLLOWLOCATION=true on purpose (github.com -> CDN). Skipped (false positive): create-release.sh "draft-safe" finding — gh release view <tag> (CLI) does resolve drafts by tag_name (0.7.20 passed those steps as a draft); only the REST /releases/tags endpoint 404s on drafts (why 9.5 uses the API list). PHPStan L5 clean; updater-hardening unit 37/37; all tests/*.unit.php green.
|
Warning Review limit reached
More reviews will be available in 34 minutes and 9 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough
ChangesUpdater fail-closed hardening
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
) - version.json -> 0.7.20.1 (maintenance release, no schema change; the highest migration stays migrate_0.7.20.sql, which is <= 0.7.20.1). - README: add "What's New in v0.7.20.1" (OpenLibrary cover fetch via SSRF-safe per-hop redirect + IP pinning #173; fail-closed updater patches + redirect-safe releases fetch #174). The version badge is dynamic and tracks version.json.
Follow-up to the PR #172 review. Each finding verified against current code; only still-valid ones fixed.
Fixed
applyPreUpdatePatchfail-open → fail-closed. A present, digest-verified pre-update patch that failed to stage (file_put_contents), parsed to a non-array, or threw mid-apply used to returnsuccess=true, letting the install proceed half/un-patched. Nowsuccess=false(the caller aborts; nothing committed yet). Consistent with the existinginvalidhandling.applyPostInstallPatchcatch surfaces errors. A runtime exception set only$errorbut leftsuccess=true, hiding it as “no patch applied”. Nowsuccess=false, so it surfaces through the caller’s non-fatal warning branch (core update is already done → stays a warning).fetchReleasesRawcURL branch redirect-safe. Primary + token-retry contexts now pinFOLLOWLOCATION=false/MAXREDIRS=0and gate success to 2xx, matchingmakeGitHubRequest. (Token was already protected byUNRESTRICTED_AUTH=false; this is defense-in-depth/consistency. Asset-download paths keepFOLLOWLOCATION=trueon purpose — github.com→CDN.)Skipped (with reason)
false→null— already addressed in earlier commits.gh release view <tag>(CLI) resolves drafts by tag_name (the 0.7.20 release passed those steps as a draft). Only the REST/releases/tagsendpoint 404s on drafts, which is exactly why STEP 9.5 uses the API list.Validation
PHPStan L5 clean ·
updater-hardeningunit 37/37 (+4 new fail-closed assertions) · alltests/*.unit.phpgreen.Summary by CodeRabbit
Note di Rilascio
Bug Fixes
Tests