Commit graph

264 commits

Author SHA1 Message Date
Elliott Hughes
6f5913511c Fix unzip formatting.
Test: toybox tests, plus the ziptool tests
Change-Id: I31fd36c1bdb015b7b5062b53874143eb28b20d24
2020-04-17 16:07:01 -07:00
Tianjie
426bf3a1f1 Handle the invalid timestamp in zipfile
The month field is one based in the zipfile modification time. And
it causes an overflow converting it to struct tm. Switch to type to
signed integer to suppress the sub-overflow.

Bug: 153882979
Test: parse the problematic zipfile
Change-Id: Iaf47bcc7f83d61b18c9e7a98bb6ab3936c9257e3
2020-04-15 16:32:42 -07:00
Tianjie
d9bc8fd639 Fix the boundary check when parsing sizes in zip64 extended field
We should check if the data to read resides within the boundary of
the extended field. Also check OOB when reading bytes from the
zipfile.

Bug: 153828925
Test: parse the poc with hwasan build
Change-Id: I54b58a287b9ae4ca0e5cc563086c1ed8051fb72a
2020-04-14 11:26:42 -07:00
Yurii Zubrytskyi
8d8f637ee5 [zip] Stop calculating crc if it's not checked
Crc calculation shows up in the profiler in 2-5% range, and is
never currently validated. Let's disable it for good.
For a well-compressible test data the difference is even nicer:

Benchmark                       Time          CPU        Iteration
------------------------------------------------------------------
ziparchive-benchmarks:
before:
  #ExtractEntry/2            1943244 ns    1926758 ns          375
  #ExtractEntry/16           1877295 ns    1867049 ns          375
  #ExtractEntry/1024         1888772 ns    1879976 ns          373
after:
  #ExtractEntry/2             817003 ns     812870 ns          874
  #ExtractEntry/16            814029 ns     809813 ns          875
  #ExtractEntry/1024          804904 ns     800972 ns          879

Bug: 153392568
Test: atest, manual
Change-Id: I917abecab01301f1d09a5bf3b542d24b3875e359
2020-04-08 13:55:54 -07:00
Tianjie
088c403e23 Allow ExtractToMemory to accept an empty buffer for empty entries
We don't actually need to extract the empty entries. Since the old
code support extracting the empty entry to a empty buffer, add the
support back in ExtractToMemory.

Bug: 153393683
Test: unittests pass

Change-Id: Idb9f0f4e6e4ffd4b44b80ddd3f54069bb7cedd7b
2020-04-07 12:25:16 -07:00
Tianjie
85c5d23100 Allow parsing zip entries larger than 4GiB
This cl supports the parsing and extraction of the zip entry who
has a large size than UINT32_MAX. Also add a few checks in the
entry writers to make sure callers have enough space for extraction.

As many users of the library assume the entry size to be 32 bits long,
we keep the 32 bit ZipEntry. We also keep the functions that expect
the 32 bit ZipEntry in the public header file. These 32 bit wrappers
could be removed later once all users recognize the 64 bit ZipEntry.

Bug: 150900468
Test: unit tests pass
Change-Id: Ia6760638ccf51e97dbef6bd55dff352f1e7ce816
2020-04-03 12:46:20 -07:00
Tianjie
0ec0eaa214 Support parsing of data descriptor
The size fields in the data descriptor can be either 4 bytes or 8 bytes.
This depends on if the size are read from the zip64 extended field in
the local file header. This cl adds support to parse these cases.

Also fix a misconception in that the uncompressed and compressed size
doesn't need to exist together in the zip64 fields of the central
directory. But they still need to co-exist in the fields of the local
file header.

Bug: 150900468
Test: unit tests pass, python tests pass
Change-Id: Ia54f9bf56c85ff456ead90a136f7fddc5be5220c
2020-03-31 12:01:12 -07:00
Tianjie
173aba03f7 Fix integrity check when parsing zip64 eocd
The old check has some missing cases and may lead to read OOB.

Bug: 152433916
Test: unit tests pass
Change-Id: I3e8705b9c2db081228c5f9bd191c133668376ff2
2020-03-28 21:31:56 -07:00
Tianjie Xu
19c5cc224f Merge "Implement the functions to parse zip64 structs" 2020-03-25 00:21:46 +00:00
Tianjie
6ab29129ec Implement the functions to parse zip64 structs
Implement the logic to parse zip64 eocd and zip64 extended info
in the extra field. Also add unit tests and python tests which
create packages larger than 4GiB.

The extraction of zip entry size > 4GiB will be supported in the follow
ups.

Bug: 150900468
Test: unit tests pass
Change-Id: I4cd9ebbd9709b3d2f9cd293625d2c79024bb45a5
2020-03-24 15:06:57 -07:00
Songchun Fan
c33f5260ea [libziparchive] add an option to start iteration with functor
To reduce the seeks for local file headers in large APK files, we can
specify entry prefix/suffix when we call StartIteration(). However,
some use cases need additional name matches that is outside the
prefix/suffix matches.

Adding a new option to StartIteration, which allows additional functor
that restricts the iteration to customized name matching schemes.

Test: atest ziparchive-tests
BUG: 151676293
Change-Id: Iff45e083b334602f183c05cb39ba521e7070252c
2020-03-24 10:16:49 -07:00
Tianjie Xu
69ee4b70c8 Add definition for zip64 struct
Add the definition of zip64 related structs. Also add place holders in
the zip parsing code. In addition, this cl changes the variable type of
num of entries to uint64_t. The number was capped at UINT16_MAX in zip32
format.

Bug: 150900468
Test: unit tests pass
Change-Id: I51a39e7b993fa376e0d050a04b8d39abae8a9e15
2020-03-20 22:23:57 -07:00
Ryan Mitchell
23150e4fe4 Allow loading zip at an offset in fd
To allow the ResourcesLoader API to load part of a file as an APK
that contains resources, an additional override of OpenArchiveFd
that contains read offset and length as parameters must be created.

This functionality allows for an APK stored in a zip file to be read
without having to write the APK to disk.

Bug: 142716192
Test: atest FrameworksResourceLoaderTests
Change-Id: I772fc8b462d71de0529717c420ced552103a6e3f
Merged-In: I772fc8b462d71de0529717c420ced552103a6e3f
2020-03-18 20:46:50 +00:00
Elliott Hughes
bda268636a libziparchive: move the array of error strings into the implementation.
Test: treehugger
Change-Id: Iaffc29f77912d268c3335b74eb712a58914ce945
2020-03-17 14:10:59 -07:00
Tianjie Xu
323c09c3d0 Move the implementation of cd entry map to a separate file
Move the entry map classes to a separate file to make the hierarchy
clear.

Test: unittests pass
Change-Id: Ie01d7835359daa4f59af75a0eda204c696d5658e
2020-03-16 17:43:49 -07:00
Tianjie Xu
0ef9783c57 Add std::map implementation for cd entry map
Add the std::map implementation to be used later in zip64 format.
Also move the entry map classes to a separate file to make the hierarchy
clear.

Test: unittests pass
Change-Id: I74d95f53207cc8ca871b955e2a15c184d5497833
2020-03-16 15:42:22 -07:00
Tianjie Xu
28f8eaeffb Create an interface for the cd entry hash table
The current implementation of the hashtable uses less memory than
a std::map. As most of the zip files we encountered don't use the zip64
extension, we should keep the current implementation. And the interface
adds the flexibility for us to switch to std::map for zip64 format.

Bug: 150900468
Test: unit tests pass
Change-Id: Ifd008785c9ff416a27049f9e0c54d9eef985bd85
2020-03-10 11:51:53 -07:00
Elliott Hughes
264a37d12f Merge "Fix SEGV in libziparchive with malformed zip file." 2019-12-18 16:14:54 +00:00
Elliott Hughes
fba2a1a1ec Fix SEGV in libziparchive with malformed zip file.
d77c99ebc3 changed MappedFile to return a
bogus zero-length mapping on failure rather than nullptr. None of the
calling code was changed, though, and it seems like doing so would be a
bad idea. Revert that part of the change.

Add missing tests, and tidy up some of the logging. Also remove
single-use or obfuscatory constants from the tests.

The new "empty.zip" was created by using zip(1) to create a zip file
with one entry, then using `zip -d` to remove it.

The new "zero-size-cd.zip" was created by using zip(1) to create a zip
file containing a single empty file, and then hex editing the two byte
"size of the central directory" field in the "end of central directory
record" structure at the end of the file. (This is equivalent to, but
much smaller than, the example zip file provided by the bug reporter.)

Bug: http://b/145925341
Test: treehugger
Change-Id: Iff64673bce7dae886ccbc9dd6c2bbe18de19f9d2
2019-12-17 08:39:09 -08:00
Elliott Hughes
8748bcc650 Rename unzip.cpp to ziptool.cpp.
It contains unzip and zipinfo, and will likely contain zip too soon.

Test: builds
Change-Id: I017df302108847f29bfdd120f20bf0fd3b9caa5b
2019-12-13 16:47:22 -08:00
Elliott Hughes
f276140d0f cli-test: a tool for testing command-line programs.
Not looking for other users right now, this is just enough to test
unzip/zip/zipinfo.

This includes tests for unzip and ziptool, along with a change to
unzip's behavior to fix AOSP `make dist` when using ziptool unzip.

Also add the boilerplate to run these tests on the device, in presubmit.

Fix command name in --help output.

Test: atest ziptool-tests
Change-Id: I5c0215a3ab8cb2cd5fc517ed9c188f81a7bf4520
2019-12-13 12:23:51 -08:00
Elliott Hughes
2ab5a70b9f ziptool: fix unknown long options.
Previously an unknown long option would cause a crash as we ran off the
end of the array.

Test: `ziptool unzip --unknown`
Change-Id: I7a7b6ac4a0fa157c111f936e837c20143cef9e28
2019-11-16 11:18:50 -08:00
Nick Desaulniers
4e7507ffc2 libziparchive: fix -Wimplicit-int-float-conversion
The value of uncompressed may not be precisely representable when
implicitly casted to an IEEE 754 single precision float.

Assuming the code doesn't need a precise compression ratio, accept the
potential imprecision via explicit cast.

system/core/libziparchive/unzip.cpp:114:68: error: implicit conversion
from 'int64_t' (aka 'long') to 'float' may lose precision
[-Werror,-Wimplicit-int-float-conversion]
  return static_cast<float>(100LL * (uncompressed - compressed)) / uncompressed;
                                                                 ~ ^~~~~~~~~~~~

Change-Id: If46cfa4eb2bb16a7491e52bb5d1c212ed5d59079
Bug: 139945549
Test: lunch hikey960-userdebug && mm
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
2019-11-13 13:04:22 -08:00
Elliott Hughes
008759711f unzip/zipinfo: use float percentages like the RI.
Test: my new test runner, specifically developed for ziptool
Change-Id: I1237d02daaf2939eebc4fd5ec19ccdd0de291ad5
2019-11-12 13:53:43 -08:00
Treehugger Robot
16366e36d5 Merge "ziparchive: add a corpus for the fuzzer." 2019-11-08 16:22:41 +00:00
Elliott Hughes
9e63ba787d ziparchive: add a corpus for the fuzzer.
Reuse the existing test data.

Test: ran fuzzer on host, saw a lot more log spam
Change-Id: If57e4b8708832d7296b118e6926d41951d4a3ca9
2019-11-07 14:24:04 -08:00
Elliott Hughes
f1b255a6ad Darwin: include <libgen.h> for basename(3).
Test: treehugger
Change-Id: I11858430f13cbb22895c9dd0befb8054308efb19
2019-11-04 19:27:33 -08:00
Elliott Hughes
bcd810622b unzip: fix Mac build.
Turns out the Mac doesn't have <error.h>. Add our own "die" function
instead, and use it everywhere so the Mac isn't using an untested
codepath.

One upside to this is that we'll now call ourselves "unzip" even when
run as `ziptool unzip ...`, which was awkward to fix with <error.h> but
trivial if we're rolling our own anyway.

Test: still works on Linux
Change-Id: I9cb1922595a21cd9f6d55a70d67e30090f8b7f21
2019-11-03 08:30:33 -08:00
Elliott Hughes
d3aee6653f unzip: add -Z for "zipinfo mode".
But don't document it because it's a silly idea. Just call zipinfo
directly if you want zipinfo!

There are multiple uses of `unzip -Z` in the AOSP build, though, so we
may as well support it if people are already using it.

Test: manual
Change-Id: I04b05795badf63febe1210fbeaa96e3bd27237f1
2019-10-29 20:47:16 -07:00
Elliott Hughes
d50952587d zipinfo: support DOS attributes.
golang doesn't include Unix mode by default.

Also show all the deflate variants ("defN" versus "defX").

Cope better with being called directly rather than via symlink.

Test: manual
Change-Id: I23b441c847ce9a557ea866b3c43bdf0542b26f10
2019-10-29 07:55:16 -07:00
Elliott Hughes
2672413d91 libziparchive: add zipinfo(1).
Useful for debugging and hermetic builds. (Various places in the build
check to see that a file was stored uncompressed.)

Test: manual
Change-Id: I127e5689cd493ab06739b765beed50912dc9cc1d
2019-10-25 10:07:08 -07:00
Elliott Hughes
f66460b92a libziparchive: add trivial fuzzer.
Didn't find anything when I ran it, but it did get me to fix the
const/non-const void* in the API.

Test: treehugger
Change-Id: If3849d974965e3e5ffcbdaf5e47921316d717410
2019-10-22 11:45:49 -07:00
Donald Chai
e170d7fe85 Avoid using data descriptors in ZIP files when possible.
These add 16 bytes per ZIP entry, and are usually avoidable.  APKs contain thousands of
deflated entries, so this overhead adds up to tens of kilobytes.

Bug: 135470635
Change-Id: Ib928aa41dd55cacc41f7394c218c4340d3bbd570
2019-07-23 06:58:53 +00:00
Elliott Hughes
2226fe6ddf Merge "Finally remove ZipString." 2019-06-20 19:20:39 +00:00
Elliott Hughes
50ef29a170 Finally remove ZipString.
Bug: http://b/129068177
Test: treehugger
Change-Id: If8c009f96931c9c2672255d8d0fe01d7992282af
2019-06-19 15:26:38 -07:00
Yurii Zubrytskyi
a6633d7739 [zip] Save 1 malloc and memset for each added file in ZipWriter
+ add a benchmark for the function.

This change speeds up the function by about 3%: 910ns->880ns

Change-Id: I33c8c31de18d10eb38f109917ecbcbdda45b4034
2019-06-18 21:49:16 -07:00
Yurii Zubrytskyi
2b283118a0 [zip] Change const char* to string_view in ZipWriter
This would allow adding entries from one zip archive into
a new one without copying, directly from a ZipString object

Change-Id: I52f91008f497e798e044c43f57a6481cf4bec36d
2019-06-18 21:00:43 -07:00
Elliott Hughes
1e40c30b0c ziparchive: add a std::string_view overload to Next.
Recovery wanted this, and frameworks/base/ wants it too.

Bug: http://b/129068177
Test: treehugger
Change-Id: I8ee3f7c058fc9c1cde829da613ed15be5ce7b41e
2019-06-12 12:12:47 -07:00
Elliott Hughes
e06a808037 Add a std::string overload to Next.
All but one existing caller actually wants a std::string.

Bug: http://b/129068177
Test: treehugger
Change-Id: I428c4453edaae74451db56e9542e4e462f08d43a
2019-05-22 19:05:44 -07:00
Elliott Hughes
13a45c01f2 libziparchive: remove now-unused StartIteration overload.
Bug: http://b/129068177
Test: treehugger
Change-Id: If494c3031aee2bd3e72eda57de4c334f11f5a5df
2019-05-10 15:00:37 -07:00
Elliott Hughes
a22ac0f07e libziparchive: start moving to a non-ZipString StartIteration API.
Same issue as with FindEntry: using ZipString in the API forces all
callers to make sure they don't hit the ZipString length limits. Switch
to std::string_view and uniformly use the empty string as a way to
signal no prefix/suffix rather than nullptr.

Also use default arguments to make the common case of no prefix and no
suffix more convenient.

Also just use std::string to increase the lifetime of the provided
prefix/suffix rather than manual memory management.

Bug: http://b/129068177
Test: treehugger
Change-Id: I6675e39ce62fadd766386d77d27423013c17d6f7
2019-05-08 11:00:32 -07:00
Elliott Hughes
1d5745fb40 Merge "libziparchive: remove now-unused FindEntry overload." 2019-05-08 17:05:46 +00:00
Dimitry Ivanov
9a45f8ff4c Merge "Enable native_bridge_support" 2019-05-07 21:47:41 +00:00
Elliott Hughes
a5ff19e7e9 libziparchive: remove now-unused FindEntry overload.
Bug: http://b/129068177
Test: treehugger
Change-Id: I53da90bb61b0299aca545f9a1420f64e3f909657
2019-05-07 09:27:59 -07:00
dimitry
a808b1150a Enable native_bridge_support
Enable native bridge support for libbase, liblog,
libziparchive and libpropertyinfoparser.

This makes it possible to use them in binaries for translated
architectures.

Bug: http://b/77159578
Test: make
Change-Id: If67ce92288b17a052ea1e79a268e284f7d941439
2019-05-06 14:05:05 +02:00
Elliott Hughes
b17bf521d5 libziparchive: report errors on over-long names.
Switch FindEntry and the ZipString constructor to std::string_view. This
lets us accept an over-long name so that we can reject it as too long.

Also fastboot changes to track the API change.

Bug: http://b/129068177
Test: treehugger
Change-Id: I7df7acd1fe2c46380b789c25f8909e0553e2d55e
2019-05-04 08:41:12 -07:00
Treehugger Robot
5664489a31 Merge "Ziparchive: Enable -Wconversion" 2019-04-19 03:33:19 +00:00
Elliott Hughes
5f8b309883 unzip: support shell globs in include/exclude lists.
Bug: http://b/113928508
Test: manual
Change-Id: Ic9b11486ce07bf3b385e0c1180c4d1bde61d1628
2019-04-08 12:46:56 -07:00
Nick Kralevich
ba80ab1373 Merge "zip_archive.cc: Use static cast instead of masking" 2019-04-08 16:23:51 +00:00
Andreas Gampe
964b95cf61 Ziparchive: Enable -Wconversion
Enable -Wconversion (but not -Wsign-conversion). Fix up code. Handle
some actual error cases:

* too many files
* files too large

Bug: 130039052
Test: atest ziparchive-tests
Change-Id: I632af317b9e65dbc728851efefd0d11a2b5c29b9
2019-04-05 13:50:48 -07:00