Merge "fs_mgr: allow no verity metadata when the device is unlocked."
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index f993820..f86aaa0 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -275,7 +275,6 @@
         "libdebuggerd_client",
         "liblog",
         "libprocinfo",
-        "libselinux",
     ],
 
     local_include_dirs: ["include"],
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 0cc5f69..b016e23 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -28,7 +28,6 @@
 #include <android-base/unique_fd.h>
 #include <debuggerd/client.h>
 #include <procinfo/process.h>
-#include <selinux/selinux.h>
 #include "util.h"
 
 using android::base::unique_fd;
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 040b3de..340cd1e 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -486,10 +486,11 @@
         if ((info.st_mode & S_IFMT) == S_IFLNK)
             unlink(target);
     mkdir(target, 0755);
+    errno = 0;
     ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
     save_errno = errno;
-    LINFO << __FUNCTION__ << "(source=" << source << ",target="
-          << target << ",type=" << rec->fs_type << ")=" << ret;
+    PINFO << __FUNCTION__ << "(source=" << source << ",target=" << target
+          << ",type=" << rec->fs_type << ")=" << ret;
     if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
         fs_mgr_set_blk_ro(source);
     }
diff --git a/include/ziparchive b/include/ziparchive
new file mode 120000
index 0000000..d8fa424
--- /dev/null
+++ b/include/ziparchive
@@ -0,0 +1 @@
+../libziparchive/include/ziparchive
\ No newline at end of file
diff --git a/init/action.cpp b/init/action.cpp
index 6900391..4a3ab48 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -326,6 +326,13 @@
     }
 }
 
+void ActionManager::ClearQueue() {
+    // We are shutting down so don't claim the oneshot builtin actions back
+    current_executing_actions_ = {};
+    event_queue_ = {};
+    current_command_ = 0;
+}
+
 bool ActionParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
                                 int line, std::string* err) {
     std::vector<std::string> triggers(args.begin() + 1, args.end());
diff --git a/init/action.h b/init/action.h
index 5cb50a7..ad15f3f 100644
--- a/init/action.h
+++ b/init/action.h
@@ -104,6 +104,7 @@
     void ExecuteOneCommand();
     bool HasMoreCommands() const;
     void DumpState() const;
+    void ClearQueue();
 
   private:
     ActionManager(ActionManager const&) = delete;
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 00ffbc3..75a8f19 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -119,7 +119,7 @@
         LOG(ERROR) << "failed to set bootloader message: " << err;
         return -1;
     }
-    DoReboot(ANDROID_RB_RESTART2, "reboot", "recovery", false);
+    property_set("sys.powerctl", "reboot,recovery");
     return 0;
 }
 
diff --git a/init/devices.cpp b/init/devices.cpp
index 215d2ea..13cf991 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -219,7 +219,7 @@
     return {0600, 0, 0};
 }
 
-void DeviceHandler::MakeDevice(const std::string& path, int block, int major, int minor,
+void DeviceHandler::MakeDevice(const std::string& path, bool block, int major, int minor,
                                const std::vector<std::string>& links) const {
     auto[mode, uid, gid] = GetDevicePermissions(path, links);
     mode |= (block ? S_IFBLK : S_IFCHR);
@@ -279,45 +279,6 @@
     }
 }
 
-std::vector<std::string> DeviceHandler::GetCharacterDeviceSymlinks(const Uevent& uevent) const {
-    std::string parent_device;
-    if (!FindPlatformDevice(uevent.path, &parent_device)) return {};
-
-    // skip path to the parent driver
-    std::string path = uevent.path.substr(parent_device.length());
-
-    if (!StartsWith(path, "/usb")) return {};
-
-    // skip root hub name and device. use device interface
-    // skip 3 slashes, including the first / by starting the search at the 1st character, not 0th.
-    // then extract what comes between the 3rd and 4th slash
-    // e.g. "/usb/usb_device/name/tty2-1:1.0" -> "name"
-
-    std::string::size_type start = 0;
-    start = path.find('/', start + 1);
-    if (start == std::string::npos) return {};
-
-    start = path.find('/', start + 1);
-    if (start == std::string::npos) return {};
-
-    auto end = path.find('/', start + 1);
-    if (end == std::string::npos) return {};
-
-    start++;  // Skip the first '/'
-
-    auto length = end - start;
-    if (length == 0) return {};
-
-    auto name_string = path.substr(start, length);
-
-    std::vector<std::string> links;
-    links.emplace_back("/dev/usb/" + uevent.subsystem + name_string);
-
-    mkdir("/dev/usb", 0755);
-
-    return links;
-}
-
 // replaces any unacceptable characters with '_', the
 // length of the resulting string is equal to the input string
 void SanitizePartitionName(std::string* string) {
@@ -385,7 +346,7 @@
     return links;
 }
 
-void DeviceHandler::HandleDevice(const std::string& action, const std::string& devpath, int block,
+void DeviceHandler::HandleDevice(const std::string& action, const std::string& devpath, bool block,
                                  int major, int minor, const std::vector<std::string>& links) const {
     if (action == "add") {
         MakeDevice(devpath, block, major, minor, links);
@@ -411,31 +372,26 @@
     }
 }
 
-void DeviceHandler::HandleBlockDeviceEvent(const Uevent& uevent) const {
-    // if it's not a /dev device, nothing to do
-    if (uevent.major < 0 || uevent.minor < 0) return;
-
-    const char* base = "/dev/block/";
-    make_dir(base, 0755, sehandle_);
-
-    std::string name = Basename(uevent.path);
-    std::string devpath = base + name;
-
-    std::vector<std::string> links;
-    if (StartsWith(uevent.path, "/devices")) {
-        links = GetBlockDeviceSymlinks(uevent);
+void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
+    if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
+        FixupSysPermissions(uevent.path, uevent.subsystem);
     }
 
-    HandleDevice(uevent.action, devpath, 1, uevent.major, uevent.minor, links);
-}
-
-void DeviceHandler::HandleGenericDeviceEvent(const Uevent& uevent) const {
     // if it's not a /dev device, nothing to do
     if (uevent.major < 0 || uevent.minor < 0) return;
 
     std::string devpath;
+    std::vector<std::string> links;
+    bool block = false;
 
-    if (StartsWith(uevent.subsystem, "usb")) {
+    if (uevent.subsystem == "block") {
+        block = true;
+        devpath = "/dev/block/" + Basename(uevent.path);
+
+        if (StartsWith(uevent.path, "/devices")) {
+            links = GetBlockDeviceSymlinks(uevent);
+        }
+    } else if (StartsWith(uevent.subsystem, "usb")) {
         if (uevent.subsystem == "usb") {
             if (!uevent.device_name.empty()) {
                 devpath = "/dev/" + uevent.device_name;
@@ -461,21 +417,7 @@
 
     mkdir_recursive(Dirname(devpath), 0755, sehandle_);
 
-    auto links = GetCharacterDeviceSymlinks(uevent);
-
-    HandleDevice(uevent.action, devpath, 0, uevent.major, uevent.minor, links);
-}
-
-void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
-    if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
-        FixupSysPermissions(uevent.path, uevent.subsystem);
-    }
-
-    if (uevent.subsystem == "block") {
-        HandleBlockDeviceEvent(uevent);
-    } else {
-        HandleGenericDeviceEvent(uevent);
-    }
+    HandleDevice(uevent.action, devpath, block, uevent.major, uevent.minor, links);
 }
 
 DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
diff --git a/init/devices.h b/init/devices.h
index 5105ad7..c64f5fb 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -115,16 +115,12 @@
     bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;
     std::tuple<mode_t, uid_t, gid_t> GetDevicePermissions(
         const std::string& path, const std::vector<std::string>& links) const;
-    void MakeDevice(const std::string& path, int block, int major, int minor,
+    void MakeDevice(const std::string& path, bool block, int major, int minor,
                     const std::vector<std::string>& links) const;
-    std::vector<std::string> GetCharacterDeviceSymlinks(const Uevent& uevent) const;
-    void HandleDevice(const std::string& action, const std::string& devpath, int block, int major,
+    void HandleDevice(const std::string& action, const std::string& devpath, bool block, int major,
                       int minor, const std::vector<std::string>& links) const;
     void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
 
-    void HandleBlockDeviceEvent(const Uevent& uevent) const;
-    void HandleGenericDeviceEvent(const Uevent& uevent) const;
-
     std::vector<Permissions> dev_permissions_;
     std::vector<SysfsPermissions> sysfs_permissions_;
     std::vector<Subsystem> subsystems_;
diff --git a/init/devices_test.cpp b/init/devices_test.cpp
index 57d8e0f..ac4ab9b 100644
--- a/init/devices_test.cpp
+++ b/init/devices_test.cpp
@@ -30,7 +30,7 @@
 class DeviceHandlerTester {
   public:
     void TestGetSymlinks(const std::string& platform_device, const Uevent& uevent,
-                         const std::vector<std::string> expected_links, bool block) {
+                         const std::vector<std::string> expected_links) {
         TemporaryDir fake_sys_root;
         device_handler_.sysfs_mount_point_ = fake_sys_root.path;
 
@@ -44,11 +44,7 @@
         mkdir_recursive(android::base::Dirname(fake_sys_root.path + uevent.path), 0777, nullptr);
 
         std::vector<std::string> result;
-        if (block) {
-            result = device_handler_.GetBlockDeviceSymlinks(uevent);
-        } else {
-            result = device_handler_.GetCharacterDeviceSymlinks(uevent);
-        }
+        result = device_handler_.GetBlockDeviceSymlinks(uevent);
 
         auto expected_size = expected_links.size();
         ASSERT_EQ(expected_size, result.size());
@@ -64,95 +60,6 @@
     DeviceHandler device_handler_;
 };
 
-TEST(device_handler, get_character_device_symlinks_success) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/usb_device/name/tty2-1:1.0",
-        .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result{"/dev/usb/ttyname"};
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_pdev_match) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/device/name/tty2-1:1.0", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_nothing_after_platform_device) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_usb_found) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/bad/bad/", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_roothub) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_usb_device) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/usb_device/", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_final_slash) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/usb_device/name", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
-TEST(device_handler, get_character_device_symlinks_no_final_name) {
-    const char* platform_device = "/devices/platform/some_device_name";
-    Uevent uevent = {
-        .path = "/devices/platform/some_device_name/usb/usb_device//", .subsystem = "tty",
-    };
-    std::vector<std::string> expected_result;
-
-    DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, false);
-}
-
 TEST(device_handler, get_block_device_symlinks_success_platform) {
     // These are actual paths from bullhead
     const char* platform_device = "/devices/soc.0/f9824900.sdhci";
@@ -164,7 +71,7 @@
     std::vector<std::string> expected_result{"/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0"};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition) {
@@ -182,7 +89,7 @@
     };
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_num) {
@@ -198,7 +105,7 @@
     };
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_name) {
@@ -214,7 +121,7 @@
     };
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_pci) {
@@ -225,7 +132,7 @@
     std::vector<std::string> expected_result{"/dev/block/pci/pci0000:00/0000:00:1f.2/mmcblk0"};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_pci_bad_format) {
@@ -236,7 +143,7 @@
     std::vector<std::string> expected_result{};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_success_vbd) {
@@ -247,7 +154,7 @@
     std::vector<std::string> expected_result{"/dev/block/vbd/1234/mmcblk0"};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_vbd_bad_format) {
@@ -258,7 +165,7 @@
     std::vector<std::string> expected_result{};
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, get_block_device_symlinks_no_matches) {
@@ -271,7 +178,7 @@
     std::vector<std::string> expected_result;
 
     DeviceHandlerTester device_handler_tester_;
-    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result, true);
+    device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
 }
 
 TEST(device_handler, sanitize_null) {
diff --git a/init/init.cpp b/init/init.cpp
index 0562dad..d23e1a3 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -94,6 +94,7 @@
 static std::unique_ptr<Timer> waiting_for_prop(nullptr);
 static std::string wait_prop_name;
 static std::string wait_prop_value;
+static bool shutting_down;
 
 void DumpState() {
     ServiceManager::GetInstance().DumpState();
@@ -158,21 +159,31 @@
     return true;
 }
 
+void ResetWaitForProp() {
+    wait_prop_name.clear();
+    wait_prop_value.clear();
+    waiting_for_prop.reset();
+}
+
 void property_changed(const std::string& name, const std::string& value) {
     // If the property is sys.powerctl, we bypass the event queue and immediately handle it.
     // This is to ensure that init will always and immediately shutdown/reboot, regardless of
     // if there are other pending events to process or if init is waiting on an exec service or
     // waiting on a property.
-    if (name == "sys.powerctl") HandlePowerctlMessage(value);
+    // In non-thermal-shutdown case, 'shutdown' trigger will be fired to let device specific
+    // commands to be executed.
+    if (name == "sys.powerctl") {
+        if (HandlePowerctlMessage(value)) {
+            shutting_down = true;
+        }
+    }
 
     if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyChange(name, value);
 
     if (waiting_for_prop) {
         if (wait_prop_name == name && wait_prop_value == value) {
-            wait_prop_name.clear();
-            wait_prop_value.clear();
             LOG(INFO) << "Wait for property took " << *waiting_for_prop;
-            waiting_for_prop.reset();
+            ResetWaitForProp();
         }
     }
 }
@@ -1135,7 +1146,7 @@
             am.ExecuteOneCommand();
         }
         if (!(waiting_for_prop || sm.IsWaitingForExec())) {
-            restart_processes();
+            if (!shutting_down) restart_processes();
 
             // If there's a process that needs restarting, wake up in time for that.
             if (process_needs_restart_at != 0) {
diff --git a/init/init.h b/init/init.h
index 479b771..aaab523 100644
--- a/init/init.h
+++ b/init/init.h
@@ -44,6 +44,8 @@
 
 void DumpState();
 
+void ResetWaitForProp();
+
 }  // namespace init
 }  // namespace android
 
diff --git a/init/reboot.cpp b/init/reboot.cpp
index c8bb98b..ec1ddd6 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -20,7 +20,6 @@
 #include <fcntl.h>
 #include <linux/fs.h>
 #include <mntent.h>
-#include <selinux/selinux.h>
 #include <sys/capability.h>
 #include <sys/cdefs.h>
 #include <sys/ioctl.h>
@@ -50,6 +49,7 @@
 #include <private/android_filesystem_config.h>
 
 #include "capabilities.h"
+#include "init.h"
 #include "property_service.h"
 #include "service.h"
 
@@ -491,6 +491,9 @@
         }
     } else if (command == "thermal-shutdown") {  // no additional parameter allowed
         cmd = ANDROID_RB_THERMOFF;
+        // Do not queue "shutdown" trigger since we want to shutdown immediately
+        DoReboot(cmd, command, reboot_target, run_fsck);
+        return true;
     } else {
         command_invalid = true;
     }
@@ -499,7 +502,26 @@
         return false;
     }
 
-    DoReboot(cmd, command, reboot_target, run_fsck);
+    LOG(INFO) << "Clear action queue and start shutdown trigger";
+    ActionManager::GetInstance().ClearQueue();
+    // Queue shutdown trigger first
+    ActionManager::GetInstance().QueueEventTrigger("shutdown");
+    // Queue built-in shutdown_done
+    auto shutdown_handler = [cmd, command, reboot_target,
+                             run_fsck](const std::vector<std::string>&) {
+        DoReboot(cmd, command, reboot_target, run_fsck);
+        return 0;
+    };
+    ActionManager::GetInstance().QueueBuiltinAction(shutdown_handler, "shutdown_done");
+
+    // Skip wait for prop if it is in progress
+    ResetWaitForProp();
+
+    // Skip wait for exec if it is in progress
+    if (ServiceManager::GetInstance().IsWaitingForExec()) {
+        ServiceManager::GetInstance().ClearExecWait();
+    }
+
     return true;
 }
 
diff --git a/init/service.cpp b/init/service.cpp
index f9a452b..a2c4b50 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -34,6 +34,7 @@
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
+#include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <processgroup/processgroup.h>
@@ -47,6 +48,7 @@
 using android::base::boot_clock;
 using android::base::GetProperty;
 using android::base::Join;
+using android::base::make_scope_guard;
 using android::base::ParseInt;
 using android::base::StartsWith;
 using android::base::StringPrintf;
@@ -235,8 +237,15 @@
 void Service::SetProcessAttributes() {
     // Keep capabilites on uid change.
     if (capabilities_.any() && uid_) {
-        if (prctl(PR_SET_SECUREBITS, SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED) != 0) {
-            PLOG(FATAL) << "prtcl(PR_SET_KEEPCAPS) failed for " << name_;
+        // If Android is running in a container, some securebits might already
+        // be locked, so don't change those.
+        int64_t securebits = prctl(PR_GET_SECUREBITS);
+        if (securebits == -1) {
+            PLOG(FATAL) << "prctl(PR_GET_SECUREBITS) failed for " << name_;
+        }
+        securebits |= SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED;
+        if (prctl(PR_SET_SECUREBITS, securebits) != 0) {
+            PLOG(FATAL) << "prctl(PR_SET_SECUREBITS) failed for " << name_;
         }
     }
 
@@ -1081,14 +1090,24 @@
 }
 
 bool ServiceManager::ReapOneProcess() {
-    int status;
-    pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG));
-    if (pid == 0) {
+    siginfo_t siginfo = {};
+    // This returns a zombie pid or informs us that there are no zombies left to be reaped.
+    // It does NOT reap the pid; that is done below.
+    if (TEMP_FAILURE_RETRY(waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG | WNOWAIT)) != 0) {
+        PLOG(ERROR) << "waitid failed";
         return false;
-    } else if (pid == -1) {
-        PLOG(ERROR) << "waitpid failed";
-        return false;
-    } else if (PropertyChildReap(pid)) {
+    }
+
+    auto pid = siginfo.si_pid;
+    if (pid == 0) return false;
+
+    // At this point we know we have a zombie pid, so we use this scopeguard to reap the pid
+    // whenever the function returns from this point forward.
+    // We do NOT want to reap the zombie earlier as in Service::Reap(), we kill(-pid, ...) and we
+    // want the pid to remain valid throughout that (and potentially future) usages.
+    auto reaper = make_scope_guard([pid] { TEMP_FAILURE_RETRY(waitpid(pid, nullptr, WNOHANG)); });
+
+    if (PropertyChildReap(pid)) {
         return true;
     }
 
@@ -1105,14 +1124,11 @@
         name = StringPrintf("Untracked pid %d", pid);
     }
 
+    auto status = siginfo.si_status;
     if (WIFEXITED(status)) {
         LOG(INFO) << name << " exited with status " << WEXITSTATUS(status) << wait_string;
     } else if (WIFSIGNALED(status)) {
         LOG(INFO) << name << " killed by signal " << WTERMSIG(status) << wait_string;
-    } else if (WIFSTOPPED(status)) {
-        LOG(INFO) << name << " stopped by signal " << WSTOPSIG(status) << wait_string;
-    } else {
-        LOG(INFO) << name << " state changed" << wait_string;
     }
 
     if (!svc) {
@@ -1136,6 +1152,15 @@
     }
 }
 
+void ServiceManager::ClearExecWait() {
+    // Clear EXEC flag if there is one pending
+    // And clear the wait flag
+    for (const auto& s : services_) {
+        s->UnSetExec();
+    }
+    exec_waiter_.reset();
+}
+
 bool ServiceParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
                                  int line, std::string* err) {
     if (args.size() < 3) {
diff --git a/init/service.h b/init/service.h
index 3c7dc74..0cc1683 100644
--- a/init/service.h
+++ b/init/service.h
@@ -89,6 +89,7 @@
     void DumpState() const;
     void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
     bool IsShutdownCritical() const { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; }
+    void UnSetExec() { flags_ &= ~SVC_EXEC; }
 
     const std::string& name() const { return name_; }
     const std::set<std::string>& classnames() const { return classnames_; }
@@ -186,7 +187,7 @@
 };
 
 class ServiceManager {
-public:
+  public:
     static ServiceManager& GetInstance();
 
     // Exposed for testing
@@ -208,8 +209,9 @@
     void ReapAnyOutstandingChildren();
     void RemoveService(const Service& svc);
     void DumpState() const;
+    void ClearExecWait();
 
-private:
+  private:
     // Cleans up a child process that exited.
     // Returns true iff a children was cleaned up.
     bool ReapOneProcess();
diff --git a/init/util.cpp b/init/util.cpp
index 4b1894f..479179e 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -370,6 +370,7 @@
 
 void panic() {
     LOG(ERROR) << "panic: rebooting to bootloader";
+    // Do not queue "shutdown" trigger since we want to shutdown immediately
     DoReboot(ANDROID_RB_RESTART2, "reboot", "bootloader", false);
 }
 
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index a643a29..e02aaf2 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -161,6 +161,7 @@
     shared_libs = [
         "libbase",
         "libunwind",
+        "libziparchive",
     ],
 }
 
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index 1084d59..84a9a2f 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -65,6 +65,7 @@
         "liblog",
         "libbase",
     ],
+    export_include_dirs: ["include"],
     target: {
         android: {
             shared_libs: [
diff --git a/libziparchive/entry_name_utils-inl.h b/libziparchive/entry_name_utils-inl.h
index ddbc286..5fc2fb4 100644
--- a/libziparchive/entry_name_utils-inl.h
+++ b/libziparchive/entry_name_utils-inl.h
@@ -55,5 +55,4 @@
   return true;
 }
 
-
 #endif  // LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_
diff --git a/libziparchive/entry_name_utils_test.cc b/libziparchive/entry_name_utils_test.cc
index 20715bb..d83d854 100644
--- a/libziparchive/entry_name_utils_test.cc
+++ b/libziparchive/entry_name_utils_test.cc
@@ -20,44 +20,43 @@
 
 TEST(entry_name_utils, NullChars) {
   // 'A', 'R', '\0', 'S', 'E'
-  const uint8_t zeroes[] = { 0x41, 0x52, 0x00, 0x53, 0x45 };
+  const uint8_t zeroes[] = {0x41, 0x52, 0x00, 0x53, 0x45};
   ASSERT_FALSE(IsValidEntryName(zeroes, sizeof(zeroes)));
 
-  const uint8_t zeroes_continuation_chars[] = { 0xc2, 0xa1, 0xc2, 0x00 };
-  ASSERT_FALSE(IsValidEntryName(zeroes_continuation_chars,
-                                sizeof(zeroes_continuation_chars)));
+  const uint8_t zeroes_continuation_chars[] = {0xc2, 0xa1, 0xc2, 0x00};
+  ASSERT_FALSE(IsValidEntryName(zeroes_continuation_chars, sizeof(zeroes_continuation_chars)));
 }
 
 TEST(entry_name_utils, InvalidSequence) {
   // 0xfe is an invalid start byte
-  const uint8_t invalid[] = { 0x41, 0xfe };
+  const uint8_t invalid[] = {0x41, 0xfe};
   ASSERT_FALSE(IsValidEntryName(invalid, sizeof(invalid)));
 
   // 0x91 is an invalid start byte (it's a valid continuation byte).
-  const uint8_t invalid2[] = { 0x41, 0x91 };
+  const uint8_t invalid2[] = {0x41, 0x91};
   ASSERT_FALSE(IsValidEntryName(invalid2, sizeof(invalid2)));
 }
 
 TEST(entry_name_utils, TruncatedContinuation) {
   // Malayalam script with truncated bytes. There should be 2 bytes
   // after 0xe0
-  const uint8_t truncated[] = { 0xe0, 0xb4, 0x85, 0xe0, 0xb4 };
+  const uint8_t truncated[] = {0xe0, 0xb4, 0x85, 0xe0, 0xb4};
   ASSERT_FALSE(IsValidEntryName(truncated, sizeof(truncated)));
 
   // 0xc2 is the start of a 2 byte sequence that we've subsequently
   // dropped.
-  const uint8_t truncated2[] = { 0xc2, 0xc2, 0xa1 };
+  const uint8_t truncated2[] = {0xc2, 0xc2, 0xa1};
   ASSERT_FALSE(IsValidEntryName(truncated2, sizeof(truncated2)));
 }
 
 TEST(entry_name_utils, BadContinuation) {
   // 0x41 is an invalid continuation char, since it's MSBs
   // aren't "10..." (are 01).
-  const uint8_t bad[] = { 0xc2, 0xa1, 0xc2, 0x41 };
+  const uint8_t bad[] = {0xc2, 0xa1, 0xc2, 0x41};
   ASSERT_FALSE(IsValidEntryName(bad, sizeof(bad)));
 
   // 0x41 is an invalid continuation char, since it's MSBs
   // aren't "10..." (are 11).
-  const uint8_t bad2[] = { 0xc2, 0xa1, 0xc2, 0xfe };
+  const uint8_t bad2[] = {0xc2, 0xa1, 0xc2, 0xfe};
   ASSERT_FALSE(IsValidEntryName(bad2, sizeof(bad2)));
 }
diff --git a/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
similarity index 90%
rename from include/ziparchive/zip_archive.h
rename to libziparchive/include/ziparchive/zip_archive.h
index ece8693..73ae68d 100644
--- a/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -28,8 +28,8 @@
 
 /* Zip compression methods we support */
 enum {
-  kCompressStored     = 0,        // no compression
-  kCompressDeflated   = 8,        // standard deflate
+  kCompressStored = 0,    // no compression
+  kCompressDeflated = 8,  // standard deflate
 };
 
 struct ZipString {
@@ -44,19 +44,17 @@
   explicit ZipString(const char* entry_name);
 
   bool operator==(const ZipString& rhs) const {
-    return name && (name_length == rhs.name_length) &&
-        (memcmp(name, rhs.name, name_length) == 0);
+    return name && (name_length == rhs.name_length) && (memcmp(name, rhs.name, name_length) == 0);
   }
 
   bool StartsWith(const ZipString& prefix) const {
     return name && (name_length >= prefix.name_length) &&
-        (memcmp(name, prefix.name, prefix.name_length) == 0);
+           (memcmp(name, prefix.name, prefix.name_length) == 0);
   }
 
   bool EndsWith(const ZipString& suffix) const {
     return name && (name_length >= suffix.name_length) &&
-        (memcmp(name + name_length - suffix.name_length, suffix.name,
-                suffix.name_length) == 0);
+           (memcmp(name + name_length - suffix.name_length, suffix.name, suffix.name_length) == 0);
   }
 };
 
@@ -134,11 +132,11 @@
  *
  * Returns 0 on success, and negative values on failure.
  */
-int32_t OpenArchiveFd(const int fd, const char* debugFileName,
-                      ZipArchiveHandle *handle, bool assume_ownership = true);
+int32_t OpenArchiveFd(const int fd, const char* debugFileName, ZipArchiveHandle* handle,
+                      bool assume_ownership = true);
 
 int32_t OpenArchiveFromMemory(void* address, size_t length, const char* debugFileName,
-                              ZipArchiveHandle *handle);
+                              ZipArchiveHandle* handle);
 /*
  * Close archive, releasing resources associated with it. This will
  * unmap the central directory of the zipfile and free all internal
@@ -164,8 +162,7 @@
  * On non-Windows platforms this method does not modify internal state and
  * can be called concurrently.
  */
-int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,
-                  ZipEntry* data);
+int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName, ZipEntry* data);
 
 /*
  * Start iterating over all entries of a zip file. The order of iteration
@@ -180,8 +177,7 @@
  *
  * Returns 0 on success and negative values on failure.
  */
-int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
-                       const ZipString* optional_prefix,
+int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr, const ZipString* optional_prefix,
                        const ZipString* optional_suffix);
 
 /*
@@ -217,8 +213,7 @@
  *
  * Returns 0 on success and negative values on failure.
  */
-int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,
-                        uint8_t* begin, uint32_t size);
+int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry, uint8_t* begin, uint32_t size);
 
 int GetFileDescriptor(const ZipArchiveHandle handle);
 
@@ -230,9 +225,9 @@
 /*
  * Stream the uncompressed data through the supplied function,
  * passing cookie to it each time it gets called.
-*/
+ */
 int32_t ProcessZipEntryContents(ZipArchiveHandle handle, ZipEntry* entry,
-        ProcessZipEntryFunction func, void* cookie);
+                                ProcessZipEntryFunction func, void* cookie);
 #endif
 
 #endif  // LIBZIPARCHIVE_ZIPARCHIVE_H_
diff --git a/include/ziparchive/zip_archive_stream_entry.h b/libziparchive/include/ziparchive/zip_archive_stream_entry.h
similarity index 100%
rename from include/ziparchive/zip_archive_stream_entry.h
rename to libziparchive/include/ziparchive/zip_archive_stream_entry.h
diff --git a/include/ziparchive/zip_writer.h b/libziparchive/include/ziparchive/zip_writer.h
similarity index 96%
rename from include/ziparchive/zip_writer.h
rename to libziparchive/include/ziparchive/zip_writer.h
index 08ead48..c350a27 100644
--- a/include/ziparchive/zip_writer.h
+++ b/libziparchive/include/ziparchive/zip_writer.h
@@ -19,7 +19,6 @@
 
 #include <cstdio>
 #include <ctime>
-#include <zlib.h>
 
 #include <memory>
 #include <string>
@@ -28,6 +27,9 @@
 #include "android-base/macros.h"
 #include "utils/Compat.h"
 
+struct z_stream_s;
+typedef struct z_stream_s z_stream;
+
 /**
  * Writes a Zip file via a stateful interface.
  *
@@ -50,7 +52,7 @@
  *   fclose(file);
  */
 class ZipWriter {
-public:
+ public:
   enum {
     /**
      * Flag to compress the zip entry using deflate.
@@ -120,8 +122,7 @@
   /**
    * Same as StartAlignedEntry(const char*, size_t), but sets a last modified time for the entry.
    */
-  int32_t StartAlignedEntryWithTime(const char* path, size_t flags, time_t time,
-                                    uint32_t alignment);
+  int32_t StartAlignedEntryWithTime(const char* path, size_t flags, time_t time, uint32_t alignment);
 
   /**
    * Writes bytes to the zip file for the previously started zip entry.
@@ -156,7 +157,7 @@
    */
   int32_t Finish();
 
-private:
+ private:
   DISALLOW_COPY_AND_ASSIGN(ZipWriter);
 
   int32_t HandleError(int32_t error_code);
@@ -179,7 +180,7 @@
   std::vector<FileEntry> files_;
   FileEntry current_file_entry_;
 
-  std::unique_ptr<z_stream, void(*)(z_stream*)> z_stream_;
+  std::unique_ptr<z_stream, void (*)(z_stream*)> z_stream_;
   std::vector<uint8_t> buffer_;
 };
 
diff --git a/libziparchive/testdata/bad_filename.zip b/libziparchive/testdata/bad_filename.zip
new file mode 100644
index 0000000..294eaf5
--- /dev/null
+++ b/libziparchive/testdata/bad_filename.zip
Binary files differ
diff --git a/libziparchive/testdata/crash.apk b/libziparchive/testdata/crash.apk
new file mode 100644
index 0000000..d6dd52d
--- /dev/null
+++ b/libziparchive/testdata/crash.apk
Binary files differ
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index efe1096..17c268b 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -115,8 +115,7 @@
  * Convert a ZipEntry to a hash table index, verifying that it's in a
  * valid range.
  */
-static int64_t EntryToIndex(const ZipString* hash_table,
-                            const uint32_t hash_table_size,
+static int64_t EntryToIndex(const ZipString* hash_table, const uint32_t hash_table_size,
                             const ZipString& name) {
   const uint32_t hash = ComputeHash(name);
 
@@ -137,7 +136,7 @@
 /*
  * Add a new entry to the hash table.
  */
-static int32_t AddToHash(ZipString *hash_table, const uint64_t hash_table_size,
+static int32_t AddToHash(ZipString* hash_table, const uint64_t hash_table_size,
                          const ZipString& name) {
   const uint64_t hash = ComputeHash(name);
   uint32_t ent = hash & (hash_table_size - 1);
@@ -161,13 +160,12 @@
 }
 
 static int32_t MapCentralDirectory0(const char* debug_file_name, ZipArchive* archive,
-                                    off64_t file_length, off64_t read_amount,
-                                    uint8_t* scan_buffer) {
+                                    off64_t file_length, off64_t read_amount, uint8_t* scan_buffer) {
   const off64_t search_start = file_length - read_amount;
 
-  if(!archive->mapped_zip.ReadAtOffset(scan_buffer, read_amount, search_start)) {
-    ALOGE("Zip: read %" PRId64 " from offset %" PRId64 " failed",
-          static_cast<int64_t>(read_amount), static_cast<int64_t>(search_start));
+  if (!archive->mapped_zip.ReadAtOffset(scan_buffer, read_amount, search_start)) {
+    ALOGE("Zip: read %" PRId64 " from offset %" PRId64 " failed", static_cast<int64_t>(read_amount),
+          static_cast<int64_t>(search_start));
     return kIoError;
   }
 
@@ -198,8 +196,7 @@
    * Verify that there's no trailing space at the end of the central directory
    * and its comment.
    */
-  const off64_t calculated_length = eocd_offset + sizeof(EocdRecord)
-      + eocd->comment_length;
+  const off64_t calculated_length = eocd_offset + sizeof(EocdRecord) + eocd->comment_length;
   if (calculated_length != file_length) {
     ALOGW("Zip: %" PRId64 " extraneous bytes at the end of the central directory",
           static_cast<int64_t>(file_length - calculated_length));
@@ -212,7 +209,7 @@
    */
   if (static_cast<off64_t>(eocd->cd_start_offset) + eocd->cd_size > eocd_offset) {
     ALOGW("Zip: bad offsets (dir %" PRIu32 ", size %" PRIu32 ", eocd %" PRId64 ")",
-        eocd->cd_start_offset, eocd->cd_size, static_cast<int64_t>(eocd_offset));
+          eocd->cd_start_offset, eocd->cd_size, static_cast<int64_t>(eocd_offset));
 #if defined(__ANDROID__)
     if (eocd->cd_start_offset + eocd->cd_size <= eocd_offset) {
       android_errorWriteLog(0x534e4554, "31251826");
@@ -225,8 +222,8 @@
     return kEmptyArchive;
   }
 
-  ALOGV("+++ num_entries=%" PRIu32 " dir_size=%" PRIu32 " dir_offset=%" PRIu32,
-        eocd->num_records, eocd->cd_size, eocd->cd_start_offset);
+  ALOGV("+++ num_entries=%" PRIu32 " dir_size=%" PRIu32 " dir_offset=%" PRIu32, eocd->num_records,
+        eocd->cd_size, eocd->cd_start_offset);
 
   /*
    * It all looks good.  Create a mapping for the CD, and set the fields
@@ -255,7 +252,6 @@
  *   num_entries
  */
 static int32_t MapCentralDirectory(const char* debug_file_name, ZipArchive* archive) {
-
   // Test file length. We use lseek64 to make sure the file
   // is small enough to be a zip file (Its size must be less than
   // 0xffffffff bytes).
@@ -292,8 +288,8 @@
   }
 
   std::vector<uint8_t> scan_buffer(read_amount);
-  int32_t result = MapCentralDirectory0(debug_file_name, archive, file_length, read_amount,
-                                        scan_buffer.data());
+  int32_t result =
+      MapCentralDirectory0(debug_file_name, archive, file_length, read_amount, scan_buffer.data());
   return result;
 }
 
@@ -314,8 +310,13 @@
    * least one unused entry to avoid an infinite loop during creation.
    */
   archive->hash_table_size = RoundUpPower2(1 + (num_entries * 4) / 3);
-  archive->hash_table = reinterpret_cast<ZipString*>(calloc(archive->hash_table_size,
-      sizeof(ZipString)));
+  archive->hash_table =
+      reinterpret_cast<ZipString*>(calloc(archive->hash_table_size, sizeof(ZipString)));
+  if (archive->hash_table == nullptr) {
+    ALOGW("Zip: unable to allocate the %u-entry hash_table, entry size: %zu",
+          archive->hash_table_size, sizeof(ZipString));
+    return -1;
+  }
 
   /*
    * Walk through the central directory, adding entries to the hash
@@ -324,22 +325,24 @@
   const uint8_t* const cd_end = cd_ptr + cd_length;
   const uint8_t* ptr = cd_ptr;
   for (uint16_t i = 0; i < num_entries; i++) {
-    const CentralDirectoryRecord* cdr =
-        reinterpret_cast<const CentralDirectoryRecord*>(ptr);
-    if (cdr->record_signature != CentralDirectoryRecord::kSignature) {
-      ALOGW("Zip: missed a central dir sig (at %" PRIu16 ")", i);
+    if (ptr > cd_end - sizeof(CentralDirectoryRecord)) {
+      ALOGW("Zip: ran off the end (at %" PRIu16 ")", i);
+#if defined(__ANDROID__)
+      android_errorWriteLog(0x534e4554, "36392138");
+#endif
       return -1;
     }
 
-    if (ptr + sizeof(CentralDirectoryRecord) > cd_end) {
-      ALOGW("Zip: ran off the end (at %" PRIu16 ")", i);
+    const CentralDirectoryRecord* cdr = reinterpret_cast<const CentralDirectoryRecord*>(ptr);
+    if (cdr->record_signature != CentralDirectoryRecord::kSignature) {
+      ALOGW("Zip: missed a central dir sig (at %" PRIu16 ")", i);
       return -1;
     }
 
     const off64_t local_header_offset = cdr->local_file_header_offset;
     if (local_header_offset >= archive->directory_offset) {
       ALOGW("Zip: bad LFH offset %" PRId64 " at entry %" PRIu16,
-          static_cast<int64_t>(local_header_offset), i);
+            static_cast<int64_t>(local_header_offset), i);
       return -1;
     }
 
@@ -348,6 +351,13 @@
     const uint16_t comment_length = cdr->comment_length;
     const uint8_t* file_name = ptr + sizeof(CentralDirectoryRecord);
 
+    if (file_name + file_name_length > cd_end) {
+      ALOGW(
+          "Zip: file name boundary exceeds the central directory range, file_name_length: "
+          "%" PRIx16 ", cd_length: %zu",
+          file_name_length, cd_length);
+      return -1;
+    }
     /* check that file name is valid UTF-8 and doesn't contain NUL (U+0000) characters */
     if (!IsValidEntryName(file_name, file_name_length)) {
       return -1;
@@ -357,8 +367,7 @@
     ZipString entry_name;
     entry_name.name = file_name;
     entry_name.name_length = file_name_length;
-    const int add_result = AddToHash(archive->hash_table,
-        archive->hash_table_size, entry_name);
+    const int add_result = AddToHash(archive->hash_table, archive->hash_table_size, entry_name);
     if (add_result != 0) {
       ALOGW("Zip: Error adding entry to hash table %d", add_result);
       return add_result;
@@ -366,8 +375,7 @@
 
     ptr += sizeof(CentralDirectoryRecord) + file_name_length + extra_length + comment_length;
     if ((ptr - cd_ptr) > static_cast<int64_t>(cd_length)) {
-      ALOGW("Zip: bad CD advance (%tu vs %zu) at entry %" PRIu16,
-          ptr - cd_ptr, cd_length, i);
+      ALOGW("Zip: bad CD advance (%tu vs %zu) at entry %" PRIu16, ptr - cd_ptr, cd_length, i);
       return -1;
     }
   }
@@ -376,8 +384,7 @@
   return 0;
 }
 
-static int32_t OpenArchiveInternal(ZipArchive* archive,
-                                   const char* debug_file_name) {
+static int32_t OpenArchiveInternal(ZipArchive* archive, const char* debug_file_name) {
   int32_t result = -1;
   if ((result = MapCentralDirectory(debug_file_name, archive)) != 0) {
     return result;
@@ -390,8 +397,8 @@
   return 0;
 }
 
-int32_t OpenArchiveFd(int fd, const char* debug_file_name,
-                      ZipArchiveHandle* handle, bool assume_ownership) {
+int32_t OpenArchiveFd(int fd, const char* debug_file_name, ZipArchiveHandle* handle,
+                      bool assume_ownership) {
   ZipArchive* archive = new ZipArchive(fd, assume_ownership);
   *handle = archive;
   return OpenArchiveInternal(archive, debug_file_name);
@@ -411,7 +418,7 @@
 }
 
 int32_t OpenArchiveFromMemory(void* address, size_t length, const char* debug_file_name,
-                              ZipArchiveHandle *handle) {
+                              ZipArchiveHandle* handle) {
   ZipArchive* archive = new ZipArchive(address, length);
   *handle = archive;
   return OpenArchiveInternal(archive, debug_file_name);
@@ -451,8 +458,7 @@
   return 0;
 }
 
-static int32_t FindEntry(const ZipArchive* archive, const int ent,
-                         ZipEntry* data) {
+static int32_t FindEntry(const ZipArchive* archive, const int ent, ZipEntry* data) {
   const uint16_t nameLen = archive->hash_table[ent].name_length;
 
   // Recover the start of the central directory entry from the filename
@@ -470,8 +476,7 @@
     return kInvalidOffset;
   }
 
-  const CentralDirectoryRecord *cdr =
-      reinterpret_cast<const CentralDirectoryRecord*>(ptr);
+  const CentralDirectoryRecord* cdr = reinterpret_cast<const CentralDirectoryRecord*>(ptr);
 
   // The offset of the start of the central directory in the zipfile.
   // We keep this lying around so that we can sanity check all our lengths
@@ -499,15 +504,15 @@
   uint8_t lfh_buf[sizeof(LocalFileHeader)];
   if (!archive->mapped_zip.ReadAtOffset(lfh_buf, sizeof(lfh_buf), local_header_offset)) {
     ALOGW("Zip: failed reading lfh name from offset %" PRId64,
-        static_cast<int64_t>(local_header_offset));
+          static_cast<int64_t>(local_header_offset));
     return kIoError;
   }
 
-  const LocalFileHeader *lfh = reinterpret_cast<const LocalFileHeader*>(lfh_buf);
+  const LocalFileHeader* lfh = reinterpret_cast<const LocalFileHeader*>(lfh_buf);
 
   if (lfh->lfh_signature != LocalFileHeader::kSignature) {
     ALOGW("Zip: didn't find signature at start of lfh, offset=%" PRId64,
-        static_cast<int64_t>(local_header_offset));
+          static_cast<int64_t>(local_header_offset));
     return kInvalidOffset;
   }
 
@@ -536,13 +541,12 @@
   // header agree on the crc, compressed, and uncompressed sizes of the entry.
   if ((lfh->gpb_flags & kGPBDDFlagMask) == 0) {
     data->has_data_descriptor = 0;
-    if (data->compressed_length != lfh->compressed_size
-        || data->uncompressed_length != lfh->uncompressed_size
-        || data->crc32 != lfh->crc32) {
-      ALOGW("Zip: size/crc32 mismatch. expected {%" PRIu32 ", %" PRIu32
-        ", %" PRIx32 "}, was {%" PRIu32 ", %" PRIu32 ", %" PRIx32 "}",
-        data->compressed_length, data->uncompressed_length, data->crc32,
-        lfh->compressed_size, lfh->uncompressed_size, lfh->crc32);
+    if (data->compressed_length != lfh->compressed_size ||
+        data->uncompressed_length != lfh->uncompressed_size || data->crc32 != lfh->crc32) {
+      ALOGW("Zip: size/crc32 mismatch. expected {%" PRIu32 ", %" PRIu32 ", %" PRIx32
+            "}, was {%" PRIu32 ", %" PRIu32 ", %" PRIx32 "}",
+            data->compressed_length, data->uncompressed_length, data->crc32, lfh->compressed_size,
+            lfh->uncompressed_size, lfh->crc32);
       return kInconsistentInformation;
     }
   } else {
@@ -580,8 +584,8 @@
     return kInconsistentInformation;
   }
 
-  const off64_t data_offset = local_header_offset + sizeof(LocalFileHeader)
-      + lfh->file_name_length + lfh->extra_field_length;
+  const off64_t data_offset = local_header_offset + sizeof(LocalFileHeader) +
+                              lfh->file_name_length + lfh->extra_field_length;
   if (data_offset > cd_offset) {
     ALOGW("Zip: bad data offset %" PRId64 " in zip", static_cast<int64_t>(data_offset));
     return kInvalidOffset;
@@ -589,16 +593,17 @@
 
   if (static_cast<off64_t>(data_offset + data->compressed_length) > cd_offset) {
     ALOGW("Zip: bad compressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
-      static_cast<int64_t>(data_offset), data->compressed_length, static_cast<int64_t>(cd_offset));
+          static_cast<int64_t>(data_offset), data->compressed_length,
+          static_cast<int64_t>(cd_offset));
     return kInvalidOffset;
   }
 
   if (data->method == kCompressStored &&
-    static_cast<off64_t>(data_offset + data->uncompressed_length) > cd_offset) {
-     ALOGW("Zip: bad uncompressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
-       static_cast<int64_t>(data_offset), data->uncompressed_length,
-       static_cast<int64_t>(cd_offset));
-     return kInvalidOffset;
+      static_cast<off64_t>(data_offset + data->uncompressed_length) > cd_offset) {
+    ALOGW("Zip: bad uncompressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
+          static_cast<int64_t>(data_offset), data->uncompressed_length,
+          static_cast<int64_t>(cd_offset));
+    return kInvalidOffset;
   }
 
   data->offset = data_offset;
@@ -613,8 +618,7 @@
   ZipString suffix;
   ZipArchive* archive;
 
-  IterationHandle(const ZipString* in_prefix,
-                  const ZipString* in_suffix) {
+  IterationHandle(const ZipString* in_prefix, const ZipString* in_suffix) {
     if (in_prefix) {
       uint8_t* name_copy = new uint8_t[in_prefix->name_length];
       memcpy(name_copy, in_prefix->name, in_prefix->name_length);
@@ -641,8 +645,7 @@
   }
 };
 
-int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
-                       const ZipString* optional_prefix,
+int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr, const ZipString* optional_prefix,
                        const ZipString* optional_suffix) {
   ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
 
@@ -655,7 +658,7 @@
   cookie->position = 0;
   cookie->archive = archive;
 
-  *cookie_ptr = cookie ;
+  *cookie_ptr = cookie;
   return 0;
 }
 
@@ -663,16 +666,14 @@
   delete reinterpret_cast<IterationHandle*>(cookie);
 }
 
-int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,
-                  ZipEntry* data) {
+int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName, ZipEntry* data) {
   const ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
   if (entryName.name_length == 0) {
     ALOGW("Zip: Invalid filename %.*s", entryName.name_length, entryName.name);
     return kInvalidEntryName;
   }
 
-  const int64_t ent = EntryToIndex(archive->hash_table,
-    archive->hash_table_size, entryName);
+  const int64_t ent = EntryToIndex(archive->hash_table, archive->hash_table_size, entryName);
 
   if (ent < 0) {
     ALOGV("Zip: Could not find entry %.*s", entryName.name_length, entryName.name);
@@ -700,10 +701,8 @@
 
   for (uint32_t i = currentOffset; i < hash_table_length; ++i) {
     if (hash_table[i].name != NULL &&
-        (handle->prefix.name_length == 0 ||
-         hash_table[i].StartsWith(handle->prefix)) &&
-        (handle->suffix.name_length == 0 ||
-         hash_table[i].EndsWith(handle->suffix))) {
+        (handle->prefix.name_length == 0 || hash_table[i].StartsWith(handle->prefix)) &&
+        (handle->suffix.name_length == 0 || hash_table[i].EndsWith(handle->suffix))) {
       handle->position = (i + 1);
       const int error = FindEntry(archive, i, data);
       if (!error) {
@@ -723,8 +722,10 @@
  public:
   virtual bool Append(uint8_t* buf, size_t buf_size) = 0;
   virtual ~Writer() {}
+
  protected:
   Writer() = default;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(Writer);
 };
@@ -734,14 +735,12 @@
 // the data appended to it.
 class MemoryWriter : public Writer {
  public:
-  MemoryWriter(uint8_t* buf, size_t size) : Writer(),
-      buf_(buf), size_(size), bytes_written_(0) {
-  }
+  MemoryWriter(uint8_t* buf, size_t size) : Writer(), buf_(buf), size_(size), bytes_written_(0) {}
 
   virtual bool Append(uint8_t* buf, size_t buf_size) override {
     if (bytes_written_ + buf_size > size_) {
-      ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)",
-            size_, bytes_written_ + buf_size);
+      ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)", size_,
+            bytes_written_ + buf_size);
       return false;
     }
 
@@ -760,7 +759,6 @@
 // The file will be truncated to the end of the written data.
 class FileWriter : public Writer {
  public:
-
   // Creates a FileWriter for |fd| and prepare to write |entry| to it,
   // guaranteeing that the file descriptor is valid and that there's enough
   // space on the volume to write out the entry completely and that the file
@@ -819,8 +817,8 @@
 
   virtual bool Append(uint8_t* buf, size_t buf_size) override {
     if (total_bytes_written_ + buf_size > declared_length_) {
-      ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)",
-            declared_length_, total_bytes_written_ + buf_size);
+      ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)", declared_length_,
+            total_bytes_written_ + buf_size);
       return false;
     }
 
@@ -833,13 +831,10 @@
 
     return result;
   }
+
  private:
-  FileWriter(const int fd, const size_t declared_length) :
-      Writer(),
-      fd_(fd),
-      declared_length_(declared_length),
-      total_bytes_written_(0) {
-  }
+  FileWriter(const int fd, const size_t declared_length)
+      : Writer(), fd_(fd), declared_length_(declared_length), total_bytes_written_(0) {}
 
   const int fd_;
   const size_t declared_length_;
@@ -882,8 +877,7 @@
   zerr = zlib_inflateInit2(&zstream, -MAX_WBITS);
   if (zerr != Z_OK) {
     if (zerr == Z_VERSION_ERROR) {
-      ALOGE("Installed zlib is not compatible with linked version (%s)",
-        ZLIB_VERSION);
+      ALOGE("Installed zlib is not compatible with linked version (%s)", ZLIB_VERSION);
     } else {
       ALOGW("Call to inflateInit2 failed (zerr=%d)", zerr);
     }
@@ -892,7 +886,7 @@
   }
 
   auto zstream_deleter = [](z_stream* stream) {
-    inflateEnd(stream);  /* free up any allocated structures */
+    inflateEnd(stream); /* free up any allocated structures */
   };
 
   std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter);
@@ -919,15 +913,13 @@
     /* uncompress the data */
     zerr = inflate(&zstream, Z_NO_FLUSH);
     if (zerr != Z_OK && zerr != Z_STREAM_END) {
-      ALOGW("Zip: inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)",
-          zerr, zstream.next_in, zstream.avail_in,
-          zstream.next_out, zstream.avail_out);
+      ALOGW("Zip: inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)", zerr, zstream.next_in,
+            zstream.avail_in, zstream.next_out, zstream.avail_out);
       return kZlibError;
     }
 
     /* write when we're full or when we're done */
-    if (zstream.avail_out == 0 ||
-      (zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {
+    if (zstream.avail_out == 0 || (zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {
       const size_t write_size = zstream.next_out - &write_buf[0];
       if (!writer->Append(&write_buf[0], write_size)) {
         // The file might have declared a bogus length.
@@ -941,7 +933,7 @@
     }
   } while (zerr == Z_OK);
 
-  assert(zerr == Z_STREAM_END);     /* other errors should've been caught */
+  assert(zerr == Z_STREAM_END); /* other errors should've been caught */
 
   // NOTE: zstream.adler is always set to 0, because we're using the -MAX_WBITS
   // "feature" of zlib to tell it there won't be a zlib file header. zlib
@@ -952,8 +944,8 @@
   *crc_out = crc;
 
   if (zstream.total_out != uncompressed_length || compressed_length != 0) {
-    ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")",
-        zstream.total_out, uncompressed_length);
+    ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")", zstream.total_out,
+          uncompressed_length);
     return kInconsistentInformation;
   }
 
@@ -961,7 +953,7 @@
 }
 
 static int32_t CopyEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, Writer* writer,
-                                 uint64_t *crc_out) {
+                                 uint64_t* crc_out) {
   static const uint32_t kBufSize = 32768;
   std::vector<uint8_t> buf(kBufSize);
 
@@ -991,8 +983,7 @@
   return 0;
 }
 
-int32_t ExtractToWriter(ZipArchiveHandle handle,
-                        ZipEntry* entry, Writer* writer) {
+int32_t ExtractToWriter(ZipArchiveHandle handle, ZipEntry* entry, Writer* writer) {
   ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
   const uint16_t method = entry->method;
   off64_t data_offset = entry->offset;
@@ -1027,14 +1018,12 @@
   return return_value;
 }
 
-int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,
-                        uint8_t* begin, uint32_t size) {
+int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry, uint8_t* begin, uint32_t size) {
   std::unique_ptr<Writer> writer(new MemoryWriter(begin, size));
   return ExtractToWriter(handle, entry, writer.get());
 }
 
-int32_t ExtractEntryToFile(ZipArchiveHandle handle,
-                           ZipEntry* entry, int fd) {
+int32_t ExtractEntryToFile(ZipArchiveHandle handle, ZipEntry* entry, int fd) {
   std::unique_ptr<Writer> writer(FileWriter::Create(fd, entry));
   if (writer.get() == nullptr) {
     return kIoError;
@@ -1061,8 +1050,7 @@
   return reinterpret_cast<ZipArchive*>(handle)->mapped_zip.GetFileDescriptor();
 }
 
-ZipString::ZipString(const char* entry_name)
-    : name(reinterpret_cast<const uint8_t*>(entry_name)) {
+ZipString::ZipString(const char* entry_name) : name(reinterpret_cast<const uint8_t*>(entry_name)) {
   size_t len = strlen(entry_name);
   CHECK_LE(len, static_cast<size_t>(UINT16_MAX));
   name_length = static_cast<uint16_t>(len);
@@ -1071,10 +1059,8 @@
 #if !defined(_WIN32)
 class ProcessWriter : public Writer {
  public:
-  ProcessWriter(ProcessZipEntryFunction func, void* cookie) : Writer(),
-    proc_function_(func),
-    cookie_(cookie) {
-  }
+  ProcessWriter(ProcessZipEntryFunction func, void* cookie)
+      : Writer(), proc_function_(func), cookie_(cookie) {}
 
   virtual bool Append(uint8_t* buf, size_t buf_size) override {
     return proc_function_(buf, buf_size, cookie_);
@@ -1091,7 +1077,7 @@
   return ExtractToWriter(handle, entry, &writer);
 }
 
-#endif //!defined(_WIN32)
+#endif  //! defined(_WIN32)
 
 int MappedZipFile::GetFileDescriptor() const {
   if (!has_fd_) {
@@ -1134,8 +1120,7 @@
     return true;
   } else {
     if (offset < 0 || offset > static_cast<off64_t>(data_length_)) {
-      ALOGE("Zip: invalid offset: %" PRId64 ", data length: %" PRId64 "\n" , offset,
-            data_length_);
+      ALOGE("Zip: invalid offset: %" PRId64 ", data length: %" PRId64 "\n", offset, data_length_);
       return false;
     }
 
@@ -1146,7 +1131,7 @@
 
 bool MappedZipFile::ReadData(uint8_t* buffer, size_t read_amount) {
   if (has_fd_) {
-    if(!android::base::ReadFully(fd_, buffer, read_amount)) {
+    if (!android::base::ReadFully(fd_, buffer, read_amount)) {
       ALOGE("Zip: read from %d failed\n", fd_);
       return false;
     }
@@ -1172,7 +1157,6 @@
     return false;
   }
   return ReadData(buf, len);
-
 }
 
 void CentralDirectory::Initialize(void* map_base_ptr, off64_t cd_start_offset, size_t cd_size) {
@@ -1183,13 +1167,13 @@
 bool ZipArchive::InitializeCentralDirectory(const char* debug_file_name, off64_t cd_start_offset,
                                             size_t cd_size) {
   if (mapped_zip.HasFd()) {
-    if (!directory_map->create(debug_file_name, mapped_zip.GetFileDescriptor(),
-                               cd_start_offset, cd_size, true /* read only */)) {
+    if (!directory_map->create(debug_file_name, mapped_zip.GetFileDescriptor(), cd_start_offset,
+                               cd_size, true /* read only */)) {
       return false;
     }
 
     CHECK_EQ(directory_map->getDataLength(), cd_size);
-    central_directory.Initialize(directory_map->getDataPtr(), 0/*offset*/, cd_size);
+    central_directory.Initialize(directory_map->getDataPtr(), 0 /*offset*/, cd_size);
   } else {
     if (mapped_zip.GetBasePtr() == nullptr) {
       ALOGE("Zip: Failed to map central directory, bad mapped_zip base pointer\n");
@@ -1197,9 +1181,10 @@
     }
     if (static_cast<off64_t>(cd_start_offset) + static_cast<off64_t>(cd_size) >
         mapped_zip.GetFileLength()) {
-      ALOGE("Zip: Failed to map central directory, offset exceeds mapped memory region ("
-            "start_offset %"  PRId64 ", cd_size %zu, mapped_region_size %" PRId64 ")",
-            static_cast<int64_t>(cd_start_offset), cd_size, mapped_zip.GetFileLength());
+      ALOGE(
+          "Zip: Failed to map central directory, offset exceeds mapped memory region ("
+          "start_offset %" PRId64 ", cd_size %zu, mapped_region_size %" PRId64 ")",
+          static_cast<int64_t>(cd_start_offset), cd_size, mapped_zip.GetFileLength());
       return false;
     }
 
diff --git a/libziparchive/zip_archive_common.h b/libziparchive/zip_archive_common.h
index bc1ebb4..8b99bde 100644
--- a/libziparchive/zip_archive_common.h
+++ b/libziparchive/zip_archive_common.h
@@ -57,6 +57,7 @@
   uint32_t cd_start_offset;
   // Length of the central directory comment.
   uint16_t comment_length;
+
  private:
   EocdRecord() = default;
   DISALLOW_COPY_AND_ASSIGN(EocdRecord);
@@ -111,6 +112,7 @@
   // The offset to the local file header for this entry, from the
   // beginning of this archive.
   uint32_t local_file_header_offset;
+
  private:
   CentralDirectoryRecord() = default;
   DISALLOW_COPY_AND_ASSIGN(CentralDirectoryRecord);
@@ -149,6 +151,7 @@
   // The length of the extra field info (in bytes). This data
   // will appear immediately after the entry file name.
   uint16_t extra_field_length;
+
  private:
   LocalFileHeader() = default;
   DISALLOW_COPY_AND_ASSIGN(LocalFileHeader);
@@ -164,6 +167,7 @@
   uint32_t compressed_size;
   // Uncompressed size of the entry.
   uint32_t uncompressed_size;
+
  private:
   DataDescriptor() = default;
   DISALLOW_COPY_AND_ASSIGN(DataDescriptor);
diff --git a/libziparchive/zip_archive_private.h b/libziparchive/zip_archive_private.h
index de93ecd..840f1af 100644
--- a/libziparchive/zip_archive_private.h
+++ b/libziparchive/zip_archive_private.h
@@ -92,21 +92,17 @@
 
 class MappedZipFile {
  public:
-  explicit MappedZipFile(const int fd) :
-    has_fd_(true),
-    fd_(fd),
-    base_ptr_(nullptr),
-    data_length_(0),
-    read_pos_(0) {}
+  explicit MappedZipFile(const int fd)
+      : has_fd_(true), fd_(fd), base_ptr_(nullptr), data_length_(0), read_pos_(0) {}
 
-  explicit MappedZipFile(void* address, size_t length) :
-    has_fd_(false),
-    fd_(-1),
-    base_ptr_(address),
-    data_length_(static_cast<off64_t>(length)),
-    read_pos_(0) {}
+  explicit MappedZipFile(void* address, size_t length)
+      : has_fd_(false),
+        fd_(-1),
+        base_ptr_(address),
+        data_length_(static_cast<off64_t>(length)),
+        read_pos_(0) {}
 
-  bool HasFd() const {return has_fd_;}
+  bool HasFd() const { return has_fd_; }
 
   int GetFileDescriptor() const;
 
@@ -137,13 +133,11 @@
 
 class CentralDirectory {
  public:
-  CentralDirectory(void) :
-    base_ptr_(nullptr),
-    length_(0) {}
+  CentralDirectory(void) : base_ptr_(nullptr), length_(0) {}
 
-  const uint8_t* GetBasePtr() const {return base_ptr_;}
+  const uint8_t* GetBasePtr() const { return base_ptr_; }
 
-  size_t GetMapLength() const {return length_;}
+  size_t GetMapLength() const { return length_; }
 
   void Initialize(void* map_base_ptr, off64_t cd_start_offset, size_t cd_size);
 
@@ -172,25 +166,25 @@
   uint32_t hash_table_size;
   ZipString* hash_table;
 
-  ZipArchive(const int fd, bool assume_ownership) :
-    mapped_zip(fd),
-    close_file(assume_ownership),
-    directory_offset(0),
-    central_directory(),
-    directory_map(new android::FileMap()),
-    num_entries(0),
-    hash_table_size(0),
-    hash_table(nullptr) {}
+  ZipArchive(const int fd, bool assume_ownership)
+      : mapped_zip(fd),
+        close_file(assume_ownership),
+        directory_offset(0),
+        central_directory(),
+        directory_map(new android::FileMap()),
+        num_entries(0),
+        hash_table_size(0),
+        hash_table(nullptr) {}
 
-  ZipArchive(void* address, size_t length) :
-    mapped_zip(address, length),
-    close_file(false),
-    directory_offset(0),
-    central_directory(),
-    directory_map(new android::FileMap()),
-    num_entries(0),
-    hash_table_size(0),
-    hash_table(nullptr) {}
+  ZipArchive(void* address, size_t length)
+      : mapped_zip(address, length),
+        close_file(false),
+        directory_offset(0),
+        central_directory(),
+        directory_map(new android::FileMap()),
+        num_entries(0),
+        hash_table_size(0),
+        hash_table(nullptr) {}
 
   ~ZipArchive() {
     if (close_file && mapped_zip.GetFileDescriptor() >= 0) {
@@ -202,7 +196,6 @@
 
   bool InitializeCentralDirectory(const char* debug_file_name, off64_t cd_start_offset,
                                   size_t cd_size);
-
 };
 
 #endif  // LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_
diff --git a/libziparchive/zip_archive_stream_entry.cc b/libziparchive/zip_archive_stream_entry.cc
index 3f336a6..50352ef 100644
--- a/libziparchive/zip_archive_stream_entry.cc
+++ b/libziparchive/zip_archive_stream_entry.cc
@@ -162,8 +162,7 @@
   int zerr = zlib_inflateInit2(&z_stream_, -MAX_WBITS);
   if (zerr != Z_OK) {
     if (zerr == Z_VERSION_ERROR) {
-      ALOGE("Installed zlib is not compatible with linked version (%s)",
-        ZLIB_VERSION);
+      ALOGE("Installed zlib is not compatible with linked version (%s)", ZLIB_VERSION);
     } else {
       ALOGE("Call to inflateInit2 failed (zerr=%d)", zerr);
     }
@@ -193,13 +192,14 @@
 
 bool ZipArchiveStreamEntryCompressed::Verify() {
   return z_stream_init_ && uncompressed_length_ == 0 && compressed_length_ == 0 &&
-      crc32_ == computed_crc32_;
+         crc32_ == computed_crc32_;
 }
 
 const std::vector<uint8_t>* ZipArchiveStreamEntryCompressed::Read() {
   if (z_stream_.avail_out == 0) {
     z_stream_.next_out = out_.data();
-    z_stream_.avail_out = out_.size();;
+    z_stream_.avail_out = out_.size();
+    ;
   }
 
   while (true) {
@@ -226,9 +226,8 @@
 
     int zerr = inflate(&z_stream_, Z_NO_FLUSH);
     if (zerr != Z_OK && zerr != Z_STREAM_END) {
-      ALOGE("inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)",
-          zerr, z_stream_.next_in, z_stream_.avail_in,
-          z_stream_.next_out, z_stream_.avail_out);
+      ALOGE("inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)", zerr, z_stream_.next_in,
+            z_stream_.avail_in, z_stream_.next_out, z_stream_.avail_out);
       return nullptr;
     }
 
@@ -276,8 +275,8 @@
   return length_ == 0;
 }
 
-ZipArchiveStreamEntry* ZipArchiveStreamEntry::Create(
-    ZipArchiveHandle handle, const ZipEntry& entry) {
+ZipArchiveStreamEntry* ZipArchiveStreamEntry::Create(ZipArchiveHandle handle,
+                                                     const ZipEntry& entry) {
   ZipArchiveStreamEntry* stream = nullptr;
   if (entry.method != kCompressStored) {
     stream = new ZipArchiveStreamEntryCompressed(handle);
@@ -292,8 +291,8 @@
   return stream;
 }
 
-ZipArchiveStreamEntry* ZipArchiveStreamEntry::CreateRaw(
-    ZipArchiveHandle handle, const ZipEntry& entry) {
+ZipArchiveStreamEntry* ZipArchiveStreamEntry::CreateRaw(ZipArchiveHandle handle,
+                                                        const ZipEntry& entry) {
   ZipArchiveStreamEntry* stream = nullptr;
   if (entry.method == kCompressStored) {
     // Not compressed, don't need to do anything special.
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 52099c3..dbc14f0 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -40,23 +40,17 @@
 static const std::string kValidZip = "valid.zip";
 static const std::string kLargeZip = "large.zip";
 static const std::string kBadCrcZip = "bad_crc.zip";
+static const std::string kCrashApk = "crash.apk";
+static const std::string kBadFilenameZip = "bad_filename.zip";
 static const std::string kUpdateZip = "dummy-update.zip";
 
-static const std::vector<uint8_t> kATxtContents {
-  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-  '\n'
-};
+static const std::vector<uint8_t> kATxtContents{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a',
+                                                'b', 'c', 'd', 'e', 'f', 'g', 'h', '\n'};
 
-static const std::vector<uint8_t> kATxtContentsCompressed {
-  'K', 'L', 'J', 'N', 'I', 'M', 'K', 207, 'H',
-  132, 210, '\\', '\0'
-};
+static const std::vector<uint8_t> kATxtContentsCompressed{'K', 'L', 'J', 'N', 'I',  'M', 'K',
+                                                          207, 'H', 132, 210, '\\', '\0'};
 
-static const std::vector<uint8_t> kBTxtContents {
-  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-  '\n'
-};
+static const std::vector<uint8_t> kBTxtContents{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '\n'};
 
 static const std::string kATxtName("a.txt");
 static const std::string kBTxtName("b.txt");
@@ -65,14 +59,12 @@
 static const std::string kLargeCompressTxtName("compress.txt");
 static const std::string kLargeUncompressTxtName("uncompress.txt");
 
-static int32_t OpenArchiveWrapper(const std::string& name,
-                                  ZipArchiveHandle* handle) {
+static int32_t OpenArchiveWrapper(const std::string& name, ZipArchiveHandle* handle) {
   const std::string abs_path = test_data_dir + "/" + name;
   return OpenArchive(abs_path.c_str(), handle);
 }
 
-static void AssertNameEquals(const std::string& name_str,
-                             const ZipString& name) {
+static void AssertNameEquals(const std::string& name_str, const ZipString& name) {
   ASSERT_EQ(name_str.size(), name.name_length);
   ASSERT_EQ(0, memcmp(name_str.c_str(), name.name, name.name_length));
 }
@@ -85,7 +77,15 @@
 TEST(ziparchive, Open) {
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
+  CloseArchive(handle);
 
+  ASSERT_EQ(-1, OpenArchiveWrapper(kBadFilenameZip, &handle));
+  CloseArchive(handle);
+}
+
+TEST(ziparchive, OutOfBound) {
+  ZipArchiveHandle handle;
+  ASSERT_EQ(-8, OpenArchiveWrapper(kCrashApk, &handle));
   CloseArchive(handle);
 }
 
@@ -335,47 +335,36 @@
 }
 
 static const uint32_t kEmptyEntriesZip[] = {
-      0x04034b50, 0x0000000a, 0x63600000, 0x00004438, 0x00000000, 0x00000000,
-      0x00090000, 0x6d65001c, 0x2e797470, 0x55747874, 0x03000954, 0x52e25c13,
-      0x52e25c24, 0x000b7875, 0x42890401, 0x88040000, 0x50000013, 0x1e02014b,
-      0x00000a03, 0x60000000, 0x00443863, 0x00000000, 0x00000000, 0x09000000,
-      0x00001800, 0x00000000, 0xa0000000, 0x00000081, 0x706d6500, 0x742e7974,
-      0x54557478, 0x13030005, 0x7552e25c, 0x01000b78, 0x00428904, 0x13880400,
-      0x4b500000, 0x00000605, 0x00010000, 0x004f0001, 0x00430000, 0x00000000 };
+    0x04034b50, 0x0000000a, 0x63600000, 0x00004438, 0x00000000, 0x00000000, 0x00090000,
+    0x6d65001c, 0x2e797470, 0x55747874, 0x03000954, 0x52e25c13, 0x52e25c24, 0x000b7875,
+    0x42890401, 0x88040000, 0x50000013, 0x1e02014b, 0x00000a03, 0x60000000, 0x00443863,
+    0x00000000, 0x00000000, 0x09000000, 0x00001800, 0x00000000, 0xa0000000, 0x00000081,
+    0x706d6500, 0x742e7974, 0x54557478, 0x13030005, 0x7552e25c, 0x01000b78, 0x00428904,
+    0x13880400, 0x4b500000, 0x00000605, 0x00010000, 0x004f0001, 0x00430000, 0x00000000};
 
 // This is a zip file containing a single entry (ab.txt) that contains
 // 90072 repetitions of the string "ab\n" and has an uncompressed length
 // of 270216 bytes.
 static const uint16_t kAbZip[] = {
-  0x4b50, 0x0403, 0x0014, 0x0000, 0x0008, 0x51d2, 0x4698, 0xc4b0,
-  0x2cda, 0x011b, 0x0000, 0x1f88, 0x0004, 0x0006, 0x001c, 0x6261,
-  0x742e, 0x7478, 0x5455, 0x0009, 0x7c03, 0x3a09, 0x7c55, 0x3a09,
-  0x7555, 0x0b78, 0x0100, 0x8904, 0x0042, 0x0400, 0x1388, 0x0000,
-  0xc2ed, 0x0d31, 0x0000, 0x030c, 0x7fa0, 0x3b2e, 0x22ff, 0xa2aa,
-  0x841f, 0x45fc, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-  0x5555, 0x5555, 0x5555, 0x5555, 0xdd55, 0x502c, 0x014b, 0x1e02,
-  0x1403, 0x0000, 0x0800, 0xd200, 0x9851, 0xb046, 0xdac4, 0x1b2c,
-  0x0001, 0x8800, 0x041f, 0x0600, 0x1800, 0x0000, 0x0000, 0x0100,
-  0x0000, 0xa000, 0x0081, 0x0000, 0x6100, 0x2e62, 0x7874, 0x5574,
-  0x0554, 0x0300, 0x097c, 0x553a, 0x7875, 0x000b, 0x0401, 0x4289,
-  0x0000, 0x8804, 0x0013, 0x5000, 0x054b, 0x0006, 0x0000, 0x0100,
-  0x0100, 0x4c00, 0x0000, 0x5b00, 0x0001, 0x0000, 0x0000
-};
+    0x4b50, 0x0403, 0x0014, 0x0000, 0x0008, 0x51d2, 0x4698, 0xc4b0, 0x2cda, 0x011b, 0x0000, 0x1f88,
+    0x0004, 0x0006, 0x001c, 0x6261, 0x742e, 0x7478, 0x5455, 0x0009, 0x7c03, 0x3a09, 0x7c55, 0x3a09,
+    0x7555, 0x0b78, 0x0100, 0x8904, 0x0042, 0x0400, 0x1388, 0x0000, 0xc2ed, 0x0d31, 0x0000, 0x030c,
+    0x7fa0, 0x3b2e, 0x22ff, 0xa2aa, 0x841f, 0x45fc, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+    0x5555, 0x5555, 0x5555, 0x5555, 0xdd55, 0x502c, 0x014b, 0x1e02, 0x1403, 0x0000, 0x0800, 0xd200,
+    0x9851, 0xb046, 0xdac4, 0x1b2c, 0x0001, 0x8800, 0x041f, 0x0600, 0x1800, 0x0000, 0x0000, 0x0100,
+    0x0000, 0xa000, 0x0081, 0x0000, 0x6100, 0x2e62, 0x7874, 0x5574, 0x0554, 0x0300, 0x097c, 0x553a,
+    0x7875, 0x000b, 0x0401, 0x4289, 0x0000, 0x8804, 0x0013, 0x5000, 0x054b, 0x0006, 0x0000, 0x0100,
+    0x0100, 0x4c00, 0x0000, 0x5b00, 0x0001, 0x0000, 0x0000};
 
 static const std::string kAbTxtName("ab.txt");
 static const size_t kAbUncompressedSize = 270216;
@@ -396,7 +385,6 @@
   uint8_t buffer[1];
   ASSERT_EQ(0, ExtractToMemory(handle, &entry, buffer, 1));
 
-
   TemporaryFile tmp_output_file;
   ASSERT_NE(-1, tmp_output_file.fd);
   ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_output_file.fd));
@@ -410,7 +398,7 @@
   TemporaryFile tmp_file;
   ASSERT_NE(-1, tmp_file.fd);
   ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, reinterpret_cast<const uint8_t*>(kAbZip),
-                         sizeof(kAbZip) - 1));
+                                        sizeof(kAbZip) - 1));
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveFd(tmp_file.fd, "EntryLargerThan32KTest", &handle));
 
@@ -438,8 +426,7 @@
   // the same as the memory buffer we extracted directly to.
   std::vector<uint8_t> file_contents(kAbUncompressedSize);
   ASSERT_EQ(0, lseek64(tmp_output_file.fd, 0, SEEK_SET));
-  ASSERT_TRUE(android::base::ReadFully(tmp_output_file.fd, &file_contents[0],
-                                       file_contents.size()));
+  ASSERT_TRUE(android::base::ReadFully(tmp_output_file.fd, &file_contents[0], file_contents.size()));
   ASSERT_EQ(file_contents, buffer);
 
   for (int i = 0; i < 90072; ++i) {
@@ -455,7 +442,7 @@
   ASSERT_NE(-1, tmp_file.fd);
 
   // Create a file with 8 bytes of random garbage.
-  static const uint8_t trailer[] = { 'A' ,'n', 'd', 'r', 'o', 'i', 'd', 'z' };
+  static const uint8_t trailer[] = {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'z'};
   ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, kEmptyEntriesZip, sizeof(kEmptyEntriesZip)));
   ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, trailer, sizeof(trailer)));
 
@@ -466,7 +453,7 @@
 TEST(ziparchive, ExtractToFile) {
   TemporaryFile tmp_file;
   ASSERT_NE(-1, tmp_file.fd);
-  const uint8_t data[8] = { '1', '2', '3', '4', '5', '6', '7', '8' };
+  const uint8_t data[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
   const size_t data_size = sizeof(data);
 
   ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, data, data_size));
@@ -480,7 +467,6 @@
   ASSERT_EQ(0, FindEntry(handle, name, &entry));
   ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_file.fd));
 
-
   // Assert that the first 8 bytes of the file haven't been clobbered.
   uint8_t read_buffer[data_size];
   ASSERT_EQ(0, lseek64(tmp_file.fd, 0, SEEK_SET));
@@ -489,10 +475,9 @@
 
   // Assert that the remainder of the file contains the incompressed data.
   std::vector<uint8_t> uncompressed_data(entry.uncompressed_length);
-  ASSERT_TRUE(android::base::ReadFully(tmp_file.fd, uncompressed_data.data(),
-                                       entry.uncompressed_length));
-  ASSERT_EQ(0, memcmp(&uncompressed_data[0], kATxtContents.data(),
-                      kATxtContents.size()));
+  ASSERT_TRUE(
+      android::base::ReadFully(tmp_file.fd, uncompressed_data.data(), entry.uncompressed_length));
+  ASSERT_EQ(0, memcmp(&uncompressed_data[0], kATxtContents.data(), kATxtContents.size()));
 
   // Assert that the total length of the file is sane
   ASSERT_EQ(static_cast<ssize_t>(data_size + kATxtContents.size()),
@@ -509,7 +494,7 @@
 
   // Memory map the file first and open the archive from the memory region.
   android::FileMap file_map;
-  file_map.create(zip_path.c_str(), fd, 0/*offset*/, sb.st_size, true);
+  file_map.create(zip_path.c_str(), fd, 0 /*offset*/, sb.st_size, true);
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveFromMemory(file_map.getDataPtr(), file_map.getDataLength(),
                                      zip_path.c_str(), &handle));
@@ -525,9 +510,8 @@
 }
 #endif
 
-static void ZipArchiveStreamTest(
-    ZipArchiveHandle& handle, const std::string& entry_name, bool raw,
-    bool verified, ZipEntry* entry, std::vector<uint8_t>* read_data) {
+static void ZipArchiveStreamTest(ZipArchiveHandle& handle, const std::string& entry_name, bool raw,
+                                 bool verified, ZipEntry* entry, std::vector<uint8_t>* read_data) {
   ZipString name;
   SetZipString(&name, entry_name);
   ASSERT_EQ(0, FindEntry(handle, name, entry));
@@ -556,9 +540,9 @@
   ASSERT_EQ(total_size, read_data->size());
 }
 
-static void ZipArchiveStreamTestUsingContents(
-    const std::string& zip_file, const std::string& entry_name,
-    const std::vector<uint8_t>& contents, bool raw) {
+static void ZipArchiveStreamTestUsingContents(const std::string& zip_file,
+                                              const std::string& entry_name,
+                                              const std::vector<uint8_t>& contents, bool raw) {
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveWrapper(zip_file, &handle));
 
@@ -572,7 +556,8 @@
   CloseArchive(handle);
 }
 
-static void ZipArchiveStreamTestUsingMemory(const std::string& zip_file, const std::string& entry_name) {
+static void ZipArchiveStreamTestUsingMemory(const std::string& zip_file,
+                                            const std::string& entry_name) {
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveWrapper(zip_file, &handle));
 
@@ -735,10 +720,8 @@
 int main(int argc, char** argv) {
   ::testing::InitGoogleTest(&argc, argv);
 
-  static struct option options[] = {
-    { "test_data_dir", required_argument, nullptr, 't' },
-    { nullptr, 0, nullptr, 0 }
-  };
+  static struct option options[] = {{"test_data_dir", required_argument, nullptr, 't'},
+                                    {nullptr, 0, nullptr, 0}};
 
   while (true) {
     int option_index;
diff --git a/libziparchive/zip_writer.cc b/libziparchive/zip_writer.cc
index 6d28bdb..6ad3366 100644
--- a/libziparchive/zip_writer.cc
+++ b/libziparchive/zip_writer.cc
@@ -16,11 +16,11 @@
 
 #include "ziparchive/zip_writer.h"
 
-#include <cstdio>
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <zlib.h>
-#define DEF_MEM_LEVEL 8                // normally in zutil.h?
+#include <cstdio>
+#define DEF_MEM_LEVEL 8  // normally in zutil.h?
 
 #include <memory>
 #include <vector>
@@ -33,13 +33,13 @@
 #include "zip_archive_common.h"
 
 #if !defined(powerof2)
-#define powerof2(x) ((((x)-1)&(x))==0)
+#define powerof2(x) ((((x)-1) & (x)) == 0)
 #endif
 
 /* Zip compression methods we support */
 enum {
-  kCompressStored     = 0,        // no compression
-  kCompressDeflated   = 8,        // standard deflate
+  kCompressStored = 0,    // no compression
+  kCompressDeflated = 8,  // standard deflate
 };
 
 // Size of the output buffer used for compression.
@@ -67,10 +67,7 @@
 static const int32_t kInvalidAlignment = -6;
 
 static const char* sErrorCodes[] = {
-    "Invalid state",
-    "IO error",
-    "Invalid entry name",
-    "Zlib error",
+    "Invalid state", "IO error", "Invalid entry name", "Zlib error",
 };
 
 const char* ZipWriter::ErrorCodeString(int32_t error_code) {
@@ -85,9 +82,13 @@
   delete stream;
 }
 
-ZipWriter::ZipWriter(FILE* f) : file_(f), seekable_(false), current_offset_(0),
-                                state_(State::kWritingZip), z_stream_(nullptr, DeleteZStream),
-                                buffer_(kBufSize) {
+ZipWriter::ZipWriter(FILE* f)
+    : file_(f),
+      seekable_(false),
+      current_offset_(0),
+      state_(State::kWritingZip),
+      z_stream_(nullptr, DeleteZStream),
+      buffer_(kBufSize) {
   // Check if the file is seekable (regular file). If fstat fails, that's fine, subsequent calls
   // will fail as well.
   struct stat file_stats;
@@ -96,13 +97,14 @@
   }
 }
 
-ZipWriter::ZipWriter(ZipWriter&& writer) : file_(writer.file_),
-                                           seekable_(writer.seekable_),
-                                           current_offset_(writer.current_offset_),
-                                           state_(writer.state_),
-                                           files_(std::move(writer.files_)),
-                                           z_stream_(std::move(writer.z_stream_)),
-                                           buffer_(std::move(writer.buffer_)){
+ZipWriter::ZipWriter(ZipWriter&& writer)
+    : file_(writer.file_),
+      seekable_(writer.seekable_),
+      current_offset_(writer.current_offset_),
+      state_(writer.state_),
+      files_(std::move(writer.files_)),
+      z_stream_(std::move(writer.z_stream_)),
+      buffer_(std::move(writer.buffer_)) {
   writer.file_ = nullptr;
   writer.state_ = State::kError;
 }
@@ -154,10 +156,10 @@
 
   struct tm* ptm;
 #if !defined(_WIN32)
-    struct tm tm_result;
-    ptm = localtime_r(&when, &tm_result);
+  struct tm tm_result;
+  ptm = localtime_r(&when, &tm_result);
 #else
-    ptm = localtime(&when);
+  ptm = localtime(&when);
 #endif
 
   int year = ptm->tm_year;
@@ -193,8 +195,8 @@
   dst->extra_field_length = src.padding_length;
 }
 
-int32_t ZipWriter::StartAlignedEntryWithTime(const char* path, size_t flags,
-                                             time_t time, uint32_t alignment) {
+int32_t ZipWriter::StartAlignedEntryWithTime(const char* path, size_t flags, time_t time,
+                                             uint32_t alignment) {
   if (state_ != State::kWritingZip) {
     return kInvalidState;
   }
@@ -252,9 +254,8 @@
     return HandleError(kIoError);
   }
 
-  if (file_entry.padding_length != 0 &&
-      fwrite(zero_padding.data(), 1, file_entry.padding_length, file_)
-      != file_entry.padding_length) {
+  if (file_entry.padding_length != 0 && fwrite(zero_padding.data(), 1, file_entry.padding_length,
+                                               file_) != file_entry.padding_length) {
     return HandleError(kIoError);
   }
 
@@ -292,7 +293,7 @@
   CHECK(state_ == State::kWritingZip);
 
   // Initialize the z_stream for compression.
-  z_stream_ = std::unique_ptr<z_stream, void(*)(z_stream*)>(new z_stream(), DeleteZStream);
+  z_stream_ = std::unique_ptr<z_stream, void (*)(z_stream*)>(new z_stream(), DeleteZStream);
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wold-style-cast"
@@ -331,8 +332,8 @@
     return result;
   }
 
-  current_file_entry_.crc32 = crc32(current_file_entry_.crc32,
-                                    reinterpret_cast<const Bytef*>(data), len);
+  current_file_entry_.crc32 =
+      crc32(current_file_entry_.crc32, reinterpret_cast<const Bytef*>(data), len);
   current_file_entry_.uncompressed_size += len;
   return kNoError;
 }
diff --git a/libziparchive/zip_writer_test.cc b/libziparchive/zip_writer_test.cc
index 9ad0252..c284273 100644
--- a/libziparchive/zip_writer_test.cc
+++ b/libziparchive/zip_writer_test.cc
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "ziparchive/zip_archive.h"
 #include "ziparchive/zip_writer.h"
+#include "ziparchive/zip_archive.h"
 
 #include <android-base/test_utils.h>
 #include <gtest/gtest.h>
@@ -361,7 +361,7 @@
 
   ASSERT_EQ(0, writer.StartEntry("large.txt", 0));
   std::vector<uint8_t> data;
-  data.resize(1024*1024, 0xef);
+  data.resize(1024 * 1024, 0xef);
   ASSERT_EQ(0, writer.WriteBytes(data.data(), data.size()));
   ASSERT_EQ(0, writer.FinishEntry());
 
@@ -382,8 +382,9 @@
                                                             ZipArchiveHandle handle,
                                                             ZipEntry* zip_entry) {
   if (expected.size() != zip_entry->uncompressed_length) {
-    return ::testing::AssertionFailure() << "uncompressed entry size "
-        << zip_entry->uncompressed_length << " does not match expected size " << expected.size();
+    return ::testing::AssertionFailure()
+           << "uncompressed entry size " << zip_entry->uncompressed_length
+           << " does not match expected size " << expected.size();
   }
 
   std::string actual;
@@ -396,7 +397,7 @@
 
   if (expected != actual) {
     return ::testing::AssertionFailure() << "actual zip_entry data '" << actual
-        << "' does not match expected '" << expected << "'";
+                                         << "' does not match expected '" << expected << "'";
   }
   return ::testing::AssertionSuccess();
 }
diff --git a/logd/Android.bp b/logd/Android.bp
new file mode 100644
index 0000000..68b79d3
--- /dev/null
+++ b/logd/Android.bp
@@ -0,0 +1,78 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This is what we want to do:
+//  event_logtags = $(shell
+//    sed -n
+//        "s/^\([0-9]*\)[ \t]*$1[ \t].*/-D`echo $1 | tr a-z A-Z`_LOG_TAG=\1/p"
+//        $(LOCAL_PATH)/$2/event.logtags)
+//  event_flag := $(call event_logtags,auditd)
+//  event_flag += $(call event_logtags,logd)
+//  event_flag += $(call event_logtags,tag_def)
+// so make sure we do not regret hard-coding it as follows:
+event_flag = [
+    "-DAUDITD_LOG_TAG=1003",
+    "-DCHATTY_LOG_TAG=1004",
+    "-DTAG_DEF_LOG_TAG=1005",
+    "-DLIBLOG_LOG_TAG=1006"
+]
+
+cc_library_static {
+    name: "liblogd",
+
+    srcs: [
+        "LogCommand.cpp",
+        "CommandListener.cpp",
+        "LogListener.cpp",
+        "LogReader.cpp",
+        "FlushCommand.cpp",
+        "LogBuffer.cpp",
+        "LogBufferElement.cpp",
+        "LogBufferInterface.cpp",
+        "LogTimes.cpp",
+        "LogStatistics.cpp",
+        "LogWhiteBlackList.cpp",
+        "libaudit.c",
+        "LogAudit.cpp",
+        "LogKlog.cpp",
+        "LogTags.cpp",
+    ],
+    logtags: ["event.logtags"],
+
+    shared_libs: ["libbase"],
+
+    export_include_dirs: ["."],
+
+    cflags: ["-Werror"] + event_flag,
+}
+
+cc_binary {
+    name: "logd",
+    init_rc: ["logd.rc"],
+
+    srcs: ["main.cpp"],
+
+    static_libs: ["liblogd"],
+
+    shared_libs: [
+        "libsysutils",
+        "liblog",
+        "libcutils",
+        "libbase",
+        "libpackagelistparser",
+        "libcap",
+    ],
+
+    cflags: ["-Werror"],
+}
diff --git a/logd/Android.mk b/logd/Android.mk
index fb51992..1bca891 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -2,73 +2,6 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_MODULE:= liblogd
-
-LOCAL_SRC_FILES := \
-    LogCommand.cpp \
-    CommandListener.cpp \
-    LogListener.cpp \
-    LogReader.cpp \
-    FlushCommand.cpp \
-    LogBuffer.cpp \
-    LogBufferElement.cpp \
-    LogBufferInterface.cpp \
-    LogTimes.cpp \
-    LogStatistics.cpp \
-    LogWhiteBlackList.cpp \
-    libaudit.c \
-    LogAudit.cpp \
-    LogKlog.cpp \
-    LogTags.cpp \
-    event.logtags
-
-LOCAL_SHARED_LIBRARIES := \
-    libbase
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-# This is what we want to do:
-#  event_logtags = $(shell \
-#    sed -n \
-#        "s/^\([0-9]*\)[ \t]*$1[ \t].*/-D`echo $1 | tr a-z A-Z`_LOG_TAG=\1/p" \
-#        $(LOCAL_PATH)/$2/event.logtags)
-#  event_flag := $(call event_logtags,auditd)
-#  event_flag += $(call event_logtags,logd)
-#  event_flag += $(call event_logtags,tag_def)
-# so make sure we do not regret hard-coding it as follows:
-event_flag := -DAUDITD_LOG_TAG=1003 -DCHATTY_LOG_TAG=1004 -DTAG_DEF_LOG_TAG=1005
-event_flag += -DLIBLOG_LOG_TAG=1006
-
-LOCAL_CFLAGS := -Werror $(event_flag)
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= logd
-
-LOCAL_INIT_RC := logd.rc
-
-LOCAL_SRC_FILES := \
-    main.cpp
-
-LOCAL_STATIC_LIBRARIES := \
-    liblogd
-
-LOCAL_SHARED_LIBRARIES := \
-    libsysutils \
-    liblog \
-    libcutils \
-    libbase \
-    libpackagelistparser \
-    libcap
-
-LOCAL_CFLAGS := -Werror
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
 LOCAL_MODULE := logtagd.rc
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 LOCAL_MODULE_CLASS := ETC
diff --git a/rootdir/init.rc b/rootdir/init.rc
index ebbec35..ae86834 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -681,6 +681,10 @@
 on property:security.perf_harden=1
     write /proc/sys/kernel/perf_event_paranoid 3
 
+# on shutdown
+# In device's init.rc, this trigger can be used to do device-specific actions
+# before shutdown. e.g disable watchdog and mask error handling
+
 ## Daemon processes to be run by init.
 ##
 service ueventd /sbin/ueventd