Commit Graph

137 Commits

Author SHA1 Message Date
Robert Haines 1c06454985 Update minimum ruby version to 3.0.
All rubies before 3.0 are EOL and this is a major version bump, so it's
the right time to do this.
2024-03-01 22:14:48 +00:00
Robert Haines 2ffbfebb88 Document or hide classes from the docs. 2023-04-14 11:25:22 +01:00
Robert Haines 84087e5774 Ensure that entries can be extracted safely without path traversal.
This commit adds a parameter to the `File#extract` and `Entry#extract` methods
so that a base destination directory can be specified for extracting archives
in bulk to somewhere in the filesystem that isn't the current working
directory. This directory is `.` by default. It is combined with the entry
path - which shouldn't but could have relative directories (e.g. `..`) in it -
and tested for safety before extracting.

Resolves #540.
2023-04-14 11:15:24 +01:00
Robert Haines f460da3afb Prevent unnecessary Zip64 data being stored.
With Zip64 write support enabled by default, it's important that we
only store the extra data when we need to. This commit ensures that
the Zip64 extra data is included for an entry if its size is over
4GB, or if we don't know how big it will be at the point of writing
the local header data.

This commit also removes the need for the Zip64Placeholder extra
data field. Now we just use the Zip64 field itself and ensure it's
filled in correctly.
2023-01-03 20:19:40 +00:00
Robert Haines 750d372380 Rename DestinationFileExistsError -> DestinationExistsError.
And define the error message within the class.
2022-08-16 11:13:30 +01:00
Robert Haines e3f0aecf93 Define the EntryNameError message within the error class. 2022-08-16 10:52:18 +01:00
Robert Haines 07eca2bae8 Define the EntrySizeError message within the error class. 2022-08-15 22:02:33 +01:00
Robert Haines 19fe79e31e Define the SplitArchiveError message within the error class. 2022-08-14 22:23:51 +01:00
Robert Haines 08391da4d5 Ensure that `Entry.ftype` is correct via `InputStream`.
When reading an archive with `InputStream`, `Entry.ftype` was returning
`:file` for all entries, even if they were a directory. This is due to
various side-effects in many methods in `Entry`. This commit fixes the
behaviour, but not the side-effects.

Fixes #533.
2022-08-13 22:09:55 +01:00
Robert Haines 466383ff1a Add other `Entry` time methods and test them all. 2022-06-20 17:18:20 +01:00
Robert Haines fff1f8ea8a Add `Entry#mtime=` as an alias of `Entry#time=`. 2022-06-20 17:18:20 +01:00
Robert Haines 62ed397b1a Generalize `Entry#time=`.
So we can use it for `atime=`, `ctime=` and `utime=` as well.
2022-06-20 17:18:20 +01:00
Robert Haines d6482bd567 Generalize `Entry#time`.
So we can use it for `atime`, `ctime` and `utime` as well.
2022-06-20 17:18:20 +01:00
Robert Haines ae0262df2e Add `Entry#zip64?` as a better way detect Zip64 entries. 2022-06-20 17:18:20 +01:00
Robert Haines 307fc6c6e9 Mark other mutating methods in `Entry` as dirty.
Also, remove `Entry#extra=` as it makes no sense (and wasn't even being
tested).

And remove slightly odd test that was assuming an archive would not be
changed if its utime was changed - even if it was being changed back
immediately. This test was merely confirming that we weren't catching
timestamp changes correctly.
2022-06-20 17:18:20 +01:00
Robert Haines 33dce510a6 Remove `Entry#dirty=` as 'dirtyness' is now monitored internally.
Had to round out some of the accessors that mark an `Entry` as dirty.
2022-06-20 17:18:20 +01:00
Robert Haines 7b340d62a6 Abstract marking as dirty into `Dirtyable` for reuse. 2022-06-20 17:18:20 +01:00
Robert Haines 3002251048 Mark certain methods in `Entry` as making it dirty.
This allows us to track which entries have changed without keeping a
copy of all entries. I hope.
2022-06-20 17:18:19 +01:00
Robert Haines 78a3cc596f Make `Entry::zipfile` private.
No need for it to be public, and especially not writeable.
2022-06-20 17:18:19 +01:00
Robert Haines e0e754ae65 Switch how the `Entry::dirty` flag is used.
Set it to true by default - because a new `Entry` is dirty by
definition, having not been written yet. Then make sure that an `Entry`
that is created by reading from a zip file is set as not dirty.
2022-06-20 17:18:19 +01:00
Robert Haines 044759f502 Fix `OutputStream#put_next_entry` to preserve `StreamableStream`s.
When passing an `Entry` type to `File#get_output_stream` the entry is
used to create a `StreamableStream`, which preserves all the info in the
entry, such as timestamp, etc. But then in `put_next_entry` all that is
lost due to the test for `kind_of?(Entry)` which a `StreamableStream` is
not. See #503 for details.

This change tests for `StreamableStream`s in `put_next_entry` and uses
them directly. Some set-up within `Entry` needed to be made more robust
to cope with this, but otherwise it's a low impact change, which does
fix the problem.

The reason this case was being missed before is that the tests weren't
testing `get_output_stream` with an `Entry` object, so I have also added
that test too.

Fixes #503.
2022-01-20 19:29:40 +00:00
Robert Haines 765cb316f1 Fix reading unknown extra fields.
When loading extra fields from both the central directory and local headers,
unknown fields were not merged correctly. They were being appended, which
means that we end up with the two versions stuck together - in some
cases duplicating the field completely.

This broke all kinds of things (like calculating the size of a local
header) in subtle ways.

This commit fixes this by implementing a new `Unknown` extra field type,
and making sure that when reading local and central extra fields they
are stored and preserved correctly. We cannot assume the unknown fields
use the same data in the local and central headers.

Fixes #505.
2021-11-19 19:53:38 +00:00
Robert Haines 19e5f4a8ce Detect and raise GPFBit3Error in `InputStream.get_next_entry`.
We were previously trying to work out where the next entry would be,
even with GP bit 3 set, but the logic was flaky and cannot really be
correct given the data available. It's not expected behaviour, so raise
the error instead.

This means that we get rid of the incorrect `Entry.data_descriptor_size`
which was doing more harm than good.
2021-06-27 21:43:03 +01:00
Robert Haines aa646ef827 Use named params for `InputStream`. 2021-06-27 10:20:11 +01:00
Robert Haines e7f0aba5ff Fix Style/OptionalBooleanParameter cop in `Entry`.
Just an internal API so safe, and makes things a lot neater.
2021-06-27 10:20:11 +01:00
Robert Haines a301d68eeb Raise an error if entry names exceed 65,535 characters.
Fixes #247.
2021-06-26 19:21:07 +01:00
Robert Haines e000552deb Raise an error on reading a split archive with `InputStream`.
Fixes #349.
2021-06-26 12:39:08 +01:00
Robert Haines 193507b15a Adjust Layout/LineLength cop to 100 characters.
We'll get the line length down in stages...
2021-06-25 22:31:34 +01:00
Robert Haines 71f2c90b20 Test that a corrupted cdir entry is caught. 2021-06-18 12:08:31 +01:00
Robert Haines cd9a3fcad1 Move all the `read_zip_*` methods out of `Entry`.
They were only ever used in `CentralDirectory` anyway.
2021-06-10 17:29:00 +01:00
Robert Haines 2410f2889e Restore file timestamps on all platforms.
Was only being done on Unix-type filesystems for some reason. Moved code
so that it is run for all files, whatever the underlying platform.
2021-06-06 16:17:22 +01:00
Robert Haines 684b69f330 Move the restore options to the top level.
This will ensure consistency between `File` and `Entry`.
2021-06-06 16:17:22 +01:00
Robert Haines b705085b09 `Entry#name_safe?` now allows Windows drive mappings. 2021-06-06 14:44:20 +01:00
Robert Haines 22a54853e6 Reinstate normalising pathname separators to `/`.
But only do it after we have set filename encoding appropriately to
avoid breaking multibyte characters with `\`s in them.

Fixes #324.
2021-06-04 16:22:45 +01:00
Ariel Zelivansky f54e3b7f56 Fix improvement & fix NTFS 2021-05-30 10:28:27 +01:00
Ariel Zelivansky 01acd0488a Quick fix to prevent crash when mtime is nil 2021-05-30 10:28:27 +01:00
Robert Haines 530afe5d0c Fix Performance/BlockGivenWithExplicitBlock cop. 2021-05-25 21:24:50 +01:00
Robert Haines e10badf68e Fix Style/FrozenStringLiteralComment cop. 2021-05-25 21:24:50 +01:00
Robert Haines 8702876e55 Set the default `Entry` time to the file's mtime on Windows.
For some reason this was being skipped on Windows, but not Linux or
MacOS.
2021-05-18 21:59:54 +01:00
Robert Haines 34237efc00 Ensure that `Entry#time=` sets times as `DOSTime` objects.
Fixes #481.
2021-05-18 19:57:03 +01:00
Oleksandr Simonov 7f3bb29487
Merge pull request #464 from hainesr/remove_dosequals
Replace and deprecate `Zip::DOSTime#dos_equals`.
2021-05-03 10:22:13 +03:00
Oleksandr Simonov a0345420d8
Merge branch 'master' into compression_level 2021-02-14 14:26:12 +02:00
Robert Haines 5a4d1d8b6b Replace and deprecate `Zip::DOSTime#dos_equals`.
Having a specific 'does this instance equal another instance' method is
kind of annoying and breaks a number of things. Most obviously it breaks
comparing to `nil`: `nil.dos_equals(other)` will fail where
`nil == other` does not.

So this commit overrides `<=>` in `Zip::DOSTime` and deprecates
`dos_equals`.
2020-11-28 21:19:58 +00:00
Robert Haines f742994cf2 Abstract out reading extra fields in Entry.
Remove some (almost) duplicated code and get ready for the real fix.
2020-09-20 18:55:39 +01:00
Robert Haines f1dd724a3a Use constants for the compression level gp flags. 2020-08-31 17:48:08 +01:00
Robert Haines cf3f4339f6 Make sure that compression method is STORE for level 0.
Whatever the compression method that is set by the user, if the
compression level is set to 0 (no compression), then the entry should be
STORED. This mimics commandline tool behaviour and matches user
expectations.
2020-08-31 17:48:08 +01:00
Robert Haines 0620fba13d Don't use raw numbers for Entry compression types.
Constants for Store and Deflate are already available, so use them. It
might be sensible to remove these local versions, but they do have their
uses as a shortened form.
2020-08-31 17:48:08 +01:00
Robert Haines 156b0f3dee Tidy up accessors in `Entry`.
Remove a load of accessors from the 'public' API by not documenting
them, and remove access to `header_signature` completely.

Also, `Entry#extra` has been created to allow extra fields to be set
correctly after initialization.
2020-08-31 17:48:08 +01:00
Robert Haines e4ceedaa58 Use keyword arguments for the `Entry` initializer.
This greatly simplifies the creation of `Entry` objects when only a
couple of fields are not set to their defaults, while at the same time
allowing an `Entry` to be fully configured at creation time if
appropriate.

This fundamentally changes the `Entry` API and  means that some
convenience methods in `OutputStream` and `File` have needed to be
refactored.
2020-08-31 17:48:08 +01:00
Robert Haines 2775f529b4 Set the compression level general purpose flags. 2020-08-31 17:48:08 +01:00