Merge "Fixed scanf modifier"
diff --git a/recovery.cpp b/recovery.cpp
index 91c511a..ccb8e5d 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -53,6 +53,7 @@
 #include <cutils/properties.h> /* for property_list */
 #include <healthd/BatteryMonitor.h>
 #include <private/android_logger.h> /* private pmsg functions */
+#include <private/android_filesystem_config.h>  /* for AID_SYSTEM */
 #include <selinux/label.h>
 #include <selinux/selinux.h>
 #include <ziparchive/zip_archive.h>
@@ -460,9 +461,9 @@
     copy_log_file(TEMPORARY_INSTALL_FILE, LAST_INSTALL_FILE, false);
     save_kernel_log(LAST_KMSG_FILE);
     chmod(LOG_FILE, 0600);
-    chown(LOG_FILE, 1000, 1000);   // system user
+    chown(LOG_FILE, AID_SYSTEM, AID_SYSTEM);
     chmod(LAST_KMSG_FILE, 0600);
-    chown(LAST_KMSG_FILE, 1000, 1000);   // system user
+    chown(LAST_KMSG_FILE, AID_SYSTEM, AID_SYSTEM);
     chmod(LAST_LOG_FILE, 0640);
     chmod(LAST_INSTALL_FILE, 0644);
     sync();
diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp
index ef121a9..5652ddf 100644
--- a/tests/component/updater_test.cpp
+++ b/tests/component/updater_test.cpp
@@ -127,6 +127,55 @@
     expect(nullptr, "sha1_check()", kArgsParsingFailure);
 }
 
+TEST_F(UpdaterTest, apply_patch_check) {
+  // Zero-argument is not valid.
+  expect(nullptr, "apply_patch_check()", kArgsParsingFailure);
+
+  // File not found.
+  expect("", "apply_patch_check(\"/doesntexist\")", kNoCause);
+
+  std::string src_file = from_testdata_base("old.file");
+  std::string src_content;
+  ASSERT_TRUE(android::base::ReadFileToString(src_file, &src_content));
+  size_t src_size = src_content.size();
+  std::string src_hash = get_sha1(src_content);
+
+  // One-argument with EMMC:file:size:sha1 should pass the check.
+  std::string filename = android::base::Join(
+      std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size), src_hash }, ":");
+  std::string cmd = "apply_patch_check(\"" + filename + "\")";
+  expect("t", cmd.c_str(), kNoCause);
+
+  // EMMC:file:(size-1):sha1:(size+1):sha1 should fail the check.
+  std::string filename_bad = android::base::Join(
+      std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size - 1), src_hash,
+                                std::to_string(src_size + 1), src_hash },
+      ":");
+  cmd = "apply_patch_check(\"" + filename_bad + "\")";
+  expect("", cmd.c_str(), kNoCause);
+
+  // EMMC:file:(size-1):sha1:size:sha1:(size+1):sha1 should pass the check.
+  filename_bad =
+      android::base::Join(std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size - 1),
+                                                    src_hash, std::to_string(src_size), src_hash,
+                                                    std::to_string(src_size + 1), src_hash },
+                          ":");
+  cmd = "apply_patch_check(\"" + filename_bad + "\")";
+  expect("t", cmd.c_str(), kNoCause);
+
+  // Multiple arguments.
+  cmd = "apply_patch_check(\"" + filename + "\", \"wrong_sha1\", \"wrong_sha2\")";
+  expect("", cmd.c_str(), kNoCause);
+
+  cmd = "apply_patch_check(\"" + filename + "\", \"wrong_sha1\", \"" + src_hash +
+        "\", \"wrong_sha2\")";
+  expect("t", cmd.c_str(), kNoCause);
+
+  cmd = "apply_patch_check(\"" + filename_bad + "\", \"wrong_sha1\", \"" + src_hash +
+        "\", \"wrong_sha2\")";
+  expect("t", cmd.c_str(), kNoCause);
+}
+
 TEST_F(UpdaterTest, file_getprop) {
     // file_getprop() expects two arguments.
     expect(nullptr, "file_getprop()", kArgsParsingFailure);
diff --git a/updater/install.cpp b/updater/install.cpp
index c9a0270..f91f3fc 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -691,7 +691,7 @@
   const std::string& filename = args[0];
 
   std::vector<std::string> sha1s;
-  if (!ReadArgs(state, argv, &sha1s, 1, argv.size() - 1)) {
+  if (argv.size() > 1 && !ReadArgs(state, argv, &sha1s, 1, argv.size() - 1)) {
     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
   }
   int result = applypatch_check(filename.c_str(), sha1s);