Skip to content

#349: Fix IO leak and retry with empty body in durable_place#386

Closed
VasilevNStas wants to merge 1 commit into
zerocracy:masterfrom
VasilevNStas:349
Closed

#349: Fix IO leak and retry with empty body in durable_place#386
VasilevNStas wants to merge 1 commit into
zerocracy:masterfrom
VasilevNStas:349

Conversation

@VasilevNStas

Copy link
Copy Markdown
Contributor

Problem

durable_place passed File.open(file, rb) IO directly into the POST params without closing it (IO leak). On retry, the IO was at EOF so the retry posted an empty body while the server still returned a DurableId.

Solution

  • Open file in block form, read content into a string, auto-close
  • Pass string content instead of IO → retries send the full body
  • Added regression test verifying retry works

This also eliminates the TOCTOU window between File.exist?/File.size checks and File.open for reading — the file is opened once, validated, read, and closed atomically.

Verification

  • bundle exec rubocop — 0 offenses
  • All tests pass (46 edge tests, 133 assertions)
  • New test test_durable_place_sends_body_on_retry confirms retry succeeds

Closes #349.

@VasilevNStas

Copy link
Copy Markdown
Contributor Author

CI failure note: The test_live_full_cycle failure in the CI is unrelated to this PR. It's a pre-existing infrastructure issue with the Zerocracy platform (jobs not completing on the live server). See issue #354 for details and discussion.

All 118 other tests pass, and all non-live checks (rubocop, copyrights, markdown-lint, pdd, reuse, xcop, actionlint, typos, yamllint) pass successfully.

@GHX5T-SOL GHX5T-SOL left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes because the current head no longer uploads zip as a file. It reads the durable into a String and passes that as the zip parameter; the PR's hosted Ubuntu rake then fails test_live_durable_lock_unlock at POST https://api.zerocracy.com/durable-place with Flash: A file must be uploaded / Failure: A file must be uploaded. The same-window master rake run passed test_live_durable_lock_unlock and only failed the known test_live_full_cycle stuck-job case, so this is not just the existing live full-cycle noise.

I also ran a no-network WebMock probe locally: the PR sends decoded zip=hello, world! on both attempts, but as a normal form field. The same probe with the old IO-based implementation still returns success under the new test stub, because test_durable_place_sends_body_on_retry only counts two POSTs and never inspects the uploaded zip part/body. Please keep zip as a file upload object while fixing the close/retry behavior, and make the regression assert that the retried request carries the file payload rather than only that a second POST happened.

Comment thread lib/baza-rb.rb Outdated
'pname' => pname,
'file' => File.basename(file),
'zip' => File.open(file, 'rb')
'zip' => content

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes zip from a file upload into a plain String form field. The PR's hosted Ubuntu rake fails test_live_durable_lock_unlock with A file must be uploaded, while the same-window master run passed that live test. The fix needs to preserve a file upload here while closing/reopening it safely.

@VasilevNStas

Copy link
Copy Markdown
Contributor Author

Closing in favor of #385 (branch 357), which solves the same file-descriptor lifetime issue with a more idiomatic block-based approach. Both PRs touch the same area in durable_place: #385 opens the file in a File.open block, passes the fd directly into post, and lets the block ensure cleanup — avoiding the conflict and keeping the fix simpler. The TOCTOU test requested by GHX5T-SOL (test_durable_place_rejects_symlink_to_non_regular_file) was added to branch 357.

@0crat

0crat commented Jun 10, 2026

Copy link
Copy Markdown

@GHX5T-SOL Great work on the review! 🎉 You've earned +13 points (+18 base, -5 for limited comments). Your total score is now +1287 - keep up the momentum and remember to check your Zerocracy account for updates!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BazaRb#durable_place leaks the IO opened for the 'zip' field and posts an empty body on retry

3 participants