forked from rubyzip/rubyzip
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 rubyzip#505.
- Loading branch information
Showing
8 changed files
with
139 additions
and
33 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# frozen_string_literal: true | ||
|
||
module Zip | ||
# A class to hold unknown extra fields so that they are preserved. | ||
class ExtraField::Unknown | ||
def initialize | ||
@local_bin = +'' | ||
@cdir_bin = +'' | ||
end | ||
|
||
def merge(binstr, local: false) | ||
return if binstr.empty? | ||
|
||
if local | ||
@local_bin << binstr | ||
else | ||
@cdir_bin << binstr | ||
end | ||
end | ||
|
||
def to_local_bin | ||
@local_bin | ||
end | ||
|
||
def to_c_dir_bin | ||
@cdir_bin | ||
end | ||
|
||
def ==(other) | ||
@local_bin == other.to_local_bin && @cdir_bin == other.to_c_dir_bin | ||
end | ||
end | ||
end |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'test_helper' | ||
|
||
class ZipExtraFieldUnknownTest < MiniTest::Test | ||
def test_new | ||
extra = ::Zip::ExtraField::Unknown.new | ||
assert_empty(extra.to_c_dir_bin) | ||
assert_empty(extra.to_local_bin) | ||
end | ||
|
||
def test_merge_cdir_then_local | ||
extra = ::Zip::ExtraField::Unknown.new | ||
field = "ux\v\x00\x01\x04\xF6\x01\x00\x00\x04\x14\x00\x00\x00" | ||
|
||
extra.merge(field) | ||
assert_empty(extra.to_local_bin) | ||
assert_equal(field, extra.to_c_dir_bin) | ||
|
||
extra.merge(field, local: true) | ||
assert_equal(field, extra.to_local_bin) | ||
assert_equal(field, extra.to_c_dir_bin) | ||
end | ||
|
||
def test_merge_local_only | ||
extra = ::Zip::ExtraField::Unknown.new | ||
field = "ux\v\x00\x01\x04\xF6\x01\x00\x00\x04\x14\x00\x00\x00" | ||
|
||
extra.merge(field, local: true) | ||
assert_equal(field, extra.to_local_bin) | ||
assert_empty(extra.to_c_dir_bin) | ||
end | ||
|
||
def test_equality | ||
extra1 = ::Zip::ExtraField::Unknown.new | ||
extra2 = ::Zip::ExtraField::Unknown.new | ||
assert_equal(extra1, extra2) | ||
|
||
extra1.merge("ux\v\x00\x01\x04\xF6\x01\x00\x00\x04\x14\x00\x00\x00") | ||
refute_equal(extra1, extra2) | ||
|
||
extra2.merge("ux\v\x00\x01\x04\xF6\x01\x00\x00\x04\x14\x00\x00\x00") | ||
assert_equal(extra1, extra2) | ||
|
||
extra1.merge('foo', local: true) | ||
refute_equal(extra1, extra2) | ||
|
||
extra2.merge('foo', local: true) | ||
assert_equal(extra1, extra2) | ||
end | ||
end |
This file contains 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