resolve merge conflicts of 4f86f26 to stage-aosp-master
Change-Id: I3ee609df70c60e16a610913b2c95892c9d74cb3e
This commit is contained in:
+42
-41
@@ -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_
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libcrypto \
|
libcrypto \
|
||||||
libcutils \
|
libcutils \
|
||||||
libbz \
|
libbz \
|
||||||
|
libziparchive \
|
||||||
|
libutils \
|
||||||
libz \
|
libz \
|
||||||
libbase \
|
libbase \
|
||||||
libtune2fs \
|
libtune2fs \
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
@@ -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, ...])
|
||||||
|
|||||||
Reference in New Issue
Block a user