Don't silently alter zip files opened with `Zip::sort_entries`.

Fixes #329.
This commit is contained in:
Robert Haines 2021-06-30 23:18:59 +01:00
parent 322955c6b4
commit 54b7762c8f
4 changed files with 20 additions and 7 deletions

View File

@ -1,5 +1,6 @@
# 3.0.0 (Next)
- Don't silently alter zip files opened with `Zip::sort_entries`. [#329](https://github.com/rubyzip/rubyzip/issues/329)
- Use named parameters for optional arguments in the public API.
- Raise an error if entry names exceed 65,535 characters. [#247](https://github.com/rubyzip/rubyzip/issues/247)
- Remove the `ZipXError` v1 legacy classes.

View File

@ -132,9 +132,9 @@ class ZipFileGenerator
end
```
### Save zip archive entries in sorted by name state
### Save zip archive entries sorted by name
To save zip archives in sorted order like below, you need to set `::Zip.sort_entries` to `true`
To save zip archives with their entries sorted by name (see below), set `::Zip.sort_entries` to `true`
```
Vegetable/
@ -148,7 +148,7 @@ fruit/mango
fruit/orange
```
After this, entries in the zip archive will be saved in ordered state.
Opening an existing zip file with this option set will not change the order of the entries automatically. Altering the zip file - adding an entry, renaming an entry, adding or changing the archive comment, etc - will cause the ordering to be applied when closing the file.
### Default permissions of zip archives

View File

@ -35,10 +35,8 @@ module Zip
entry if @entry_set.delete(to_key(entry))
end
def each
@entry_set = sorted_entries.dup.each do |_, value|
yield(value)
end
def each(&block)
entries.each(&block)
end
def entries

View File

@ -62,9 +62,15 @@ class ZipEntrySetTest < MiniTest::Test
count = 0
@zip_entry_set.each do |entry|
assert(ZIP_ENTRIES.include?(entry))
refute(entry.dirty)
entry.dirty = true # Check that entries can be changed in this block.
count += 1
end
assert_equal(ZIP_ENTRIES.size, count)
@zip_entry_set.each do |entry|
assert(entry.dirty)
end
end
def test_entries
@ -101,6 +107,14 @@ class ZipEntrySetTest < MiniTest::Test
arr << entry
end
assert_equal(ZIP_ENTRIES.sort, arr)
# Ensure `each` above hasn't permanently altered the ordering.
::Zip.sort_entries = false
arr = []
@zip_entry_set.each do |entry|
arr << entry
end
assert_equal(ZIP_ENTRIES, arr)
end
def test_compound