Fix SEGV in libziparchive with malformed zip file.

d77c99ebc3d896501531e9522b690c4a0e971aff 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
diff --git a/base/mapped_file.cpp b/base/mapped_file.cpp
index 862b73b..fff3453 100644
--- a/base/mapped_file.cpp
+++ b/base/mapped_file.cpp
@@ -38,15 +38,14 @@
 std::unique_ptr<MappedFile> MappedFile::FromFd(borrowed_fd fd, off64_t offset, size_t length,
                                                int prot) {
 #if defined(_WIN32)
-  auto file =
-      FromOsHandle(reinterpret_cast<HANDLE>(_get_osfhandle(fd.get())), offset, length, prot);
+  return FromOsHandle(reinterpret_cast<HANDLE>(_get_osfhandle(fd.get())), offset, length, prot);
 #else
-  auto file = FromOsHandle(fd.get(), offset, length, prot);
+  return FromOsHandle(fd.get(), offset, length, prot);
 #endif
-  return file ? std::make_unique<MappedFile>(std::move(file)) : std::unique_ptr<MappedFile>{};
 }
 
-MappedFile MappedFile::FromOsHandle(os_handle h, off64_t offset, size_t length, int prot) {
+std::unique_ptr<MappedFile> MappedFile::FromOsHandle(os_handle h, off64_t offset, size_t length,
+                                                     int prot) {
   static const off64_t page_size = InitPageSize();
   size_t slop = offset % page_size;
   off64_t file_offset = offset - slop;
@@ -59,28 +58,30 @@
     // http://b/119818070 "app crashes when reading asset of zero length".
     // Return a MappedFile that's only valid for reading the size.
     if (length == 0 && ::GetLastError() == ERROR_FILE_INVALID) {
-      return MappedFile{const_cast<char*>(kEmptyBuffer), 0, 0, nullptr};
+      return std::unique_ptr<MappedFile>(
+          new MappedFile(const_cast<char*>(kEmptyBuffer), 0, 0, nullptr));
     }
-    return MappedFile(nullptr, 0, 0, nullptr);
+    return nullptr;
   }
   void* base = MapViewOfFile(handle, (prot & PROT_WRITE) ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ, 0,
                              file_offset, file_length);
   if (base == nullptr) {
     CloseHandle(handle);
-    return MappedFile(nullptr, 0, 0, nullptr);
+    return nullptr;
   }
-  return MappedFile{static_cast<char*>(base), length, slop, handle};
+  return std::unique_ptr<MappedFile>(
+      new MappedFile(static_cast<char*>(base), length, slop, handle));
 #else
   void* base = mmap(nullptr, file_length, prot, MAP_SHARED, h, file_offset);
   if (base == MAP_FAILED) {
     // http://b/119818070 "app crashes when reading asset of zero length".
     // mmap fails with EINVAL for a zero length region.
     if (errno == EINVAL && length == 0) {
-      return MappedFile{const_cast<char*>(kEmptyBuffer), 0, 0};
+      return std::unique_ptr<MappedFile>(new MappedFile(const_cast<char*>(kEmptyBuffer), 0, 0));
     }
-    return MappedFile(nullptr, 0, 0);
+    return nullptr;
   }
-  return MappedFile{static_cast<char*>(base), length, slop};
+  return std::unique_ptr<MappedFile>(new MappedFile(static_cast<char*>(base), length, slop));
 #endif
 }