Disable rubyzip zip64 so Word can open generated court reports - #7098
Merged
Conversation
rubyzip 3 flipped write_zip64_support to true by default (it was false in 2.x), and the caxlsx bump floated us from rubyzip 2.4.1 to 3.x in April. Sablon builds reports with Zip::OutputStream.write_buffer, which streams entries without knowing their sizes up front, so with zip64 on every entry was written with version-needed 45 and 0xFFFFFFFF size placeholders. Word rejects zip64 OOXML packages outright — "The file isn't in the correct format" — while unzip, rubyzip and the docx gem all read them happily. That is why the whole suite stayed green while production handed users unopenable files, across every org and template. Confirmed against production: the blob downloads byte-for-byte intact, and its first entry header reads 2d 00 ... ff ff ff ff ff ff ff ff. Nothing was corrupt in transit; the file was written as zip64 at generation. Add a guard asserting version-needed 20 and real entry sizes, since every content-level assertion we have passes on a zip64 package. Refs #7093 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What github issue is this PR for, if any?
Refs #7093
What changed, and why?
Generated court reports download fine and then Word refuses them:
Root cause: the reports are being written as zip64.
rubyzip 3 flipped
write_zip64_supporttotrueby default — it wasfalsein 2.x — and the caxlsx bump in e310472 (2026-04-13) floated us from rubyzip 2.4.1 to 3.x. Sablon builds reports withZip::OutputStream.write_buffer, which streams entries without knowing their sizes up front, so with zip64 enabled every entry gets written with version-needed 45 and0xFFFFFFFFsize placeholders.Microsoft Word rejects zip64 OOXML packages outright.
unzip, rubyzip and thedocxgem all read them happily, which is exactly why nothing caught it.Confirmed against production — the blob is byte-for-byte intact coming out of Azure, and it is zip64 at rest:
Nothing corrupts in transit. The file is written wrong at generation.
Zip.write_zip64_support = falserestores the pre-April behaviour. Before / after on the same template:which matches how Word itself writes the template (
1400).The setting is global rather than scoped to sablon because caxlsx has the same exposure — Excel dislikes zip64 for the same reason Word does. The tradeoff is no archives over 4GB or past 65,535 entries; court reports and spreadsheet exports are nowhere near either.
Note for whoever deploys: every court report already sitting in Azure was written as zip64 and stays unopenable. Users have to re-generate. Nothing to backfill — the next generate overwrites.
How is this tested? (please write rspec and jest tests!) 💖💪
Added a
zip container formatguard tospec/models/case_court_report_spec.rbasserting version-needed 20 and real entry sizes. Every existing assertion in that file inspects content via the docx gem, which parses zip64 without complaint — so a container-level assertion is the only kind that catches this.Verified the guard actually fails on the defect, by removing the initializer and re-running:
Full runs, green:
I also ran all six shipped templates through sablon and validated each output — valid zip, no duplicate entries, every XML part passing strict Nokogiri parsing — to rule out the package being malformed in some other way first.
Screenshots please :)
No UI change. The visible difference is Word opening the file instead of refusing it.