Commit graph

405 commits

Author SHA1 Message Date
Baligh Uddin
28d0f1a3af Migrate system/core/base to system/libbase.
Add Symlink to ensure hardcoded references do not break build.
BUG: 148941208
test: TH

Change-Id: Ia2b69de1af6e07be2aab3ba4fe1493de80269c40
Merged-In: I1134f1e9e968b9273748e2483bea8d25e5c9e994
2020-05-19 21:32:42 +00:00
Josh Gao
3dc6710974 base: delete abi compatibility shims.
It's been a year, so references to these in master's vendor blobs
should be gone by now.

Test: treehugger
Change-Id: I090145e69f82e7ee78d66b0b92141bda56250837
2020-05-18 14:07:36 -07:00
Elliott Hughes
8c253d4d42 Avoid zero-initializing our most-used buffers.
The StringPrintf one is heavily used and brings the overhead versus
fmtlib down to 1.5x rather than 2x. I don't have a convenient benchmark
for the other two.

Test: libbase tests & benchmarks
Bug: http://b/155324241
Change-Id: I9e704a360846d5520c53f668e7c315b0c0ea55f8
2020-04-29 14:10:12 -07:00
Jooyung Han
8c2056f747 Merge "libbase/liblog: set min_sdk_version" 2020-04-27 23:00:58 +00:00
Tom Cherry
91fd50c78f Merge "base: reimagine line splitting in logger.cpp" 2020-04-27 16:03:46 +00:00
Maciej Żenczykowski
57d2fa4e52 result.h - fix bugprone-suspicious-semicolon warning
Fixes:
  system/core/base/include/android-base/result.h:
  133:94: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]

Bernie says:
  it probably means that there's a parser bug with "if constexpr"

  maybe, at static analysis pass, the "if constexpr" was evaluated to false,
  and the compiler removed the "then" block from the AST...
  ... and then it thought you had written it that way :-)
  https://reviews.llvm.org/D46027

Test: builds
Bug: 153035880
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I25df8eeca4ec06b3180c1cd21b554fc583c5581a
2020-04-24 11:28:06 -07:00
Maciej Żenczykowski
dc12124aba expected.h - fix bugprone-forwarding-reference-overload warnings
Fixes:
  system/core/base/include/android-base/expected.h:
  186:13: warning: constructor accepting a forwarding reference can hide the copy and move constructors [bugprone-forwarding-reference-overload]
  195:22: warning: constructor accepting a forwarding reference can hide the copy and move constructors [bugprone-forwarding-reference-overload]
  611:13: warning: constructor accepting a forwarding reference can hide the copy and move constructors [bugprone-forwarding-reference-overload]

To quote Tom Cherry:
  I'm a bit confused at what's happening there.
  I think it's a bug in the linter itself.
  The general solution to that problem is a heavy dose of std::enable_if<>
  to hide that constructor when the 'U' parameter is the same class,
  but those constructors do have the necessarily std::enable_if<> lines.

  I think the problem is that the linter doesn't check that the macro
  _ENABLE_IF() expands into std::enable_if<>.  Let me try explicitly
  putting the std::enable_if<> instead of the macro and check if it
  goes away.

  I expanded the macro but the linter doesn't still doesn't accept
  the format of `std::enable_if_t<(condition_here)>* = nullptr`.
  It does accept `typename Enable = std::enable_if_t<(condition_here), void>`,
  which is the syntax used on their example here:
    https://clang.llvm.org/extra/clang-tidy/checks/bugprone-forwarding-reference-overload.html.

  That latter syntax doesn't work for us.
  See the Notes section on
    https://en.cppreference.com/w/cpp/types/enable_if
  as a reference for why what we're doing is correct.

Test: builds
Bug: 153035880
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I493ff19208cc104f5f176a36ec23fbcb914388f7
2020-04-24 11:28:06 -07:00
Tom Cherry
36d31c530d base: reimagine line splitting in logger.cpp
Previously, we would split messages by line and call the logger
function for each line.  We would hold a lock during this, to ensure
that multiple threads would not interleave their messages.

There are a few problems with this approach:
1) Using a lock is not efficient and is not fork safe
2) With APEX, there is one lock per instance of libbase, so we must
   move the lock to a location where all instances can access it, or
   perform the line splitting in a way that does not require the lock.

To solve these issues, we reimagine line splitting.
1) We move the lock out of the LogMessage::~LogMessage() and make it
   the logger's responsibility to split lines, giving the logger the
   option to lock or not.
2) We do not need any locks at all for StderrLogger.
   Instead, we generate a single string that contains all of the lines
   with their appropriate log header.  A single write() call is used
   to output this at once.
3) Logd handles log messages with newlines correctly, however it only
   accepts up to a maximum size of log message.  Therefore we
   separate the incoming log message into chunks, delimited by new
   lines, up to that maximum size, and send each of those to logd.
   Note that this is the strategy used in
   android.util.Log.printlns().
   This should solve a majority of use cases, since the maximum size
   that logd accepts is nearly 4K, while remaining lock free.
   If interleaving messages absolutely must be avoided, a lock can
   still be used given 1) above.

Bug: 65062446
Bug: 153824050
Test: logging, particularly multi-line stack traces, show correctly
Test: existing and new unit tests
Change-Id: Id0cb5669bee7f912da1e17f7010f0ee4c93be1e3
2020-04-23 16:38:11 -07:00
Maciej Żenczykowski
4fc9b99329 expected.h - fix bugprone-branch-clone warning
Fixes:
  system/core/base/include/android-base/expected.h:606:39: warning: repeated branch in conditional chain [bugprone-branch-clone]
    if (x.has_value() != y.has_value()) {
                                        ^
  system/core/base/include/android-base/expected.h:608:4: note: end of the original
    } else if (!x.has_value()) {
     ^
  system/core/base/include/android-base/expected.h:610:10: note: clone 1 starts here
    } else {
           ^

Test: builds
Bug: 153035880
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ie67a8bb1bf622319adea15466c42077e0e9b1a18
2020-04-23 13:44:33 -07:00
Jooyung Han
3851f7e836 libbase/liblog: set min_sdk_version
Modules contributing mainline modules (APK/APEX) should set
min_sdk_version as well as apex_available.

For now setting min_sdk_version doesn't change build outputs.
But build-time checks will be added soon.

Bug: 152655956
Test: m
Change-Id: If4ff1fbc31e5be3f5611a4713ae4032aba4ee5f2
2020-04-23 23:40:14 +09:00
Tom Cherry
53d301c29b Remove thread safety from libbase logging / liblog
There are no libbase users that require thread safety for SetLogger,
SetAborter, or SetDefaultTag  and the equivalent liblog symbols are
unreleased, thus have effectively no users.

It is hard to imagine a scenario where a user would need to use these
functions in a multi-threaded program, and it is unreasonable for all
users to pay for thread safety for a vast minority of potential
scenarios. Thread safety implies less efficiency and necessarily means
that these functions are neither fork safe nor async-signal safe, and
we do have users who depend on those characteristics.

It is always possible for users of the non-thread safe versions of
these functions to build thread safe versions on top of them.  For
example, if a user needs a thread safe SetLogger(), they can use the
non-thread safe SetLogger at the start of their program to register a
logger that has its own lock and pointer to a logger function.

Bug: 119867234
Test: logging unit tests
Change-Id: I8afffec1a6957d3bda95502a4c59493e0c5049ce
2020-04-22 13:12:11 -07:00
Tom Cherry
85f2bc930a Cleanup some trivial TODOs.
1) There's no reason or way to support boot_clock for waiting for
   property changes, since the underlying futex_wait uses
   CLOCK_MONOTONIC.  We probably wouldn't want boot_clock even if it
   did, since it doesn't make sense to consider the time a device was
   suspending in the timeout for waiting for a property to change.
2) The init tokenizer has been essentially unchanged for a decade,
   there's no motivation to 'fix' it to not require a trailing
   newline.
3) The ueventd TODO regarding moving vendor specific ueventd.rc
   entries out of rootdir has been fixed.

Test: n/a
Change-Id: I3b68e3d2f25cbd539f9f8ff526669b8af04d833d
2020-04-10 10:15:30 -07:00
Tom Cherry
ebf43ad2d8 liblog: correct new APIs per the API review
1) Rename __android_logger_data to __android_log_message and rename
   __android_log_write_logger_data to
   __android_log_write_log_message. Move the const char* message
   argument into __android_log_message.
2) Add @param, @return, and "Available since API level 30." to the
   documentation of new functions.
3) Document that the user defined aborter should but may not abort.
4) Document the line separation is the responsibility of the log
   function provided to __android_log_set_logger().

Bug: 150898477
Test: build, liblog and libbase unit tests
Change-Id: I07c41011ef25b3e7cc4943f3f1e240a2f6aa2802
2020-03-25 18:36:10 +00:00
Jooyung Han
2d954136fa base: dlopen/dlsym for liblog when SDK_VER <= 29
libbase doesn't have to rely on dlopen/dlsym to use liblog's new symbols
when it is built for __ANDROID_SDK_VERSION__ > 29.

Bug: 150860940
Test: TARGET_BUILD_APPS="com.android.adbd com.android.resolv" m
      objdump -T ...shared_com.android.resolv/libbase.so | grep LIBLOG_R
        => should be none because resolv apex is targeting 29
      objdump -T ...shared_com.android.adbd/libbase.so | grep LIBLOG_R
        => should list all new symbols because adbd apex is targeting R
      objdump -T ...shared/libbase.so | grep LIBLOG_R
        => should list all new symbols

Merged-In: I7f7f16510d7637cd380fe35ea9ff3e804f38851d
Change-Id: I7f7f16510d7637cd380fe35ea9ff3e804f38851d
(cherry picked from commit 22207e6590)
2020-03-18 17:42:41 +09:00
Tom Cherry
c74afeaa8b Merge changes Id67203bb,I0c1dd57f
* changes:
  liblog: move LOG_ID_DEFAULT into the log_id enum
  liblog: use int32_t and uint32_t for new NDK APIs
2020-03-13 16:10:35 +00:00
Tom Cherry
f1a975bece liblog: use int32_t and uint32_t for new NDK APIs
As requested during the API review.

Bug: 150898477
Test: liblog and libbase unit tests
Change-Id: I0c1dd57f7499e432bb881e1da1beb55f1ff7de05
2020-03-12 11:11:24 -07:00
Jiyong Park
2c608b32db libbase uses liblog symbols via dlsym when it is built for APEX
libbase is a popular library that is used by many APEXes either directly
or transitively. It is being used by several Mainline modules that were
launched with Q, in which case everything in the APEX - including
libbase - shouldn't use new APIs that are added post Q, i.e. R.

libbase however is using a few new R symbols from liblog, and this is
preventing those Q-launching Mainline modules that are built in R source
tree from being installed to Q devices.

Fortunately, the dependencies to the new R symbols are guarded with a
flag; when the existence of the symbols are not guaranteed, it uses
dlsym. This change fixes the aforementioned problem by turning on the
flag also when libbase is built for an APEX.

Exempt-From-Owner-Approval: cherry-pick rvc-dev

Bug: 149569129
Test: TARGET_BUILD_APPS=com.android.media
vendor/google/build/build_mainline_modules.sh
adb install --staged out/dist/mainline_modules_arm64/com.android.media.apex
adb reboot
The APEX is installed and mediaextractor process doesn't crash

Merged-In: I44b5ec028850613cb45fc3e792f43cd8e87cfd00
(cherry picked from commit 5280b5c03e)
Change-Id: I44b5ec028850613cb45fc3e792f43cd8e87cfd00
2020-03-11 07:53:23 +00:00
Josh Gao
a964a96ae7 Merge "base: tag unique_fd::reset as reinitializing for clang-tidy." 2020-03-10 22:32:41 +00:00
Josh Gao
e43893e95c base: tag unique_fd::reset as reinitializing for clang-tidy.
Appease clang-tidy by marking reset() as a method that reinitializes
after moving out of a unique_fd.

Unfortunately, there isn't an attribute that let us mark the type as
being safe to use after move in general, which means that moving out of
a unique_fd and then calling get() on it will still be frowned upon.

clang-tidy has a hard-coded list of standard container types that
are safe to use after move, but doesn't provide a way to mark custom
types as satisfying this condition.

Bug: http://b/150959261
Test: reverted the change to unique_fd.h and the test failed
Change-Id: Ide73d7caa4cd2b192018f111059d696dca4de987
2020-03-09 12:32:56 -07:00
Jiyong Park
8bf9b1632e Set apex_available property
The marked library(ies) were available to the APEXes via the hand-written
whitelist in build/soong/apex/apex.go. Trying to remove the whitelist
by adding apex_available property to the Android.bp of the libraries.

In this change, following libs were made available to all apexes because
their usage is quite common and there is no reason to restrict them
to some APEXes.

* libbase_headers
* libcutils, libcutils_headers
* libutils_headers, libsystem_headers
* liblog_headers
* libbacktrace, libbacktrace_headers
* libcrypto_utils

Bug: 150999716
Test: m
Change-Id: If3d3652e6604ed4f6d7694fe7ac61ae496621026
2020-03-09 16:38:02 +09:00
Tom Cherry
d620ec7fb9 base: access all new liblog symbols through liblog_functions
The original CL was missing these.

Bug: 149591522
Test: build
Change-Id: I99615b81cfe9166a00c812a8642ecf1244bf08b9
2020-03-05 10:52:01 -08:00
Josh Gao
891e6dad73 base: add CachedProperty.
Copy bionic's CachedProperty with some minor API tweaks, to allow for
efficient querying of properties that rarely change.

Bug: http://b/141959374
Test: treehugger
Change-Id: I4dfc3f527d30262b35e871d256cec69e69f2e1d7
2020-02-27 13:56:48 -08:00
Elliott Hughes
f77f6f003c Remove various bits of dead code and unused workarounds.
Test: treehugger
Change-Id: I68fcd5da304d04ff4da3c3f3712fb79ce6b5791e
Merged-In: I68fcd5da304d04ff4da3c3f3712fb79ce6b5791e
2020-02-22 16:53:24 +00:00
Howard Ro
6c364f94ad Merge "Allow apexes to link against more libs" 2020-02-19 01:17:09 +00:00
Tom Cherry
d5f9d87da2 base: remove Errorf/ErrnoErrorf work around
This is no longer needed

Test: build
Change-Id: Ied9b26ff517906d662f90a31c98829843c1e9a9f
2020-02-14 12:43:11 -08:00
Jeffrey Huang
0c0b774a64 Allow apexes to link against more libs
Bug: 145923087
Test: m -j
Change-Id: I45e002ffbd16f13b71f32c80e8a2f826bfa9ec2e
2020-02-14 10:41:15 -08:00
Treehugger Robot
39e990d477 Merge "Convert system/core to Result::ok()" 2020-02-07 06:14:16 +00:00
Tom Cherry
91bbe9ef56 Merge "Check Errorf()/ErrnoErrorf() format string at compile time" 2020-02-06 19:14:15 +00:00
Bernie Innocenti
cecebbbacc Convert system/core to Result::ok()
No functionality changes, this is a mechanical cleanup.

Test: m
Test: cd system/core && atest
Change-Id: Ifdaa3ce1947ed578f656d5a446978726eb416c36
2020-02-06 17:04:27 +00:00
Bernie Innocenti
beffc028d6 Add macros to check for successful Result
These macros are meant to be used in tests:

  Result<File> maybe_a_file = OpenFile(...);
  EXPECT_OK(maybe_a_file);

On failure, the error is printed.

There's no equivalent EXPECT_NOT_OK() because it is a testing anti-pattern
which causes tests to pass even when the error changed as a result of a
regression. Use EPECT_EQ(result, Error(...)) instead.

Test: cd system/core && atest
Test: m
Change-Id: Ie26f90d3c62620e7b1f10013829ba43ef5364fe1
2020-02-06 15:27:26 +09:00
Bernie Innocenti
4adfde41ea Add android::base::expected::ok()
This is an alias for has_value() which is meant to be more concise, yet
more explicit than the conversions to bool.

Leave operator bool() in place for now: due to the large number of
users, removal of operator bool() needs to be broken up into incremental
stages.

Test: cd system/core && atest
Test: m
Change-Id: Ib1eb00f47d3c0f2229bb176b62687463b834f280
2020-02-06 15:27:26 +09:00
Tom Cherry
f8e6bf6d81 Check Errorf()/ErrnoErrorf() format string at compile time
fmtlib provides compile time checking of format strings that we're not
currently using.  This change makes Errorf() and ErrnoErrorf() into
macros such that we can take advantage of this capability.

Test: build successfully normally
Test: fail the build if using an invalid format string
Change-Id: Icb8ba8cb973bbd1fa4755a62e7598bdbb0113757
2020-02-05 07:57:14 -08:00
Bernie Innocenti
1cc76dfe84 Delete dangerous comparison operators from base::expected
These operators were included because they're present in the draft
standard proposal of std::expected, but they were deemed to lead to
bugs, particularly when T is implicitly convertible to bool.

Change-Id: Ib149decf1f230198f358dc1ae0eaed71961363f6
Test: m
2020-02-04 12:55:23 +00:00
Tom Cherry
42ee2e4f8f libbase: Have LogdLogger use LOGGER_ENTRY_MAX_PAYLOAD for its buffer
LogdLogger has its own buffer for adding the file and line number to
FATAL messages, but it is much lower than LOGGER_ENTRY_MAX_PAYLOAD and
that causes problems now that more logs are piped through this logger,
so increase the limit to maximum.

Also, in the case that the file and line number are not added, simply
pass the buffer through to liblog, since there is no reason to copy to
a separate buffer.

Bug: 148678509
Test: build, unit tests
Change-Id: I064aa34641e784dca6c529c51cb192069821d64a
2020-01-31 20:01:47 +00:00
Tom Cherry
ff464b1288 liblog: always restore errno in logging functions
Some recent changes can have these logging functions potentially set
errno.  This change places android::base::ErrnoRestorer at the entry
point of the public functions where we want to guarantee errno is
restored to ensure this will not happen again.

Test: build
Change-Id: Iab4170ab16b9c7301474a509ee42d38b370b91a4
2020-01-27 13:50:44 -08:00
Tom Cherry
2ec6a53a46 liblog: use default tag for loggability checks if no tag is provided
Bug: 116329414
Bug: 119867234
Test: new unit tests
Change-Id: I92a3f4f95e5f482f6fe20f17ed83c8ed367b06dc
2020-01-27 09:38:54 -08:00
Maciej Żenczykowski
041f8f5054 add NOLINTNEXTLINE(google-explicit-constructor)
Test: builds without warnings
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Iac7c63816dd7bf2536c0d465ef1e845330be505b
2020-01-26 20:15:07 -08:00
Yifan Hong
d66e442c21 Merge changes from topic "ramdisk"
* changes:
  Add e2fsck to fs_config
  Make ramdisk_available.
2020-01-24 22:39:35 +00:00
Tom Cherry
69ee5dde99 Move default tag from libbase to liblog
Bug: 119867234
Test: log tags look right, libbase/liblog unit tests
Change-Id: I3670c3fdce3d0238a23a53bba2877ffed1291f9c
2020-01-23 08:39:31 -08:00
Yifan Hong
7dd4553991 Make ramdisk_available.
Test: pass
Bug: 147347110
Change-Id: I9787e386e552393efc5beed5aac577be9ce1a3c5
2020-01-22 16:47:14 -08:00
Elliott Hughes
7becf26301 Merge "Make OSTREAM_STRING_POINTER_USAGE_WARNING build even with GCC" 2020-01-22 01:06:05 +00:00
Tom Cherry
0391a879f7 Move minimum log priority from libbase to liblog
See the previous commit moving SetLogger and SetAborter to liblog for
motivation.

This creates more harmony between the two mechanisms in libbase and
liblog for checking loggability.
Currently:
1) libbase filters all messages based on its minimum log priority. For
   example, if minimum log priority in libbase remained at its
   default, but a tag was specifically opted into DEBUG logs via
   log.tag.<tag>, libbase would not print this log.
2) liblog ignores libbase's minimum log priority.  For example if a
   process called SetMinimumLogPriority(WARNING) but used a library
   that logged via liblog's ALOGI macro, that log would still be
   printed even though the process intends on filtering out those INFO
   messages.

With this change:
1) If both a minimum log priority and a priority through log.tag.<tag>
   are set, then the lower of the two values is used.
2) If only one or the other is set, then that value is used.  This
   fixes the two issues described above.
3) If neither of these values are set, then the default of using INFO
   is unchanged.

Bug: 116329414
Bug: 119867234
Test: libbase and liblog minimum log priority tests
Change-Id: Icb49b30b9d93bf797470e23730ae9e537931bb6c
2020-01-21 12:14:43 -08:00
Tom Cherry
349b0c43ad Move SetLogger and SetAborter from libbase to liblog
libbase is copied into each APEX module which requires it, meaning
that there may be multiple instances of libbase running within a
single process with their own copy of libbase's globals.  This means
that SetLogger() and SetAborter() will only impact logs from the
instance of libbase that calls it.  This change moves this state to
liblog, since it will only ever have one instance in a single
process.

One major side-effect here is that now both ALOGE style and LOG(...)
style logs will be handled through the same logger function.  For
example, a logger specified through libbase's SetLogger() will now see
logs sent to liblog through ALOGE().  This is intended behavior.

A second side-effect is that libbase's stderr logger is used for all
host logging now.  It's simply a better logging default than the
fake_log_device logger in liblog currently and makes ALOGE and
LOG(...) logs on host follow the same format.

Bug: 119867234
Test: libbase and liblog unit tests; logging works
Change-Id: Ib52cbfb4e43749e50910ed19a993dffae19ace86
2020-01-21 11:05:24 -08:00
Davide Pallotti
2acd25a33d Make OSTREAM_STRING_POINTER_USAGE_WARNING build even with GCC
This is for projects built with GCC that import parts of Android that,
despite not having Android-specific dependencies, still end up
depending on logging.h.
Also removes outdated notes.

Change-Id: I5a47b302bcaeeb935592d8fc7ad2fe5068d226c3
2020-01-21 10:54:36 +01:00
Tom Cherry
f633b62b63 Merge "Require liblog for libbase in all configurations" 2020-01-15 23:20:07 +00:00
Peter Collingbourne
9ef741ccac Merge "Add unique_fd::operator{==,!=} overloads that take a unique_fd." 2020-01-15 01:24:01 +00:00
Peter Collingbourne
cc9566b6df Add unique_fd::operator{==,!=} overloads that take a unique_fd.
With C++20, any use of the existing overloads with two unique_fd
arguments is likely to become ambiguous:
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20200113/301880.html

Newer versions of clang complain about this ambiguity. Fix the error by
adding overloads that take two unique_fds.

Bug: 145916209
Change-Id: I18a292827d8841b6d24f948682123ab54dc7aaca
2020-01-13 18:44:11 -08:00
Tom Cherry
d044eaa4e7 base: remove LOG_TO(), PLOG_TO() and LOG_STREAM_TO() macros
There were only two users of these and both of them were better off
setting up a default logger.

These macros are not particularly useful as it's not useful for a
single program to write to both the MAIN and SYSTEM logs.  In fact,
the opposite of these macros would be more beneficial: having more
programs write to only the MAIN or only the SYSTEM buffer, so getting
rid of these macros removes a temptation for bad behavior.

Users that absolutely need to do this behavior can still use the
liblog macros or functions, but that should be an extreme edge case,
such as the few programs that write to the CRASH buffer and does not
need to exist in libbase.

Bug: 119867234
Test: build
Change-Id: I23369c3b48ed636b617220cab47f77fdd5559763
2020-01-13 09:29:15 -08:00
Tom Cherry
992163021d Require liblog for libbase in all configurations
liblog will soon be required for all of libbase's logging.  This
change proactively requires liblog in all configurations instead of
just Android.

Bug: 119867234
Test: build
Change-Id: I696162fbebc78d4ef23c6032412101ac51d397a4
2020-01-09 10:43:26 -08: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