Merge "applypatch: Change the patch parameter to const Value& in Apply{BSDiff,Image}Patch."
am: de07371b03
Change-Id: I2261486420f8e55cfbdd61f130be24f6e4deebf4
This commit is contained in:
commit
e2296b7a25
5 changed files with 49 additions and 47 deletions
|
@ -651,11 +651,11 @@ static int GenerateTarget(const FileContents& source_file, const std::unique_ptr
|
|||
|
||||
int result;
|
||||
if (use_bsdiff) {
|
||||
result = ApplyBSDiffPatch(source_file.data.data(), source_file.data.size(), patch.get(), 0,
|
||||
sink, &ctx);
|
||||
result =
|
||||
ApplyBSDiffPatch(source_file.data.data(), source_file.data.size(), *patch, 0, sink, &ctx);
|
||||
} else {
|
||||
result = ApplyImagePatch(source_file.data.data(), source_file.data.size(), patch.get(), sink,
|
||||
&ctx, bonus_data);
|
||||
result = ApplyImagePatch(source_file.data.data(), source_file.data.size(), *patch, sink, &ctx,
|
||||
bonus_data);
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
|
|
|
@ -65,7 +65,7 @@ void ShowBSDiffLicense() {
|
|||
);
|
||||
}
|
||||
|
||||
int ApplyBSDiffPatch(const unsigned char* old_data, size_t old_size, const Value* patch,
|
||||
int ApplyBSDiffPatch(const unsigned char* old_data, size_t old_size, const Value& patch,
|
||||
size_t patch_offset, SinkFn sink, SHA_CTX* ctx) {
|
||||
auto sha_sink = [&sink, &ctx](const uint8_t* data, size_t len) {
|
||||
len = sink(data, len);
|
||||
|
@ -73,22 +73,20 @@ int ApplyBSDiffPatch(const unsigned char* old_data, size_t old_size, const Value
|
|||
return len;
|
||||
};
|
||||
|
||||
CHECK(patch != nullptr);
|
||||
CHECK_LE(patch_offset, patch->data.size());
|
||||
CHECK_LE(patch_offset, patch.data.size());
|
||||
|
||||
int result = bsdiff::bspatch(old_data, old_size,
|
||||
reinterpret_cast<const uint8_t*>(&patch->data[patch_offset]),
|
||||
patch->data.size() - patch_offset, sha_sink);
|
||||
reinterpret_cast<const uint8_t*>(&patch.data[patch_offset]),
|
||||
patch.data.size() - patch_offset, sha_sink);
|
||||
if (result != 0) {
|
||||
LOG(ERROR) << "bspatch failed, result: " << result;
|
||||
// print SHA1 of the patch in the case of a data error.
|
||||
if (result == 2) {
|
||||
uint8_t digest[SHA_DIGEST_LENGTH];
|
||||
SHA1(reinterpret_cast<const uint8_t*>(patch->data.data() + patch_offset),
|
||||
patch->data.size() - patch_offset, digest);
|
||||
SHA1(reinterpret_cast<const uint8_t*>(patch.data.data() + patch_offset),
|
||||
patch.data.size() - patch_offset, digest);
|
||||
std::string patch_sha1 = print_sha1(digest);
|
||||
LOG(ERROR) << "Patch may be corrupted, offset: " << patch_offset << ", SHA1: "
|
||||
<< patch_sha1;
|
||||
LOG(ERROR) << "Patch may be corrupted, offset: " << patch_offset << ", SHA1: " << patch_sha1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -50,7 +50,7 @@ static inline int32_t Read4(const void *address) {
|
|||
// This function is a wrapper of ApplyBSDiffPatch(). It has a custom sink function to deflate the
|
||||
// patched data and stream the deflated data to output.
|
||||
static bool ApplyBSDiffPatchAndStreamOutput(const uint8_t* src_data, size_t src_len,
|
||||
const Value* patch, size_t patch_offset,
|
||||
const Value& patch, size_t patch_offset,
|
||||
const char* deflate_header, SinkFn sink, SHA_CTX* ctx) {
|
||||
size_t expected_target_length = static_cast<size_t>(Read8(deflate_header + 32));
|
||||
int level = Read4(deflate_header + 40);
|
||||
|
@ -135,48 +135,39 @@ static bool ApplyBSDiffPatchAndStreamOutput(const uint8_t* src_data, size_t src_
|
|||
int ApplyImagePatch(const unsigned char* old_data, size_t old_size, const unsigned char* patch_data,
|
||||
size_t patch_size, SinkFn sink) {
|
||||
Value patch(VAL_BLOB, std::string(reinterpret_cast<const char*>(patch_data), patch_size));
|
||||
|
||||
return ApplyImagePatch(old_data, old_size, &patch, sink, nullptr, nullptr);
|
||||
return ApplyImagePatch(old_data, old_size, patch, sink, nullptr, nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply the patch given in 'patch_filename' to the source data given
|
||||
* by (old_data, old_size). Write the patched output to the 'output'
|
||||
* file, and update the SHA context with the output data as well.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int ApplyImagePatch(const unsigned char* old_data, size_t old_size, const Value* patch, SinkFn sink,
|
||||
int ApplyImagePatch(const unsigned char* old_data, size_t old_size, const Value& patch, SinkFn sink,
|
||||
SHA_CTX* ctx, const Value* bonus_data) {
|
||||
if (patch->data.size() < 12) {
|
||||
if (patch.data.size() < 12) {
|
||||
printf("patch too short to contain header\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// IMGDIFF2 uses CHUNK_NORMAL, CHUNK_DEFLATE, and CHUNK_RAW.
|
||||
// (IMGDIFF1, which is no longer supported, used CHUNK_NORMAL and
|
||||
// CHUNK_GZIP.)
|
||||
size_t pos = 12;
|
||||
const char* header = &patch->data[0];
|
||||
if (memcmp(header, "IMGDIFF2", 8) != 0) {
|
||||
// IMGDIFF2 uses CHUNK_NORMAL, CHUNK_DEFLATE, and CHUNK_RAW. (IMGDIFF1, which is no longer
|
||||
// supported, used CHUNK_NORMAL and CHUNK_GZIP.)
|
||||
const char* const patch_header = patch.data.data();
|
||||
if (memcmp(patch_header, "IMGDIFF2", 8) != 0) {
|
||||
printf("corrupt patch file header (magic number)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int num_chunks = Read4(header + 8);
|
||||
|
||||
int num_chunks = Read4(patch_header + 8);
|
||||
size_t pos = 12;
|
||||
for (int i = 0; i < num_chunks; ++i) {
|
||||
// each chunk's header record starts with 4 bytes.
|
||||
if (pos + 4 > patch->data.size()) {
|
||||
if (pos + 4 > patch.data.size()) {
|
||||
printf("failed to read chunk %d record\n", i);
|
||||
return -1;
|
||||
}
|
||||
int type = Read4(&patch->data[pos]);
|
||||
int type = Read4(patch_header + pos);
|
||||
pos += 4;
|
||||
|
||||
if (type == CHUNK_NORMAL) {
|
||||
const char* normal_header = &patch->data[pos];
|
||||
const char* normal_header = patch_header + pos;
|
||||
pos += 24;
|
||||
if (pos > patch->data.size()) {
|
||||
if (pos > patch.data.size()) {
|
||||
printf("failed to read chunk %d normal header data\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
@ -194,30 +185,32 @@ int ApplyImagePatch(const unsigned char* old_data, size_t old_size, const Value*
|
|||
return -1;
|
||||
}
|
||||
} else if (type == CHUNK_RAW) {
|
||||
const char* raw_header = &patch->data[pos];
|
||||
const char* raw_header = patch_header + pos;
|
||||
pos += 4;
|
||||
if (pos > patch->data.size()) {
|
||||
if (pos > patch.data.size()) {
|
||||
printf("failed to read chunk %d raw header data\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t data_len = static_cast<size_t>(Read4(raw_header));
|
||||
|
||||
if (pos + data_len > patch->data.size()) {
|
||||
if (pos + data_len > patch.data.size()) {
|
||||
printf("failed to read chunk %d raw data\n", i);
|
||||
return -1;
|
||||
}
|
||||
if (ctx) SHA1_Update(ctx, &patch->data[pos], data_len);
|
||||
if (sink(reinterpret_cast<const unsigned char*>(&patch->data[pos]), data_len) != data_len) {
|
||||
if (ctx) {
|
||||
SHA1_Update(ctx, patch_header + pos, data_len);
|
||||
}
|
||||
if (sink(reinterpret_cast<const unsigned char*>(patch_header + pos), data_len) != data_len) {
|
||||
printf("failed to write chunk %d raw data\n", i);
|
||||
return -1;
|
||||
}
|
||||
pos += data_len;
|
||||
} else if (type == CHUNK_DEFLATE) {
|
||||
// deflate chunks have an additional 60 bytes in their chunk header.
|
||||
const char* deflate_header = &patch->data[pos];
|
||||
const char* deflate_header = patch_header + pos;
|
||||
pos += 60;
|
||||
if (pos > patch->data.size()) {
|
||||
if (pos > patch.data.size()) {
|
||||
printf("failed to read chunk %d deflate header data\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ extern std::string cache_temp_source;
|
|||
using SinkFn = std::function<size_t(const unsigned char*, size_t)>;
|
||||
|
||||
// applypatch.cpp
|
||||
|
||||
int ShowLicenses();
|
||||
size_t FreeSpaceForFile(const char* filename);
|
||||
int CacheSizeCheck(size_t bytes);
|
||||
|
@ -66,15 +67,25 @@ int LoadFileContents(const char* filename, FileContents* file);
|
|||
int SaveFileContents(const char* filename, const FileContents* file);
|
||||
|
||||
// bspatch.cpp
|
||||
|
||||
void ShowBSDiffLicense();
|
||||
int ApplyBSDiffPatch(const unsigned char* old_data, size_t old_size, const Value* patch,
|
||||
|
||||
// Applies the bsdiff-patch given in 'patch' (from offset 'patch_offset' to the end) to the source
|
||||
// data given by (old_data, old_size). Writes the patched output through the given 'sink', and
|
||||
// updates the SHA-1 context with the output data. Returns 0 on success.
|
||||
int ApplyBSDiffPatch(const unsigned char* old_data, size_t old_size, const Value& patch,
|
||||
size_t patch_offset, SinkFn sink, SHA_CTX* ctx);
|
||||
|
||||
// imgpatch.cpp
|
||||
int ApplyImagePatch(const unsigned char* old_data, size_t old_size, const Value* patch, SinkFn sink,
|
||||
|
||||
// Applies the imgdiff-patch given in 'patch' to the source data given by (old_data, old_size), with
|
||||
// the optional bonus data. Writes the patched output through the given 'sink', and updates the
|
||||
// SHA-1 context with the output data. Returns 0 on success.
|
||||
int ApplyImagePatch(const unsigned char* old_data, size_t old_size, const Value& patch, SinkFn sink,
|
||||
SHA_CTX* ctx, const Value* bonus_data);
|
||||
|
||||
// freecache.cpp
|
||||
|
||||
int MakeFreeSpaceOnCache(size_t bytes_needed);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1318,7 +1318,7 @@ static int PerformCommandDiff(CommandParameters& params) {
|
|||
|
||||
RangeSinkWriter writer(params.fd, tgt);
|
||||
if (params.cmdname[0] == 'i') { // imgdiff
|
||||
if (ApplyImagePatch(params.buffer.data(), blocks * BLOCKSIZE, &patch_value,
|
||||
if (ApplyImagePatch(params.buffer.data(), blocks * BLOCKSIZE, patch_value,
|
||||
std::bind(&RangeSinkWriter::Write, &writer, std::placeholders::_1,
|
||||
std::placeholders::_2),
|
||||
nullptr, nullptr) != 0) {
|
||||
|
@ -1327,7 +1327,7 @@ static int PerformCommandDiff(CommandParameters& params) {
|
|||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (ApplyBSDiffPatch(params.buffer.data(), blocks * BLOCKSIZE, &patch_value, 0,
|
||||
if (ApplyBSDiffPatch(params.buffer.data(), blocks * BLOCKSIZE, patch_value, 0,
|
||||
std::bind(&RangeSinkWriter::Write, &writer, std::placeholders::_1,
|
||||
std::placeholders::_2),
|
||||
nullptr) != 0) {
|
||||
|
|
Loading…
Reference in a new issue