diff options
-rw-r--r-- | applypatch/applypatch.cpp | 4 | ||||
-rw-r--r-- | install.cpp | 8 | ||||
-rw-r--r-- | otafault/ota_io.cpp | 28 | ||||
-rw-r--r-- | otafault/ota_io.h | 20 | ||||
-rw-r--r-- | tests/component/applypatch_test.cpp | 175 | ||||
-rw-r--r-- | updater/install.cpp | 142 |
6 files changed, 259 insertions, 118 deletions
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp index 9b84fa104..95389da6e 100644 --- a/applypatch/applypatch.cpp +++ b/applypatch/applypatch.cpp @@ -66,7 +66,7 @@ int LoadFileContents(const char* filename, FileContents* file) { } std::vector<unsigned char> data(file->st.st_size); - std::unique_ptr<FILE, decltype(&ota_fclose)> f(ota_fopen(filename, "rb"), ota_fclose); + unique_file f(ota_fopen(filename, "rb")); if (!f) { printf("failed to open \"%s\": %s\n", filename, strerror(errno)); return -1; @@ -118,7 +118,7 @@ static int LoadPartitionContents(const std::string& filename, FileContents* file std::sort(pairs.begin(), pairs.end()); const char* partition = pieces[1].c_str(); - std::unique_ptr<FILE, decltype(&ota_fclose)> dev(ota_fopen(partition, "rb"), ota_fclose); + unique_file dev(ota_fopen(partition, "rb")); if (!dev) { printf("failed to open emmc partition \"%s\": %s\n", partition, strerror(errno)); return -1; diff --git a/install.cpp b/install.cpp index 98f1e3f36..f124a2688 100644 --- a/install.cpp +++ b/install.cpp @@ -373,6 +373,14 @@ try_update_binary(const char* path, ZipArchiveHandle zip, bool* wipe_cache, } pid_t pid = fork(); + + if (pid == -1) { + close(pipefd[0]); + close(pipefd[1]); + PLOG(ERROR) << "Failed to fork update binary"; + return INSTALL_ERROR; + } + if (pid == 0) { umask(022); close(pipefd[0]); diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index 2efd3004a..f5b01136f 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <map> +#include "ota_io.h" #include <errno.h> #include <fcntl.h> @@ -22,8 +22,10 @@ #include <sys/stat.h> #include <unistd.h> +#include <map> +#include <memory> + #include "config.h" -#include "ota_io.h" static std::map<intptr_t, const char*> filename_cache; static std::string read_fault_file_name = ""; @@ -68,17 +70,33 @@ FILE* ota_fopen(const char* path, const char* mode) { return fh; } -int ota_close(int fd) { +static int __ota_close(int fd) { // descriptors can be reused, so make sure not to leave them in the cache filename_cache.erase(fd); return close(fd); } -int ota_fclose(FILE* fh) { - filename_cache.erase((intptr_t)fh); +void OtaCloser::Close(int fd) { + __ota_close(fd); +} + +int ota_close(unique_fd& fd) { + return __ota_close(fd.release()); +} + +static int __ota_fclose(FILE* fh) { + filename_cache.erase(reinterpret_cast<intptr_t>(fh)); return fclose(fh); } +void OtaFcloser::operator()(FILE* f) { + __ota_fclose(f); +}; + +int ota_fclose(unique_file& fh) { + return __ota_fclose(fh.release()); +} + size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) { if (should_fault_inject(OTAIO_READ)) { auto cached = filename_cache.find((intptr_t)stream); diff --git a/otafault/ota_io.h b/otafault/ota_io.h index e119eef08..395b4230e 100644 --- a/otafault/ota_io.h +++ b/otafault/ota_io.h @@ -26,6 +26,8 @@ #include <stdio.h> #include <sys/stat.h> +#include <memory> + #include <android-base/unique_fd.h> #define OTAIO_CACHE_FNAME "/cache/saved.file" @@ -38,10 +40,6 @@ int ota_open(const char* path, int oflags, mode_t mode); FILE* ota_fopen(const char* filename, const char* mode); -int ota_close(int fd); - -int ota_fclose(FILE* fh); - size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream); ssize_t ota_read(int fd, void* buf, size_t nbyte); @@ -53,11 +51,19 @@ ssize_t ota_write(int fd, const void* buf, size_t nbyte); int ota_fsync(int fd); struct OtaCloser { - static void Close(int fd) { - ota_close(fd); - } + static void Close(int); }; using unique_fd = android::base::unique_fd_impl<OtaCloser>; +int ota_close(unique_fd& fd); + +struct OtaFcloser { + void operator()(FILE*); +}; + +using unique_file = std::unique_ptr<FILE, OtaFcloser>; + +int ota_fclose(unique_file& fh); + #endif diff --git a/tests/component/applypatch_test.cpp b/tests/component/applypatch_test.cpp index 1a0b19113..d178303aa 100644 --- a/tests/component/applypatch_test.cpp +++ b/tests/component/applypatch_test.cpp @@ -83,15 +83,11 @@ class ApplyPatchTest : public ::testing::Test { ASSERT_TRUE(android::base::WriteStringToFile("hello", rand_file)); // set up SHA constants - sha1sum(old_file, &old_sha1); - sha1sum(new_file, &new_sha1); + sha1sum(old_file, &old_sha1, &old_size); + sha1sum(new_file, &new_sha1, &new_size); srand(time(nullptr)); bad_sha1_a = android::base::StringPrintf("%040x", rand()); bad_sha1_b = android::base::StringPrintf("%040x", rand()); - - struct stat st; - stat(&new_file[0], &st); - new_size = st.st_size; } static std::string old_file; @@ -105,6 +101,7 @@ class ApplyPatchTest : public ::testing::Test { static std::string bad_sha1_a; static std::string bad_sha1_b; + static size_t old_size; static size_t new_size; }; @@ -184,7 +181,7 @@ std::string ApplyPatchTest::old_sha1; std::string ApplyPatchTest::new_sha1; std::string ApplyPatchTest::bad_sha1_a; std::string ApplyPatchTest::bad_sha1_b; - +size_t ApplyPatchTest::old_size; size_t ApplyPatchTest::new_size; std::vector<std::unique_ptr<Value>> ApplyPatchFullTest::patches; @@ -211,6 +208,42 @@ TEST_F(ApplyPatchTest, CheckModeFailure) { ASSERT_NE(0, applypatch_check(&old_file[0], sha1s)); } +TEST_F(ApplyPatchTest, CheckModeEmmcTarget) { + // EMMC:old_file:size:sha1 should pass the check. + std::string src_file = + "EMMC:" + old_file + ":" + std::to_string(old_size) + ":" + old_sha1; + std::vector<std::string> sha1s; + ASSERT_EQ(0, applypatch_check(src_file.c_str(), sha1s)); + + // EMMC:old_file:(size-1):sha1:(size+1):sha1 should fail the check. + src_file = "EMMC:" + old_file + ":" + std::to_string(old_size - 1) + ":" + old_sha1 + ":" + + std::to_string(old_size + 1) + ":" + old_sha1; + ASSERT_EQ(1, applypatch_check(src_file.c_str(), sha1s)); + + // EMMC:old_file:(size-1):sha1:size:sha1:(size+1):sha1 should pass the check. + src_file = "EMMC:" + old_file + ":" + + std::to_string(old_size - 1) + ":" + old_sha1 + ":" + + std::to_string(old_size) + ":" + old_sha1 + ":" + + std::to_string(old_size + 1) + ":" + old_sha1; + ASSERT_EQ(0, applypatch_check(src_file.c_str(), sha1s)); + + // EMMC:old_file:(size+1):sha1:(size-1):sha1:size:sha1 should pass the check. + src_file = "EMMC:" + old_file + ":" + + std::to_string(old_size + 1) + ":" + old_sha1 + ":" + + std::to_string(old_size - 1) + ":" + old_sha1 + ":" + + std::to_string(old_size) + ":" + old_sha1; + ASSERT_EQ(0, applypatch_check(src_file.c_str(), sha1s)); + + // EMMC:new_file:(size+1):old_sha1:(size-1):old_sha1:size:old_sha1:size:new_sha1 + // should pass the check. + src_file = "EMMC:" + new_file + ":" + + std::to_string(old_size + 1) + ":" + old_sha1 + ":" + + std::to_string(old_size - 1) + ":" + old_sha1 + ":" + + std::to_string(old_size) + ":" + old_sha1 + ":" + + std::to_string(new_size) + ":" + new_sha1; + ASSERT_EQ(0, applypatch_check(src_file.c_str(), sha1s)); +} + TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) { mangle_file(old_file); std::vector<std::string> sha1s = { old_sha1 }; @@ -307,7 +340,7 @@ TEST_F(ApplyPatchDoubleCacheTest, ApplyDoubleCorruptedInNewLocation) { ASSERT_FALSE(file_cmp(output_loc, new_file)); } -TEST(ApplyPatchModes, InvalidArgs) { +TEST(ApplyPatchModesTest, InvalidArgs) { // At least two args (including the filename). ASSERT_EQ(2, applypatch_modes(1, (const char* []){ "applypatch" })); @@ -315,21 +348,22 @@ TEST(ApplyPatchModes, InvalidArgs) { ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-x" })); } -TEST(ApplyPatchModes, PatchMode) { +TEST(ApplyPatchModesTest, PatchMode) { std::string boot_img = from_testdata_base("boot.img"); size_t boot_img_size; std::string boot_img_sha1; sha1sum(boot_img, &boot_img_sha1, &boot_img_size); std::string recovery_img = from_testdata_base("recovery.img"); - size_t recovery_img_size; std::string recovery_img_sha1; - sha1sum(recovery_img, &recovery_img_sha1, &recovery_img_size); - + size_t size; + sha1sum(recovery_img, &recovery_img_sha1, &size); + std::string recovery_img_size = std::to_string(size); std::string bonus_file = from_testdata_base("bonus.file"); // applypatch -b <bonus-file> <src-file> <tgt-file> <tgt-sha1> <tgt-size> <src-sha1>:<patch> TemporaryFile tmp1; + std::string patch = boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot.p"); std::vector<const char*> args = { "applypatch", "-b", @@ -337,28 +371,32 @@ TEST(ApplyPatchModes, PatchMode) { boot_img.c_str(), tmp1.path, recovery_img_sha1.c_str(), - std::to_string(recovery_img_size).c_str(), - (boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot.p")).c_str() + recovery_img_size.c_str(), + patch.c_str() }; ASSERT_EQ(0, applypatch_modes(args.size(), args.data())); // applypatch <src-file> <tgt-file> <tgt-sha1> <tgt-size> <src-sha1>:<patch> TemporaryFile tmp2; + patch = boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot-with-bonus.p"); std::vector<const char*> args2 = { "applypatch", boot_img.c_str(), tmp2.path, recovery_img_sha1.c_str(), - std::to_string(recovery_img_size).c_str(), - (boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot-with-bonus.p")).c_str() + recovery_img_size.c_str(), + patch.c_str() }; ASSERT_EQ(0, applypatch_modes(args2.size(), args2.data())); // applypatch -b <bonus-file> <src-file> <tgt-file> <tgt-sha1> <tgt-size> \ - // <src-sha1-fake>:<patch1> <src-sha1>:<patch2> + // <src-sha1-fake>:<patch1> <src-sha1>:<patch2> TemporaryFile tmp3; std::string bad_sha1_a = android::base::StringPrintf("%040x", rand()); std::string bad_sha1_b = android::base::StringPrintf("%040x", rand()); + std::string patch1 = bad_sha1_a + ":" + from_testdata_base("recovery-from-boot.p"); + std::string patch2 = boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot.p"); + std::string patch3 = bad_sha1_b + ":" + from_testdata_base("recovery-from-boot.p"); std::vector<const char*> args3 = { "applypatch", "-b", @@ -366,15 +404,85 @@ TEST(ApplyPatchModes, PatchMode) { boot_img.c_str(), tmp3.path, recovery_img_sha1.c_str(), - std::to_string(recovery_img_size).c_str(), - (bad_sha1_a + ":" + from_testdata_base("recovery-from-boot.p")).c_str(), - (boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot.p")).c_str(), - (bad_sha1_b + ":" + from_testdata_base("recovery-from-boot.p")).c_str(), + recovery_img_size.c_str(), + patch1.c_str(), + patch2.c_str(), + patch3.c_str() + }; + ASSERT_EQ(0, applypatch_modes(args3.size(), args3.data())); +} + +TEST(ApplyPatchModesTest, PatchModeEmmcTarget) { + std::string boot_img = from_testdata_base("boot.img"); + size_t boot_img_size; + std::string boot_img_sha1; + sha1sum(boot_img, &boot_img_sha1, &boot_img_size); + + std::string recovery_img = from_testdata_base("recovery.img"); + size_t size; + std::string recovery_img_sha1; + sha1sum(recovery_img, &recovery_img_sha1, &size); + std::string recovery_img_size = std::to_string(size); + + std::string bonus_file = from_testdata_base("bonus.file"); + + // applypatch -b <bonus-file> <src-file> <tgt-file> <tgt-sha1> <tgt-size> <src-sha1>:<patch> + TemporaryFile tmp1; + std::string src_file = + "EMMC:" + boot_img + ":" + std::to_string(boot_img_size) + ":" + boot_img_sha1; + std::string tgt_file = "EMMC:" + std::string(tmp1.path); + std::string patch = boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot.p"); + std::vector<const char*> args = { + "applypatch", + "-b", + bonus_file.c_str(), + src_file.c_str(), + tgt_file.c_str(), + recovery_img_sha1.c_str(), + recovery_img_size.c_str(), + patch.c_str() + }; + ASSERT_EQ(0, applypatch_modes(args.size(), args.data())); + + // applypatch <src-file> <tgt-file> <tgt-sha1> <tgt-size> <src-sha1>:<patch> + TemporaryFile tmp2; + patch = boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot-with-bonus.p"); + tgt_file = "EMMC:" + std::string(tmp2.path); + std::vector<const char*> args2 = { + "applypatch", + src_file.c_str(), + tgt_file.c_str(), + recovery_img_sha1.c_str(), + recovery_img_size.c_str(), + patch.c_str() + }; + ASSERT_EQ(0, applypatch_modes(args2.size(), args2.data())); + + // applypatch -b <bonus-file> <src-file> <tgt-file> <tgt-sha1> <tgt-size> \ + // <src-sha1-fake>:<patch1> <src-sha1>:<patch2> + TemporaryFile tmp3; + tgt_file = "EMMC:" + std::string(tmp3.path); + std::string bad_sha1_a = android::base::StringPrintf("%040x", rand()); + std::string bad_sha1_b = android::base::StringPrintf("%040x", rand()); + std::string patch1 = bad_sha1_a + ":" + from_testdata_base("recovery-from-boot.p"); + std::string patch2 = boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot.p"); + std::string patch3 = bad_sha1_b + ":" + from_testdata_base("recovery-from-boot.p"); + std::vector<const char*> args3 = { + "applypatch", + "-b", + bonus_file.c_str(), + src_file.c_str(), + tgt_file.c_str(), + recovery_img_sha1.c_str(), + recovery_img_size.c_str(), + patch1.c_str(), + patch2.c_str(), + patch3.c_str() }; ASSERT_EQ(0, applypatch_modes(args3.size(), args3.data())); } -TEST(ApplyPatchModes, PatchModeInvalidArgs) { +TEST(ApplyPatchModesTest, PatchModeInvalidArgs) { // Invalid bonus file. ASSERT_NE(0, applypatch_modes(3, (const char* []){ "applypatch", "-b", "/doesntexist" })); @@ -388,9 +496,10 @@ TEST(ApplyPatchModes, PatchModeInvalidArgs) { sha1sum(boot_img, &boot_img_sha1, &boot_img_size); std::string recovery_img = from_testdata_base("recovery.img"); - size_t recovery_img_size; + size_t size; std::string recovery_img_sha1; - sha1sum(recovery_img, &recovery_img_sha1, &recovery_img_size); + sha1sum(recovery_img, &recovery_img_sha1, &size); + std::string recovery_img_size = std::to_string(size); // Bonus file is not supported in flash mode. // applypatch -b <bonus-file> <src-file> <tgt-file> <tgt-sha1> <tgt-size> @@ -402,40 +511,44 @@ TEST(ApplyPatchModes, PatchModeInvalidArgs) { boot_img.c_str(), tmp4.path, recovery_img_sha1.c_str(), - std::to_string(recovery_img_size).c_str() }; + recovery_img_size.c_str() + }; ASSERT_NE(0, applypatch_modes(args4.size(), args4.data())); // Failed to parse patch args. TemporaryFile tmp5; + std::string bad_arg1 = + "invalid-sha1:filename" + from_testdata_base("recovery-from-boot-with-bonus.p"); std::vector<const char*> args5 = { "applypatch", boot_img.c_str(), tmp5.path, recovery_img_sha1.c_str(), - std::to_string(recovery_img_size).c_str(), - ("invalid-sha1:filename" + from_testdata_base("recovery-from-boot-with-bonus.p")).c_str(), + recovery_img_size.c_str(), + bad_arg1.c_str() }; ASSERT_NE(0, applypatch_modes(args5.size(), args5.data())); // Target size cannot be zero. TemporaryFile tmp6; + std::string patch = boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot-with-bonus.p"); std::vector<const char*> args6 = { "applypatch", boot_img.c_str(), tmp6.path, recovery_img_sha1.c_str(), "0", // target size - (boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot-with-bonus.p")).c_str() + patch.c_str() }; ASSERT_NE(0, applypatch_modes(args6.size(), args6.data())); } -TEST(ApplyPatchModes, CheckModeInvalidArgs) { +TEST(ApplyPatchModesTest, CheckModeInvalidArgs) { // Insufficient args. ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-c" })); } -TEST(ApplyPatchModes, SpaceModeInvalidArgs) { +TEST(ApplyPatchModesTest, SpaceModeInvalidArgs) { // Insufficient args. ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-s" })); @@ -449,6 +562,6 @@ TEST(ApplyPatchModes, SpaceModeInvalidArgs) { ASSERT_EQ(0, applypatch_modes(3, (const char* []){ "applypatch", "-s", "0x10" })); } -TEST(ApplyPatchModes, ShowLicenses) { +TEST(ApplyPatchModesTest, ShowLicenses) { ASSERT_EQ(0, applypatch_modes(2, (const char* []){ "applypatch", "-l" })); } diff --git a/updater/install.cpp b/updater/install.cpp index b9bc19e2c..8db5c1fe0 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -509,8 +509,8 @@ Value* PackageExtractFileFn(const char* name, State* state, int argc, Expr* argv return StringValue(""); } - int fd = TEMP_FAILURE_RETRY( - ota_open(dest_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)); + unique_fd fd(TEMP_FAILURE_RETRY( + ota_open(dest_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR))); if (fd == -1) { printf("%s: can't open %s for write: %s\n", name, dest_path.c_str(), strerror(errno)); return StringValue(""); @@ -872,68 +872,67 @@ Value* GetPropFn(const char* name, State* state, int argc, Expr* argv[]) { // per line. # comment lines, blank lines, lines without '=' ignored), // and returns the value for 'key' (or "" if it isn't defined). Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { - if (argc != 2) { - return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %d", name, argc); - } + if (argc != 2) { + return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %d", name, argc); + } - std::vector<std::string> args; - if (!ReadArgs(state, 2, argv, &args)) { - return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); - } - const std::string& filename = args[0]; - const std::string& key = args[1]; + std::vector<std::string> args; + if (!ReadArgs(state, 2, argv, &args)) { + return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); + } + const std::string& filename = args[0]; + const std::string& key = args[1]; - struct stat st; - if (stat(filename.c_str(), &st) < 0) { - return ErrorAbort(state, kFileGetPropFailure, "%s: failed to stat \"%s\": %s", name, - filename.c_str(), strerror(errno)); - } + struct stat st; + if (stat(filename.c_str(), &st) < 0) { + return ErrorAbort(state, kFileGetPropFailure, "%s: failed to stat \"%s\": %s", name, + filename.c_str(), strerror(errno)); + } - constexpr off_t MAX_FILE_GETPROP_SIZE = 65536; - if (st.st_size > MAX_FILE_GETPROP_SIZE) { - return ErrorAbort(state, kFileGetPropFailure, "%s too large for %s (max %lld)", - filename.c_str(), name, static_cast<long long>(MAX_FILE_GETPROP_SIZE)); - } + constexpr off_t MAX_FILE_GETPROP_SIZE = 65536; + if (st.st_size > MAX_FILE_GETPROP_SIZE) { + return ErrorAbort(state, kFileGetPropFailure, "%s too large for %s (max %lld)", + filename.c_str(), name, static_cast<long long>(MAX_FILE_GETPROP_SIZE)); + } - std::string buffer(st.st_size, '\0'); - FILE* f = ota_fopen(filename.c_str(), "rb"); - if (f == nullptr) { - return ErrorAbort(state, kFileOpenFailure, "%s: failed to open %s: %s", name, - filename.c_str(), strerror(errno)); - } + std::string buffer(st.st_size, '\0'); + unique_file f(ota_fopen(filename.c_str(), "rb")); + if (f == nullptr) { + return ErrorAbort(state, kFileOpenFailure, "%s: failed to open %s: %s", name, filename.c_str(), + strerror(errno)); + } - if (ota_fread(&buffer[0], 1, st.st_size, f) != static_cast<size_t>(st.st_size)) { - ErrorAbort(state, kFreadFailure, "%s: failed to read %zu bytes from %s", - name, static_cast<size_t>(st.st_size), filename.c_str()); - ota_fclose(f); - return nullptr; - } + if (ota_fread(&buffer[0], 1, st.st_size, f.get()) != static_cast<size_t>(st.st_size)) { + ErrorAbort(state, kFreadFailure, "%s: failed to read %zu bytes from %s", name, + static_cast<size_t>(st.st_size), filename.c_str()); + return nullptr; + } - ota_fclose(f); + ota_fclose(f); - std::vector<std::string> lines = android::base::Split(buffer, "\n"); - for (size_t i = 0; i < lines.size(); i++) { - std::string line = android::base::Trim(lines[i]); + std::vector<std::string> lines = android::base::Split(buffer, "\n"); + for (size_t i = 0; i < lines.size(); i++) { + std::string line = android::base::Trim(lines[i]); - // comment or blank line: skip to next line - if (line.empty() || line[0] == '#') { - continue; - } - size_t equal_pos = line.find('='); - if (equal_pos == std::string::npos) { - continue; - } + // comment or blank line: skip to next line + if (line.empty() || line[0] == '#') { + continue; + } + size_t equal_pos = line.find('='); + if (equal_pos == std::string::npos) { + continue; + } - // trim whitespace between key and '=' - std::string str = android::base::Trim(line.substr(0, equal_pos)); + // trim whitespace between key and '=' + std::string str = android::base::Trim(line.substr(0, equal_pos)); - // not the key we're looking for - if (key != str) continue; + // not the key we're looking for + if (key != str) continue; - return StringValue(android::base::Trim(line.substr(equal_pos + 1))); - } + return StringValue(android::base::Trim(line.substr(equal_pos + 1))); + } - return StringValue(""); + return StringValue(""); } // apply_patch_space(bytes) @@ -1292,29 +1291,26 @@ Value* GetStageFn(const char* name, State* state, int argc, Expr* argv[]) { } Value* WipeBlockDeviceFn(const char* name, State* state, int argc, Expr* argv[]) { - if (argc != 2) { - return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %d", name, argc); - } - - std::vector<std::string> args; - if (!ReadArgs(state, 2, argv, &args)) { - return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); - } - const std::string& filename = args[0]; - const std::string& len_str = args[1]; - - size_t len; - if (!android::base::ParseUint(len_str.c_str(), &len)) { - return nullptr; - } - int fd = ota_open(filename.c_str(), O_WRONLY, 0644); - // The wipe_block_device function in ext4_utils returns 0 on success and 1 - // for failure. - int status = wipe_block_device(fd, len); + if (argc != 2) { + return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %d", name, argc); + } - ota_close(fd); + std::vector<std::string> args; + if (!ReadArgs(state, 2, argv, &args)) { + return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); + } + const std::string& filename = args[0]; + const std::string& len_str = args[1]; - return StringValue((status == 0) ? "t" : ""); + size_t len; + if (!android::base::ParseUint(len_str.c_str(), &len)) { + return nullptr; + } + unique_fd fd(ota_open(filename.c_str(), O_WRONLY, 0644)); + // The wipe_block_device function in ext4_utils returns 0 on success and 1 + // for failure. + int status = wipe_block_device(fd, len); + return StringValue((status == 0) ? "t" : ""); } Value* EnableRebootFn(const char* name, State* state, int argc, Expr* argv[]) { |