Ref: https://bugs.ruby-lang.org/issues/20205
This patch will suppress the "literal string will be frozen in the
future" warning on the 2.4 branch.
Steps to reproduce
---
Run the following commands with ruby 3.4.0preview1:
```console
$ cd /tmp
$ git clone git@github.com:rubyzip/rubyzip.git
$ cd rubyzip
$ git switch 2.4
$ bundle install
$ ruby -I lib -W:deprecated -e '
require "zip"
Zip::File.open("test/data/ntfs.zip") do |zip_file|
zip_file.each do |entry|
puts entry.get_input_stream.read
end
end
'
```
Expected result
---
```console
ntfs test
```
Actual result
---
```console
/private/tmp/rubyzip/lib/zip/extra_field/ntfs.rb:54: warning: literal string will be frozen in the future
ntfs test
```
Environment
---
```console
$ ruby -v
ruby 3.4.0preview1 (2024-05-16 master 9d69619623) [x86_64-darwin23]
```
Ref: https://bugs.ruby-lang.org/issues/20205
In Ruby 3.4 string literals will be "chilled" by default. Meaning
they are still mutable, but will pretend to be frozen.
In most case it has no impact, just emit a few warnings there and
there, but there is one thing it impacts is the `StringIO.new('')`
pattern. `StringIO` checks if the given string is frozen, and if
it is will act as a read only IO.
This breaks rubyzip 2.x.
This commit make the 2.x branch compatible with frozen string literals.
From the documentation: "...times that are present will appear in the
order indicated, but any combination of times may be omitted. (Creation
time may be present without access time, for example.)"
This fixes the parsing so that the times are read into the correct
fields, according to the flags. Before they were simply assumed to be in
order and all present.
From the documentation: "The time values are in standard Unix signed-long
format, indicating the number of seconds since 1 January 1970 00:00:00."
The three time values were being unpacked with 'VVV', which is unsigned
32-bit, but they should be unpacked with 'l<l<l<': signed-long little
endian.
This commit adds the capability of creating archives larger than
4GB via zip64 extensions. It also fixes bugs reading archives of
this size (specifically, the 64-bit offset of the local file
header was not being read from the central directory entry).
To maximize compatibility, zip64 extensions are used only when
required. Unfortunately, at the time we write a local file header,
we don't know the size of the file and thus whether a Zip64
Extended Information Extra Field will be required. Therefore
this commit writes a 'placeholder' extra field to reserve space
for the zip64 entry, which will be written if necessary when
we update the local entry with the final sizes and CRC. I use
the signature "\x99\x99" for this field, following the example
of DotNetZip which does the same.
This commit also adds a rake task, zip64_full_test, which
fully tests zip64 by actually creating and verifying a 4GB zip
file. Please note, however, that this test requires UnZip
version 6.00 or newer, which may not be supplied by your OS.
This test doesn't run along with the main unit tests because
it takes a few minutes to complete.