summaryrefslogtreecommitdiffstats
path: root/applypatch/imgdiff.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'applypatch/imgdiff.cpp')
-rw-r--r--applypatch/imgdiff.cpp93
1 files changed, 49 insertions, 44 deletions
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp
index f22502e38..528daf113 100644
--- a/applypatch/imgdiff.cpp
+++ b/applypatch/imgdiff.cpp
@@ -130,6 +130,8 @@
#include <unistd.h>
#include <sys/types.h>
+#include <bsdiff.h>
+
#include "zlib.h"
#include "imgdiff.h"
#include "utils.h"
@@ -144,8 +146,6 @@ typedef struct {
size_t source_start;
size_t source_len;
- off_t* I; // used by bsdiff
-
// --- for CHUNK_DEFLATE chunks only: ---
// original (compressed) deflate data
@@ -179,10 +179,6 @@ static int fileentry_compare(const void* a, const void* b) {
}
}
-// from bsdiff.c
-int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* newdata, off_t newsize,
- const char* patch_filename);
-
unsigned char* ReadZip(const char* filename,
int* num_chunks, ImageChunk** chunks,
int include_pseudo_chunk) {
@@ -193,7 +189,7 @@ unsigned char* ReadZip(const char* filename,
}
size_t sz = static_cast<size_t>(st.st_size);
- unsigned char* img = reinterpret_cast<unsigned char*>(malloc(sz));
+ unsigned char* img = static_cast<unsigned char*>(malloc(sz));
FILE* f = fopen(filename, "rb");
if (fread(img, 1, sz, f) != sz) {
printf("failed to read \"%s\" %s\n", filename, strerror(errno));
@@ -220,7 +216,7 @@ unsigned char* ReadZip(const char* filename,
int cdcount = Read2(img+i+8);
int cdoffset = Read4(img+i+16);
- ZipFileEntry* temp_entries = reinterpret_cast<ZipFileEntry*>(malloc(
+ ZipFileEntry* temp_entries = static_cast<ZipFileEntry*>(malloc(
cdcount * sizeof(ZipFileEntry)));
int entrycount = 0;
@@ -228,6 +224,7 @@ unsigned char* ReadZip(const char* filename,
for (i = 0; i < cdcount; ++i) {
if (!(cd[0] == 0x50 && cd[1] == 0x4b && cd[2] == 0x01 && cd[3] == 0x02)) {
printf("bad central directory entry %d\n", i);
+ free(temp_entries);
return NULL;
}
@@ -238,7 +235,7 @@ unsigned char* ReadZip(const char* filename,
int mlen = Read2(cd+32); // file comment len
int hoffset = Read4(cd+42); // local header offset
- char* filename = reinterpret_cast<char*>(malloc(nlen+1));
+ char* filename = static_cast<char*>(malloc(nlen+1));
memcpy(filename, cd+46, nlen);
filename[nlen] = '\0';
@@ -287,7 +284,7 @@ unsigned char* ReadZip(const char* filename,
#endif
*num_chunks = 0;
- *chunks = reinterpret_cast<ImageChunk*>(malloc((entrycount*2+2) * sizeof(ImageChunk)));
+ *chunks = static_cast<ImageChunk*>(malloc((entrycount*2+2) * sizeof(ImageChunk)));
ImageChunk* curr = *chunks;
if (include_pseudo_chunk) {
@@ -296,7 +293,6 @@ unsigned char* ReadZip(const char* filename,
curr->len = st.st_size;
curr->data = img;
curr->filename = NULL;
- curr->I = NULL;
++curr;
++*num_chunks;
}
@@ -311,10 +307,9 @@ unsigned char* ReadZip(const char* filename,
curr->deflate_len = temp_entries[nextentry].deflate_len;
curr->deflate_data = img + pos;
curr->filename = temp_entries[nextentry].filename;
- curr->I = NULL;
curr->len = temp_entries[nextentry].uncomp_len;
- curr->data = reinterpret_cast<unsigned char*>(malloc(curr->len));
+ curr->data = static_cast<unsigned char*>(malloc(curr->len));
z_stream strm;
strm.zalloc = Z_NULL;
@@ -326,6 +321,10 @@ unsigned char* ReadZip(const char* filename,
// -15 means we are decoding a 'raw' deflate stream; zlib will
// not expect zlib headers.
int ret = inflateInit2(&strm, -15);
+ if (ret < 0) {
+ printf("failed to initialize inflate: %d\n", ret);
+ return NULL;
+ }
strm.avail_out = curr->len;
strm.next_out = curr->data;
@@ -356,7 +355,6 @@ unsigned char* ReadZip(const char* filename,
}
curr->data = img + pos;
curr->filename = NULL;
- curr->I = NULL;
pos += curr->len;
++*num_chunks;
@@ -385,7 +383,7 @@ unsigned char* ReadImage(const char* filename,
}
size_t sz = static_cast<size_t>(st.st_size);
- unsigned char* img = reinterpret_cast<unsigned char*>(malloc(sz + 4));
+ unsigned char* img = static_cast<unsigned char*>(malloc(sz + 4));
FILE* f = fopen(filename, "rb");
if (fread(img, 1, sz, f) != sz) {
printf("failed to read \"%s\" %s\n", filename, strerror(errno));
@@ -407,7 +405,6 @@ unsigned char* ReadImage(const char* filename,
while (pos < sz) {
unsigned char* p = img+pos;
- bool processed_deflate = false;
if (sz - pos >= 4 &&
p[0] == 0x1f && p[1] == 0x8b &&
p[2] == 0x08 && // deflate compression
@@ -416,7 +413,7 @@ unsigned char* ReadImage(const char* filename,
size_t chunk_offset = pos;
*num_chunks += 3;
- *chunks = reinterpret_cast<ImageChunk*>(realloc(*chunks,
+ *chunks = static_cast<ImageChunk*>(realloc(*chunks,
*num_chunks * sizeof(ImageChunk)));
ImageChunk* curr = *chunks + (*num_chunks-3);
@@ -425,7 +422,6 @@ unsigned char* ReadImage(const char* filename,
curr->type = CHUNK_NORMAL;
curr->len = GZIP_HEADER_LEN;
curr->data = p;
- curr->I = NULL;
pos += curr->len;
p += curr->len;
@@ -433,7 +429,6 @@ unsigned char* ReadImage(const char* filename,
curr->type = CHUNK_DEFLATE;
curr->filename = NULL;
- curr->I = NULL;
// We must decompress this chunk in order to discover where it
// ends, and so we can put the uncompressed data and its length
@@ -441,7 +436,7 @@ unsigned char* ReadImage(const char* filename,
size_t allocated = 32768;
curr->len = 0;
- curr->data = reinterpret_cast<unsigned char*>(malloc(allocated));
+ curr->data = static_cast<unsigned char*>(malloc(allocated));
curr->start = pos;
curr->deflate_data = p;
@@ -455,34 +450,37 @@ unsigned char* ReadImage(const char* filename,
// -15 means we are decoding a 'raw' deflate stream; zlib will
// not expect zlib headers.
int ret = inflateInit2(&strm, -15);
+ if (ret < 0) {
+ printf("failed to initialize inflate: %d\n", ret);
+ return NULL;
+ }
do {
strm.avail_out = allocated - curr->len;
strm.next_out = curr->data + curr->len;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret < 0) {
- if (!processed_deflate) {
- // This is the first chunk, assume that it's just a spurious
- // gzip header instead of a real one.
- break;
- }
- printf("Error: inflate failed [%s] at file offset [%zu]\n"
- "imgdiff only supports gzip kernel compression,"
- " did you try CONFIG_KERNEL_LZO?\n",
+ printf("Warning: inflate failed [%s] at offset [%zu],"
+ " treating as a normal chunk\n",
strm.msg, chunk_offset);
- free(img);
- return NULL;
+ break;
}
curr->len = allocated - strm.avail_out;
if (strm.avail_out == 0) {
allocated *= 2;
- curr->data = reinterpret_cast<unsigned char*>(realloc(curr->data, allocated));
+ curr->data = static_cast<unsigned char*>(realloc(curr->data, allocated));
}
- processed_deflate = true;
} while (ret != Z_STREAM_END);
curr->deflate_len = sz - strm.avail_in - pos;
inflateEnd(&strm);
+
+ if (ret < 0) {
+ free(curr->data);
+ *num_chunks -= 2;
+ continue;
+ }
+
pos += curr->deflate_len;
p += curr->deflate_len;
++curr;
@@ -493,7 +491,6 @@ unsigned char* ReadImage(const char* filename,
curr->start = pos;
curr->len = GZIP_FOOTER_LEN;
curr->data = img+pos;
- curr->I = NULL;
pos += curr->len;
p += curr->len;
@@ -514,10 +511,9 @@ unsigned char* ReadImage(const char* filename,
// Reallocate the list for every chunk; we expect the number of
// chunks to be small (5 for typical boot and recovery images).
++*num_chunks;
- *chunks = reinterpret_cast<ImageChunk*>(realloc(*chunks, *num_chunks * sizeof(ImageChunk)));
+ *chunks = static_cast<ImageChunk*>(realloc(*chunks, *num_chunks * sizeof(ImageChunk)));
ImageChunk* curr = *chunks + (*num_chunks-1);
curr->start = pos;
- curr->I = NULL;
// 'pos' is not the offset of the start of a gzip chunk, so scan
// forward until we find a gzip header.
@@ -565,10 +561,18 @@ int TryReconstruction(ImageChunk* chunk, unsigned char* out) {
int ret;
ret = deflateInit2(&strm, chunk->level, chunk->method, chunk->windowBits,
chunk->memLevel, chunk->strategy);
+ if (ret < 0) {
+ printf("failed to initialize deflate: %d\n", ret);
+ return -1;
+ }
do {
strm.avail_out = BUFFER_SIZE;
strm.next_out = out;
ret = deflate(&strm, Z_FINISH);
+ if (ret < 0) {
+ printf("failed to deflate: %d\n", ret);
+ return -1;
+ }
size_t have = BUFFER_SIZE - strm.avail_out;
if (memcmp(out, chunk->deflate_data+p, have) != 0) {
@@ -598,8 +602,7 @@ int ReconstructDeflateChunk(ImageChunk* chunk) {
return -1;
}
- size_t p = 0;
- unsigned char* out = reinterpret_cast<unsigned char*>(malloc(BUFFER_SIZE));
+ unsigned char* out = static_cast<unsigned char*>(malloc(BUFFER_SIZE));
// We only check two combinations of encoder parameters: level 6
// (the default) and level 9 (the maximum).
@@ -645,7 +648,7 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) {
close(fd); // temporary file is created and we don't need its file
// descriptor
- int r = bsdiff(src->data, src->len, &(src->I), tgt->data, tgt->len, ptemp);
+ int r = bsdiff::bsdiff(src->data, src->len, tgt->data, tgt->len, ptemp);
if (r != 0) {
printf("bsdiff() failed: %d\n", r);
return NULL;
@@ -660,7 +663,7 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) {
size_t sz = static_cast<size_t>(st.st_size);
// TODO: Memory leak on error return.
- unsigned char* data = reinterpret_cast<unsigned char*>(malloc(sz));
+ unsigned char* data = static_cast<unsigned char*>(malloc(sz));
if (tgt->type == CHUNK_NORMAL && tgt->len <= sz) {
unlink(ptemp);
@@ -827,7 +830,7 @@ int main(int argc, char** argv) {
return 1;
}
bonus_size = st.st_size;
- bonus_data = reinterpret_cast<unsigned char*>(malloc(bonus_size));
+ bonus_data = static_cast<unsigned char*>(malloc(bonus_size));
FILE* f = fopen(argv[2], "rb");
if (f == NULL) {
printf("failed to open bonus file %s: %s\n", argv[2], strerror(errno));
@@ -844,7 +847,6 @@ int main(int argc, char** argv) {
}
if (argc != 4) {
- usage:
printf("usage: %s [-z] [-b <bonus-file>] <src-img> <tgt-img> <patch-file>\n",
argv[0]);
return 2;
@@ -974,9 +976,9 @@ int main(int argc, char** argv) {
DumpChunks(src_chunks, num_src_chunks);
printf("Construct patches for %d chunks...\n", num_tgt_chunks);
- unsigned char** patch_data = reinterpret_cast<unsigned char**>(malloc(
+ unsigned char** patch_data = static_cast<unsigned char**>(malloc(
num_tgt_chunks * sizeof(unsigned char*)));
- size_t* patch_size = reinterpret_cast<size_t*>(malloc(num_tgt_chunks * sizeof(size_t)));
+ size_t* patch_size = static_cast<size_t*>(malloc(num_tgt_chunks * sizeof(size_t)));
for (i = 0; i < num_tgt_chunks; ++i) {
if (zip_mode) {
ImageChunk* src;
@@ -990,7 +992,7 @@ int main(int argc, char** argv) {
} else {
if (i == 1 && bonus_data) {
printf(" using %zu bytes of bonus data for chunk %d\n", bonus_size, i);
- src_chunks[i].data = reinterpret_cast<unsigned char*>(realloc(src_chunks[i].data,
+ src_chunks[i].data = static_cast<unsigned char*>(realloc(src_chunks[i].data,
src_chunks[i].len + bonus_size));
memcpy(src_chunks[i].data+src_chunks[i].len, bonus_data, bonus_size);
src_chunks[i].len += bonus_size;
@@ -1077,6 +1079,9 @@ int main(int argc, char** argv) {
}
}
+ free(patch_data);
+ free(patch_size);
+
fclose(f);
return 0;