resolve merge conflicts of 4f86f26 to stage-aosp-master

Change-Id: I3ee609df70c60e16a610913b2c95892c9d74cb3e
This commit is contained in:
Tao Bao
2016-11-15 23:13:24 -08:00
6 changed files with 204 additions and 144 deletions
+42 -41
View File
@@ -18,52 +18,53 @@
#define _ERROR_CODE_H_ #define _ERROR_CODE_H_
enum ErrorCode { enum ErrorCode {
kNoError = -1, kNoError = -1,
kLowBattery = 20, kLowBattery = 20,
kZipVerificationFailure, kZipVerificationFailure,
kZipOpenFailure, kZipOpenFailure,
kBootreasonInBlacklist kBootreasonInBlacklist
}; };
enum CauseCode { enum CauseCode {
kNoCause = -1, kNoCause = -1,
kArgsParsingFailure = 100, kArgsParsingFailure = 100,
kStashCreationFailure, kStashCreationFailure,
kFileOpenFailure, kFileOpenFailure,
kLseekFailure, kLseekFailure,
kFreadFailure, kFreadFailure,
kFwriteFailure, kFwriteFailure,
kFsyncFailure, kFsyncFailure,
kLibfecFailure, kLibfecFailure,
kFileGetPropFailure, kFileGetPropFailure,
kFileRenameFailure, kFileRenameFailure,
kSymlinkFailure, kSymlinkFailure,
kSetMetadataFailure, kSetMetadataFailure,
kTune2FsFailure, kTune2FsFailure,
kRebootFailure, kRebootFailure,
kVendorFailure = 200 kPackageExtractFileFailure,
kVendorFailure = 200
}; };
enum UncryptErrorCode { enum UncryptErrorCode {
kUncryptNoError = -1, kUncryptNoError = -1,
kUncryptErrorPlaceholder = 50, kUncryptErrorPlaceholder = 50,
kUncryptTimeoutError = 100, kUncryptTimeoutError = 100,
kUncryptFileRemoveError, kUncryptFileRemoveError,
kUncryptFileOpenError, kUncryptFileOpenError,
kUncryptSocketOpenError, kUncryptSocketOpenError,
kUncryptSocketWriteError, kUncryptSocketWriteError,
kUncryptSocketListenError, kUncryptSocketListenError,
kUncryptSocketAcceptError, kUncryptSocketAcceptError,
kUncryptFstabReadError, kUncryptFstabReadError,
kUncryptFileStatError, kUncryptFileStatError,
kUncryptBlockOpenError, kUncryptBlockOpenError,
kUncryptIoctlError, kUncryptIoctlError,
kUncryptReadError, kUncryptReadError,
kUncryptWriteError, kUncryptWriteError,
kUncryptFileSyncError, kUncryptFileSyncError,
kUncryptFileCloseError, kUncryptFileCloseError,
kUncryptFileRenameError, kUncryptFileRenameError,
kUncryptPackageMissingError, kUncryptPackageMissingError,
}; };
#endif #endif // _ERROR_CODE_H_
+2
View File
@@ -92,6 +92,8 @@ LOCAL_STATIC_LIBRARIES := \
libcrypto \ libcrypto \
libcutils \ libcutils \
libbz \ libbz \
libziparchive \
libutils \
libz \ libz \
libbase \ libbase \
libtune2fs \ libtune2fs \
+9
View File
@@ -19,6 +19,15 @@
#include <stdlib.h> #include <stdlib.h>
// Zip entries in ziptest_valid.zip.
static const std::string kATxtContents("abcdefghabcdefgh\n");
static const std::string kBTxtContents("abcdefgh\n");
// echo -n -e "abcdefghabcdefgh\n" | sha1sum
static const std::string kATxtSha1Sum("32c96a03dc8cd20097940f351bca6261ee5a1643");
// echo -n -e "abcdefgh\n" | sha1sum
static const std::string kBTxtSha1Sum("e414af7161c9554089f4106d6f1797ef14a73666");
static const char* data_root = getenv("ANDROID_DATA"); static const char* data_root = getenv("ANDROID_DATA");
static std::string from_testdata_base(const std::string& fname) { static std::string from_testdata_base(const std::string& fname) {
+75 -17
View File
@@ -24,35 +24,40 @@
#include <android-base/properties.h> #include <android-base/properties.h>
#include <android-base/test_utils.h> #include <android-base/test_utils.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <ziparchive/zip_archive.h>
#include "common/test_constants.h"
#include "edify/expr.h" #include "edify/expr.h"
#include "error_code.h" #include "error_code.h"
#include "updater/install.h" #include "updater/install.h"
#include "updater/updater.h"
struct selabel_handle *sehandle = nullptr; struct selabel_handle *sehandle = nullptr;
static void expect(const char* expected, const char* expr_str, CauseCode cause_code) { static void expect(const char* expected, const char* expr_str, CauseCode cause_code,
Expr* e; UpdaterInfo* info = nullptr) {
int error_count; Expr* e;
EXPECT_EQ(parse_string(expr_str, &e, &error_count), 0); int error_count = 0;
ASSERT_EQ(0, parse_string(expr_str, &e, &error_count));
ASSERT_EQ(0, error_count);
State state(expr_str, nullptr); State state(expr_str, info);
std::string result; std::string result;
bool status = Evaluate(&state, e, &result); bool status = Evaluate(&state, e, &result);
if (expected == nullptr) { if (expected == nullptr) {
EXPECT_FALSE(status); ASSERT_FALSE(status);
} else { } else {
EXPECT_STREQ(expected, result.c_str()); ASSERT_TRUE(status);
} ASSERT_STREQ(expected, result.c_str());
}
// Error code is set in updater/updater.cpp only, by parsing State.errmsg. // Error code is set in updater/updater.cpp only, by parsing State.errmsg.
EXPECT_EQ(kNoError, state.error_code); ASSERT_EQ(kNoError, state.error_code);
// Cause code should always be available.
EXPECT_EQ(cause_code, state.cause_code);
// Cause code should always be available.
ASSERT_EQ(cause_code, state.cause_code);
} }
class UpdaterTest : public ::testing::Test { class UpdaterTest : public ::testing::Test {
@@ -264,3 +269,56 @@ TEST_F(UpdaterTest, symlink) {
ASSERT_EQ(0, unlink(src1.c_str())); ASSERT_EQ(0, unlink(src1.c_str()));
ASSERT_EQ(0, unlink(src2.c_str())); ASSERT_EQ(0, unlink(src2.c_str()));
} }
// TODO: Test extracting to block device.
TEST_F(UpdaterTest, package_extract_file) {
// package_extract_file expects 1 or 2 arguments.
expect(nullptr, "package_extract_file()", kArgsParsingFailure);
expect(nullptr, "package_extract_file(\"arg1\", \"arg2\", \"arg3\")", kArgsParsingFailure);
std::string zip_path = from_testdata_base("ziptest_valid.zip");
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle));
// Need to set up the ziphandle.
UpdaterInfo updater_info;
updater_info.package_zip = handle;
// Two-argument version.
TemporaryFile temp_file1;
std::string script("package_extract_file(\"a.txt\", \"" + std::string(temp_file1.path) + "\")");
expect("t", script.c_str(), kNoCause, &updater_info);
// Verify the extracted entry.
std::string data;
ASSERT_TRUE(android::base::ReadFileToString(temp_file1.path, &data));
ASSERT_EQ(kATxtContents, data);
// Now extract another entry to the same location, which should overwrite.
script = "package_extract_file(\"b.txt\", \"" + std::string(temp_file1.path) + "\")";
expect("t", script.c_str(), kNoCause, &updater_info);
ASSERT_TRUE(android::base::ReadFileToString(temp_file1.path, &data));
ASSERT_EQ(kBTxtContents, data);
// Missing zip entry. The two-argument version doesn't abort.
script = "package_extract_file(\"doesntexist\", \"" + std::string(temp_file1.path) + "\")";
expect("", script.c_str(), kNoCause, &updater_info);
// Extract to /dev/full should fail.
script = "package_extract_file(\"a.txt\", \"/dev/full\")";
expect("", script.c_str(), kNoCause, &updater_info);
// One-argument version.
script = "sha1_check(package_extract_file(\"a.txt\"))";
expect(kATxtSha1Sum.c_str(), script.c_str(), kNoCause, &updater_info);
script = "sha1_check(package_extract_file(\"b.txt\"))";
expect(kBTxtSha1Sum.c_str(), script.c_str(), kNoCause, &updater_info);
// Missing entry. The one-argument version aborts the evaluation.
script = "package_extract_file(\"doesntexist\")";
expect(nullptr, script.c_str(), kPackageExtractFileFailure, &updater_info);
CloseArchive(handle);
}
-3
View File
@@ -30,9 +30,6 @@
#include "common/test_constants.h" #include "common/test_constants.h"
static const std::string kATxtContents("abcdefghabcdefgh\n");
static const std::string kBTxtContents("abcdefgh\n");
TEST(ZipTest, ExtractPackageRecursive) { TEST(ZipTest, ExtractPackageRecursive) {
std::string zip_path = from_testdata_base("ziptest_valid.zip"); std::string zip_path = from_testdata_base("ziptest_valid.zip");
ZipArchiveHandle handle; ZipArchiveHandle handle;
+76 -83
View File
@@ -477,93 +477,86 @@ Value* PackageExtractDirFn(const char* name, State* state,
return StringValue(success ? "t" : ""); return StringValue(success ? "t" : "");
} }
// package_extract_file(package_file[, dest_file])
// Extracts a single package_file from the update package and writes it to dest_file,
// overwriting existing files if necessary. Without the dest_file argument, returns the
// contents of the package file as a binary blob.
Value* PackageExtractFileFn(const char* name, State* state, int argc, Expr* argv[]) {
if (argc < 1 || argc > 2) {
return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 or 2 args, got %d", name, argc);
}
// package_extract_file(package_path, destination_path) if (argc == 2) {
// or // The two-argument version extracts to a file.
// package_extract_file(package_path)
// to return the entire contents of the file as the result of this std::vector<std::string> args;
// function (the char* returned is actually a FileContents*). if (!ReadArgs(state, 2, argv, &args)) {
Value* PackageExtractFileFn(const char* name, State* state, return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %d args", name, argc);
int argc, Expr* argv[]) {
if (argc < 1 || argc > 2) {
return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 or 2 args, got %d",
name, argc);
} }
bool success = false; const std::string& zip_path = args[0];
const std::string& dest_path = args[1];
if (argc == 2) { ZipArchiveHandle za = static_cast<UpdaterInfo*>(state->cookie)->package_zip;
// The two-argument version extracts to a file. ZipString zip_string_path(zip_path.c_str());
ZipEntry entry;
ZipArchiveHandle za = ((UpdaterInfo*)(state->cookie))->package_zip; if (FindEntry(za, zip_string_path, &entry) != 0) {
printf("%s: no %s in package\n", name, zip_path.c_str());
std::vector<std::string> args; return StringValue("");
if (!ReadArgs(state, 2, argv, &args)) {
return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %d args", name,
argc);
}
const std::string& zip_path = args[0];
const std::string& dest_path = args[1];
ZipString zip_string_path(zip_path.c_str());
ZipEntry entry;
if (FindEntry(za, zip_string_path, &entry) != 0) {
printf("%s: no %s in package\n", name, zip_path.c_str());
return StringValue("");
}
int 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("");
}
success = ExtractEntryToFile(za, &entry, fd);
if (ota_fsync(fd) == -1) {
printf("fsync of \"%s\" failed: %s\n", dest_path.c_str(), strerror(errno));
success = false;
}
if (ota_close(fd) == -1) {
printf("close of \"%s\" failed: %s\n", dest_path.c_str(), strerror(errno));
success = false;
}
return StringValue(success ? "t" : "");
} else {
// The one-argument version returns the contents of the file
// as the result.
std::vector<std::string> args;
if (!ReadArgs(state, 1, argv, &args)) {
return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %d args", name,
argc);
}
const std::string& zip_path = args[0];
Value* v = new Value(VAL_INVALID, "");
ZipArchiveHandle za = ((UpdaterInfo*)(state->cookie))->package_zip;
ZipString zip_string_path(zip_path.c_str());
ZipEntry entry;
if (FindEntry(za, zip_string_path, &entry) != 0) {
printf("%s: no %s in package\n", name, zip_path.c_str());
return v;
}
v->data.resize(entry.uncompressed_length);
if (ExtractToMemory(za, &entry, reinterpret_cast<uint8_t*>(&v->data[0]),
v->data.size()) != 0) {
printf("%s: faled to extract %zu bytes to memory\n", name, v->data.size());
} else {
success = true;
}
if (!success) {
v->data.clear();
} else {
v->type = VAL_BLOB;
}
return v;
} }
int 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("");
}
bool success = true;
int32_t ret = ExtractEntryToFile(za, &entry, fd);
if (ret != 0) {
printf("%s: Failed to extract entry \"%s\" (%u bytes) to \"%s\": %s\n", name,
zip_path.c_str(), entry.uncompressed_length, dest_path.c_str(), ErrorCodeString(ret));
success = false;
}
if (ota_fsync(fd) == -1) {
printf("fsync of \"%s\" failed: %s\n", dest_path.c_str(), strerror(errno));
success = false;
}
if (ota_close(fd) == -1) {
printf("close of \"%s\" failed: %s\n", dest_path.c_str(), strerror(errno));
success = false;
}
return StringValue(success ? "t" : "");
} else {
// The one-argument version returns the contents of the file as the result.
std::vector<std::string> args;
if (!ReadArgs(state, 1, argv, &args)) {
return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %d args", name, argc);
}
const std::string& zip_path = args[0];
ZipArchiveHandle za = static_cast<UpdaterInfo*>(state->cookie)->package_zip;
ZipString zip_string_path(zip_path.c_str());
ZipEntry entry;
if (FindEntry(za, zip_string_path, &entry) != 0) {
return ErrorAbort(state, kPackageExtractFileFailure, "%s(): no %s in package", name,
zip_path.c_str());
}
std::string buffer;
buffer.resize(entry.uncompressed_length);
int32_t ret = ExtractToMemory(za, &entry, reinterpret_cast<uint8_t*>(&buffer[0]), buffer.size());
if (ret != 0) {
return ErrorAbort(state, kPackageExtractFileFailure,
"%s: Failed to extract entry \"%s\" (%zu bytes) to memory: %s", name,
zip_path.c_str(), buffer.size(), ErrorCodeString(ret));
}
return new Value(VAL_BLOB, buffer);
}
} }
// symlink(target, [src1, src2, ...]) // symlink(target, [src1, src2, ...])