Loading applypatch/Android.mk +69 −21 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ LOCAL_PATH := $(call my-dir) # libapplypatch (static library) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := \ applypatch.cpp \ bspatch.cpp \ Loading @@ -26,11 +25,11 @@ LOCAL_SRC_FILES := \ utils.cpp LOCAL_MODULE := libapplypatch LOCAL_MODULE_TAGS := eng LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_STATIC_LIBRARIES += \ LOCAL_STATIC_LIBRARIES := \ libotafault \ libbase \ libcrypto \ Loading @@ -42,36 +41,45 @@ include $(BUILD_STATIC_LIBRARY) # libimgpatch (static library) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp LOCAL_SRC_FILES := \ bspatch.cpp \ imgpatch.cpp \ utils.cpp LOCAL_MODULE := libimgpatch LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_STATIC_LIBRARIES += libcrypto libbz libz LOCAL_STATIC_LIBRARIES := \ libcrypto \ libbz \ libz LOCAL_CFLAGS := -Werror include $(BUILD_STATIC_LIBRARY) # libimgpatch (host static library) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp LOCAL_SRC_FILES := \ bspatch.cpp \ imgpatch.cpp \ utils.cpp LOCAL_MODULE := libimgpatch LOCAL_MODULE_HOST_OS := linux LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_STATIC_LIBRARIES += libcrypto libbz libz LOCAL_STATIC_LIBRARIES := \ libcrypto \ libbz \ libz LOCAL_CFLAGS := -Werror include $(BUILD_HOST_STATIC_LIBRARY) # libapplypatch_modes (static library) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := \ applypatch_modes.cpp LOCAL_MODULE := libapplypatch_modes Loading @@ -87,7 +95,6 @@ include $(BUILD_STATIC_LIBRARY) # applypatch (target executable) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := applypatch_main.cpp LOCAL_MODULE := applypatch LOCAL_C_INCLUDES := bootable/recovery Loading @@ -106,18 +113,59 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_CFLAGS := -Werror include $(BUILD_EXECUTABLE) libimgdiff_src_files := \ imgdiff.cpp \ utils.cpp # libbsdiff is compiled with -D_FILE_OFFSET_BITS=64. libimgdiff_cflags := \ -Werror \ -D_FILE_OFFSET_BITS=64 libimgdiff_static_libraries := \ libbsdiff \ libz # libimgdiff (static library) # =============================== include $(CLEAR_VARS) LOCAL_SRC_FILES := \ $(libimgdiff_src_files) LOCAL_MODULE := libimgdiff LOCAL_CFLAGS := \ $(libimgdiff_cflags) LOCAL_STATIC_LIBRARIES := \ $(libimgdiff_static_libraries) LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include include $(BUILD_STATIC_LIBRARY) # libimgdiff (host static library) # =============================== include $(CLEAR_VARS) LOCAL_SRC_FILES := \ $(libimgdiff_src_files) LOCAL_MODULE := libimgdiff LOCAL_CFLAGS := \ $(libimgdiff_cflags) LOCAL_STATIC_LIBRARIES := \ $(libimgdiff_static_libraries) LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include include $(BUILD_HOST_STATIC_LIBRARY) # imgdiff (host static executable) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := imgdiff.cpp utils.cpp LOCAL_SRC_FILES := imgdiff_main.cpp LOCAL_MODULE := imgdiff LOCAL_STATIC_LIBRARIES += \ libbsdiff \ LOCAL_CFLAGS := -Werror LOCAL_STATIC_LIBRARIES := \ libimgdiff \ $(libimgdiff_static_libraries) \ libbz \ libdivsufsort64 \ libdivsufsort \ libz LOCAL_CFLAGS := -Werror LOCAL_FORCE_STATIC_EXECUTABLE := true libdivsufsort64 include $(BUILD_HOST_EXECUTABLE) applypatch/imgdiff.cpp +24 −30 Original line number Diff line number Diff line Loading @@ -121,19 +121,19 @@ * information that is stored on the system partition. */ #include "applypatch/imgdiff.h" #include <errno.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <unistd.h> #include <sys/types.h> #include <unistd.h> #include <bsdiff.h> #include <zlib.h> #include "zlib.h" #include "imgdiff.h" #include "utils.h" typedef struct { Loading Loading @@ -374,8 +374,7 @@ unsigned char* ReadZip(const char* filename, * return value when done with all the chunks. Returns NULL on * failure. */ unsigned char* ReadImage(const char* filename, int* num_chunks, ImageChunk** chunks) { unsigned char* ReadImage(const char* filename, int* num_chunks, ImageChunk** chunks) { struct stat st; if (stat(filename, &st) != 0) { printf("failed to stat \"%s\": %s\n", filename, strerror(errno)); Loading Loading @@ -413,8 +412,7 @@ unsigned char* ReadImage(const char* filename, size_t chunk_offset = pos; *num_chunks += 3; *chunks = static_cast<ImageChunk*>(realloc(*chunks, *num_chunks * sizeof(ImageChunk))); *chunks = static_cast<ImageChunk*>(realloc(*chunks, *num_chunks * sizeof(ImageChunk))); ImageChunk* curr = *chunks + (*num_chunks-3); // create a normal chunk for the header. Loading Loading @@ -502,8 +500,7 @@ unsigned char* ReadImage(const char* filename, // the decompression. size_t footer_size = Read4(p-4); if (footer_size != curr[-2].len) { printf("Error: footer size %zu != decompressed size %zu\n", footer_size, curr[-2].len); printf("Error: footer size %zu != decompressed size %zu\n", footer_size, curr[-2].len); free(img); return NULL; } Loading Loading @@ -637,7 +634,11 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) { } } #if defined(__ANDROID__) char ptemp[] = "/data/local/tmp/imgdiff-patch-XXXXXX"; #else char ptemp[] = "/tmp/imgdiff-patch-XXXXXX"; #endif int fd = mkstemp(ptemp); if (fd == -1) { Loading Loading @@ -793,10 +794,8 @@ void MergeAdjacentNormalChunks(ImageChunk* chunks, int* num_chunks) { *num_chunks = out; } ImageChunk* FindChunkByName(const char* name, ImageChunk* chunks, int num_chunks) { int i; for (i = 0; i < num_chunks; ++i) { ImageChunk* FindChunkByName(const char* name, ImageChunk* chunks, int num_chunks) { for (int i = 0; i < num_chunks; ++i) { if (chunks[i].type == CHUNK_DEFLATE && chunks[i].filename && strcmp(name, chunks[i].filename) == 0) { return chunks+i; Loading @@ -812,11 +811,11 @@ void DumpChunks(ImageChunk* chunks, int num_chunks) { } } int main(int argc, char** argv) { int zip_mode = 0; int imgdiff(int argc, const char** argv) { bool zip_mode = false; if (argc >= 2 && strcmp(argv[1], "-z") == 0) { zip_mode = 1; zip_mode = true; --argc; ++argv; } Loading Loading @@ -880,12 +879,10 @@ int main(int argc, char** argv) { // Verify that the source and target images have the same chunk // structure (ie, the same sequence of deflate and normal chunks). if (!zip_mode) { // Merge the gzip header and footer in with any adjacent // normal chunks. MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks); MergeAdjacentNormalChunks(src_chunks, &num_src_chunks); } if (num_src_chunks != num_tgt_chunks) { printf("source and target don't have same number of chunks!\n"); Loading @@ -897,8 +894,7 @@ int main(int argc, char** argv) { } for (i = 0; i < num_src_chunks; ++i) { if (src_chunks[i].type != tgt_chunks[i].type) { printf("source and target don't have same chunk " "structure! (chunk %d)\n", i); printf("source and target don't have same chunk structure! (chunk %d)\n", i); printf("source chunks:\n"); DumpChunks(src_chunks, num_src_chunks); printf("target chunks:\n"); Loading Loading @@ -983,8 +979,7 @@ int main(int argc, char** argv) { if (zip_mode) { ImageChunk* src; if (tgt_chunks[i].type == CHUNK_DEFLATE && (src = FindChunkByName(tgt_chunks[i].filename, src_chunks, num_src_chunks))) { (src = FindChunkByName(tgt_chunks[i].filename, src_chunks, num_src_chunks))) { patch_data[i] = MakePatch(src, tgt_chunks+i, patch_size+i); } else { patch_data[i] = MakePatch(src_chunks, tgt_chunks+i, patch_size+i); Loading @@ -1000,8 +995,7 @@ int main(int argc, char** argv) { patch_data[i] = MakePatch(src_chunks+i, tgt_chunks+i, patch_size+i); } printf("patch %3d is %zu bytes (of %zu)\n", i, patch_size[i], tgt_chunks[i].source_len); printf("patch %3d is %zu bytes (of %zu)\n", i, patch_size[i], tgt_chunks[i].source_len); } // Figure out how big the imgdiff file header is going to be, so Loading applypatch/imgdiff_main.cpp 0 → 100644 +21 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "applypatch/imgdiff.h" int main(int argc, char** argv) { return imgdiff(argc, const_cast<const char**>(argv)); } applypatch/imgpatch.cpp +200 −205 Original line number Diff line number Diff line Loading @@ -14,30 +14,32 @@ * limitations under the License. */ // See imgdiff.c in this directory for a description of the patch file // See imgdiff.cpp in this directory for a description of the patch file // format. #include <applypatch/imgpatch.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <sys/cdefs.h> #include <sys/stat.h> #include <errno.h> #include <unistd.h> #include <string.h> #include <string> #include <vector> #include "zlib.h" #include "openssl/sha.h" #include "applypatch/applypatch.h" #include "imgdiff.h" #include <applypatch/applypatch.h> #include <applypatch/imgdiff.h> #include <openssl/sha.h> #include <zlib.h> #include "utils.h" int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const unsigned char* patch_data, ssize_t patch_size, SinkFn sink, void* token) { Value patch(VAL_BLOB, std::string( reinterpret_cast<const char*>(patch_data), patch_size)); Value patch(VAL_BLOB, std::string(reinterpret_cast<const char*>(patch_data), patch_size)); return ApplyImagePatch(old_data, old_size, &patch, sink, token, nullptr, nullptr); } Loading @@ -48,10 +50,8 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, * file, and update the SHA context with the output data as well. * Return 0 on success. */ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const Value* patch, SinkFn sink, void* token, SHA_CTX* ctx, const Value* bonus_data) { int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const Value* patch, SinkFn sink, void* token, SHA_CTX* ctx, const Value* bonus_data) { if (patch->data.size() < 12) { printf("patch too short to contain header\n"); return -1; Loading Loading @@ -94,8 +94,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, printf("source data too short\n"); return -1; } ApplyBSDiffPatch(old_data + src_start, src_len, patch, patch_offset, sink, token, ctx); ApplyBSDiffPatch(old_data + src_start, src_len, patch, patch_offset, sink, token, ctx); } else if (type == CHUNK_RAW) { const char* raw_header = &patch->data[pos]; pos += 4; Loading @@ -111,8 +110,8 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, return -1; } if (ctx) SHA1_Update(ctx, &patch->data[pos], data_len); if (sink(reinterpret_cast<const unsigned char*>(&patch->data[pos]), data_len, token) != data_len) { if (sink(reinterpret_cast<const unsigned char*>(&patch->data[pos]), data_len, token) != data_len) { printf("failed to write chunk %d raw data\n", i); return -1; } Loading Loading @@ -161,12 +160,11 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = src_len; strm.next_in = (unsigned char*)(old_data + src_start); strm.next_in = const_cast<unsigned char*>(old_data + src_start); strm.avail_out = expanded_len; strm.next_out = expanded_source.data(); int ret; ret = inflateInit2(&strm, -15); int ret = inflateInit2(&strm, -15); if (ret != Z_OK) { printf("failed to init source inflation: %d\n", ret); return -1; Loading @@ -188,22 +186,20 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, inflateEnd(&strm); if (bonus_size) { memcpy(expanded_source.data() + (expanded_len - bonus_size), &bonus_data->data[0], bonus_size); memcpy(expanded_source.data() + (expanded_len - bonus_size), &bonus_data->data[0], bonus_size); } } // Next, apply the bsdiff patch (in memory) to the uncompressed // data. // Next, apply the bsdiff patch (in memory) to the uncompressed data. std::vector<unsigned char> uncompressed_target_data; if (ApplyBSDiffPatchMem(expanded_source.data(), expanded_len, patch, patch_offset, if (ApplyBSDiffPatchMem(expanded_source.data(), expanded_len, patch, patch_offset, &uncompressed_target_data) != 0) { return -1; } if (uncompressed_target_data.size() != target_len) { printf("expected target len to be %zu, but it's %zu\n", target_len, uncompressed_target_data.size()); printf("expected target len to be %zu, but it's %zu\n", target_len, uncompressed_target_data.size()); return -1; } Loading Loading @@ -237,8 +233,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, ssize_t have = temp_data.size() - strm.avail_out; if (sink(temp_data.data(), have, token) != have) { printf("failed to write %zd compressed bytes to output\n", have); printf("failed to write %zd compressed bytes to output\n", have); return -1; } if (ctx) SHA1_Update(ctx, temp_data.data(), have); Loading applypatch/imgdiff.h→applypatch/include/applypatch/imgdiff.h +15 −6 Original line number Diff line number Diff line Loading @@ -14,6 +14,11 @@ * limitations under the License. */ #ifndef _APPLYPATCH_IMGDIFF_H #define _APPLYPATCH_IMGDIFF_H #include <stddef.h> // Image patch chunk types #define CHUNK_NORMAL 0 #define CHUNK_GZIP 1 // version 1 only Loading @@ -24,7 +29,11 @@ // support gzipped data with any of the optional fields, so for now it // will always be ten bytes. See RFC 1952 for the definition of the // gzip format. #define GZIP_HEADER_LEN 10 static constexpr size_t GZIP_HEADER_LEN = 10; // The gzip footer size really is fixed. #define GZIP_FOOTER_LEN 8 static constexpr size_t GZIP_FOOTER_LEN = 8; int imgdiff(int argc, const char** argv); #endif // _APPLYPATCH_IMGDIFF_H Loading
applypatch/Android.mk +69 −21 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ LOCAL_PATH := $(call my-dir) # libapplypatch (static library) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := \ applypatch.cpp \ bspatch.cpp \ Loading @@ -26,11 +25,11 @@ LOCAL_SRC_FILES := \ utils.cpp LOCAL_MODULE := libapplypatch LOCAL_MODULE_TAGS := eng LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_STATIC_LIBRARIES += \ LOCAL_STATIC_LIBRARIES := \ libotafault \ libbase \ libcrypto \ Loading @@ -42,36 +41,45 @@ include $(BUILD_STATIC_LIBRARY) # libimgpatch (static library) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp LOCAL_SRC_FILES := \ bspatch.cpp \ imgpatch.cpp \ utils.cpp LOCAL_MODULE := libimgpatch LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_STATIC_LIBRARIES += libcrypto libbz libz LOCAL_STATIC_LIBRARIES := \ libcrypto \ libbz \ libz LOCAL_CFLAGS := -Werror include $(BUILD_STATIC_LIBRARY) # libimgpatch (host static library) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp LOCAL_SRC_FILES := \ bspatch.cpp \ imgpatch.cpp \ utils.cpp LOCAL_MODULE := libimgpatch LOCAL_MODULE_HOST_OS := linux LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_STATIC_LIBRARIES += libcrypto libbz libz LOCAL_STATIC_LIBRARIES := \ libcrypto \ libbz \ libz LOCAL_CFLAGS := -Werror include $(BUILD_HOST_STATIC_LIBRARY) # libapplypatch_modes (static library) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := \ applypatch_modes.cpp LOCAL_MODULE := libapplypatch_modes Loading @@ -87,7 +95,6 @@ include $(BUILD_STATIC_LIBRARY) # applypatch (target executable) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := applypatch_main.cpp LOCAL_MODULE := applypatch LOCAL_C_INCLUDES := bootable/recovery Loading @@ -106,18 +113,59 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_CFLAGS := -Werror include $(BUILD_EXECUTABLE) libimgdiff_src_files := \ imgdiff.cpp \ utils.cpp # libbsdiff is compiled with -D_FILE_OFFSET_BITS=64. libimgdiff_cflags := \ -Werror \ -D_FILE_OFFSET_BITS=64 libimgdiff_static_libraries := \ libbsdiff \ libz # libimgdiff (static library) # =============================== include $(CLEAR_VARS) LOCAL_SRC_FILES := \ $(libimgdiff_src_files) LOCAL_MODULE := libimgdiff LOCAL_CFLAGS := \ $(libimgdiff_cflags) LOCAL_STATIC_LIBRARIES := \ $(libimgdiff_static_libraries) LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include include $(BUILD_STATIC_LIBRARY) # libimgdiff (host static library) # =============================== include $(CLEAR_VARS) LOCAL_SRC_FILES := \ $(libimgdiff_src_files) LOCAL_MODULE := libimgdiff LOCAL_CFLAGS := \ $(libimgdiff_cflags) LOCAL_STATIC_LIBRARIES := \ $(libimgdiff_static_libraries) LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include include $(BUILD_HOST_STATIC_LIBRARY) # imgdiff (host static executable) # =============================== include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := imgdiff.cpp utils.cpp LOCAL_SRC_FILES := imgdiff_main.cpp LOCAL_MODULE := imgdiff LOCAL_STATIC_LIBRARIES += \ libbsdiff \ LOCAL_CFLAGS := -Werror LOCAL_STATIC_LIBRARIES := \ libimgdiff \ $(libimgdiff_static_libraries) \ libbz \ libdivsufsort64 \ libdivsufsort \ libz LOCAL_CFLAGS := -Werror LOCAL_FORCE_STATIC_EXECUTABLE := true libdivsufsort64 include $(BUILD_HOST_EXECUTABLE)
applypatch/imgdiff.cpp +24 −30 Original line number Diff line number Diff line Loading @@ -121,19 +121,19 @@ * information that is stored on the system partition. */ #include "applypatch/imgdiff.h" #include <errno.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <unistd.h> #include <sys/types.h> #include <unistd.h> #include <bsdiff.h> #include <zlib.h> #include "zlib.h" #include "imgdiff.h" #include "utils.h" typedef struct { Loading Loading @@ -374,8 +374,7 @@ unsigned char* ReadZip(const char* filename, * return value when done with all the chunks. Returns NULL on * failure. */ unsigned char* ReadImage(const char* filename, int* num_chunks, ImageChunk** chunks) { unsigned char* ReadImage(const char* filename, int* num_chunks, ImageChunk** chunks) { struct stat st; if (stat(filename, &st) != 0) { printf("failed to stat \"%s\": %s\n", filename, strerror(errno)); Loading Loading @@ -413,8 +412,7 @@ unsigned char* ReadImage(const char* filename, size_t chunk_offset = pos; *num_chunks += 3; *chunks = static_cast<ImageChunk*>(realloc(*chunks, *num_chunks * sizeof(ImageChunk))); *chunks = static_cast<ImageChunk*>(realloc(*chunks, *num_chunks * sizeof(ImageChunk))); ImageChunk* curr = *chunks + (*num_chunks-3); // create a normal chunk for the header. Loading Loading @@ -502,8 +500,7 @@ unsigned char* ReadImage(const char* filename, // the decompression. size_t footer_size = Read4(p-4); if (footer_size != curr[-2].len) { printf("Error: footer size %zu != decompressed size %zu\n", footer_size, curr[-2].len); printf("Error: footer size %zu != decompressed size %zu\n", footer_size, curr[-2].len); free(img); return NULL; } Loading Loading @@ -637,7 +634,11 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) { } } #if defined(__ANDROID__) char ptemp[] = "/data/local/tmp/imgdiff-patch-XXXXXX"; #else char ptemp[] = "/tmp/imgdiff-patch-XXXXXX"; #endif int fd = mkstemp(ptemp); if (fd == -1) { Loading Loading @@ -793,10 +794,8 @@ void MergeAdjacentNormalChunks(ImageChunk* chunks, int* num_chunks) { *num_chunks = out; } ImageChunk* FindChunkByName(const char* name, ImageChunk* chunks, int num_chunks) { int i; for (i = 0; i < num_chunks; ++i) { ImageChunk* FindChunkByName(const char* name, ImageChunk* chunks, int num_chunks) { for (int i = 0; i < num_chunks; ++i) { if (chunks[i].type == CHUNK_DEFLATE && chunks[i].filename && strcmp(name, chunks[i].filename) == 0) { return chunks+i; Loading @@ -812,11 +811,11 @@ void DumpChunks(ImageChunk* chunks, int num_chunks) { } } int main(int argc, char** argv) { int zip_mode = 0; int imgdiff(int argc, const char** argv) { bool zip_mode = false; if (argc >= 2 && strcmp(argv[1], "-z") == 0) { zip_mode = 1; zip_mode = true; --argc; ++argv; } Loading Loading @@ -880,12 +879,10 @@ int main(int argc, char** argv) { // Verify that the source and target images have the same chunk // structure (ie, the same sequence of deflate and normal chunks). if (!zip_mode) { // Merge the gzip header and footer in with any adjacent // normal chunks. MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks); MergeAdjacentNormalChunks(src_chunks, &num_src_chunks); } if (num_src_chunks != num_tgt_chunks) { printf("source and target don't have same number of chunks!\n"); Loading @@ -897,8 +894,7 @@ int main(int argc, char** argv) { } for (i = 0; i < num_src_chunks; ++i) { if (src_chunks[i].type != tgt_chunks[i].type) { printf("source and target don't have same chunk " "structure! (chunk %d)\n", i); printf("source and target don't have same chunk structure! (chunk %d)\n", i); printf("source chunks:\n"); DumpChunks(src_chunks, num_src_chunks); printf("target chunks:\n"); Loading Loading @@ -983,8 +979,7 @@ int main(int argc, char** argv) { if (zip_mode) { ImageChunk* src; if (tgt_chunks[i].type == CHUNK_DEFLATE && (src = FindChunkByName(tgt_chunks[i].filename, src_chunks, num_src_chunks))) { (src = FindChunkByName(tgt_chunks[i].filename, src_chunks, num_src_chunks))) { patch_data[i] = MakePatch(src, tgt_chunks+i, patch_size+i); } else { patch_data[i] = MakePatch(src_chunks, tgt_chunks+i, patch_size+i); Loading @@ -1000,8 +995,7 @@ int main(int argc, char** argv) { patch_data[i] = MakePatch(src_chunks+i, tgt_chunks+i, patch_size+i); } printf("patch %3d is %zu bytes (of %zu)\n", i, patch_size[i], tgt_chunks[i].source_len); printf("patch %3d is %zu bytes (of %zu)\n", i, patch_size[i], tgt_chunks[i].source_len); } // Figure out how big the imgdiff file header is going to be, so Loading
applypatch/imgdiff_main.cpp 0 → 100644 +21 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "applypatch/imgdiff.h" int main(int argc, char** argv) { return imgdiff(argc, const_cast<const char**>(argv)); }
applypatch/imgpatch.cpp +200 −205 Original line number Diff line number Diff line Loading @@ -14,30 +14,32 @@ * limitations under the License. */ // See imgdiff.c in this directory for a description of the patch file // See imgdiff.cpp in this directory for a description of the patch file // format. #include <applypatch/imgpatch.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <sys/cdefs.h> #include <sys/stat.h> #include <errno.h> #include <unistd.h> #include <string.h> #include <string> #include <vector> #include "zlib.h" #include "openssl/sha.h" #include "applypatch/applypatch.h" #include "imgdiff.h" #include <applypatch/applypatch.h> #include <applypatch/imgdiff.h> #include <openssl/sha.h> #include <zlib.h> #include "utils.h" int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const unsigned char* patch_data, ssize_t patch_size, SinkFn sink, void* token) { Value patch(VAL_BLOB, std::string( reinterpret_cast<const char*>(patch_data), patch_size)); Value patch(VAL_BLOB, std::string(reinterpret_cast<const char*>(patch_data), patch_size)); return ApplyImagePatch(old_data, old_size, &patch, sink, token, nullptr, nullptr); } Loading @@ -48,10 +50,8 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, * file, and update the SHA context with the output data as well. * Return 0 on success. */ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const Value* patch, SinkFn sink, void* token, SHA_CTX* ctx, const Value* bonus_data) { int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const Value* patch, SinkFn sink, void* token, SHA_CTX* ctx, const Value* bonus_data) { if (patch->data.size() < 12) { printf("patch too short to contain header\n"); return -1; Loading Loading @@ -94,8 +94,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, printf("source data too short\n"); return -1; } ApplyBSDiffPatch(old_data + src_start, src_len, patch, patch_offset, sink, token, ctx); ApplyBSDiffPatch(old_data + src_start, src_len, patch, patch_offset, sink, token, ctx); } else if (type == CHUNK_RAW) { const char* raw_header = &patch->data[pos]; pos += 4; Loading @@ -111,8 +110,8 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, return -1; } if (ctx) SHA1_Update(ctx, &patch->data[pos], data_len); if (sink(reinterpret_cast<const unsigned char*>(&patch->data[pos]), data_len, token) != data_len) { if (sink(reinterpret_cast<const unsigned char*>(&patch->data[pos]), data_len, token) != data_len) { printf("failed to write chunk %d raw data\n", i); return -1; } Loading Loading @@ -161,12 +160,11 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = src_len; strm.next_in = (unsigned char*)(old_data + src_start); strm.next_in = const_cast<unsigned char*>(old_data + src_start); strm.avail_out = expanded_len; strm.next_out = expanded_source.data(); int ret; ret = inflateInit2(&strm, -15); int ret = inflateInit2(&strm, -15); if (ret != Z_OK) { printf("failed to init source inflation: %d\n", ret); return -1; Loading @@ -188,22 +186,20 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, inflateEnd(&strm); if (bonus_size) { memcpy(expanded_source.data() + (expanded_len - bonus_size), &bonus_data->data[0], bonus_size); memcpy(expanded_source.data() + (expanded_len - bonus_size), &bonus_data->data[0], bonus_size); } } // Next, apply the bsdiff patch (in memory) to the uncompressed // data. // Next, apply the bsdiff patch (in memory) to the uncompressed data. std::vector<unsigned char> uncompressed_target_data; if (ApplyBSDiffPatchMem(expanded_source.data(), expanded_len, patch, patch_offset, if (ApplyBSDiffPatchMem(expanded_source.data(), expanded_len, patch, patch_offset, &uncompressed_target_data) != 0) { return -1; } if (uncompressed_target_data.size() != target_len) { printf("expected target len to be %zu, but it's %zu\n", target_len, uncompressed_target_data.size()); printf("expected target len to be %zu, but it's %zu\n", target_len, uncompressed_target_data.size()); return -1; } Loading Loading @@ -237,8 +233,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, ssize_t have = temp_data.size() - strm.avail_out; if (sink(temp_data.data(), have, token) != have) { printf("failed to write %zd compressed bytes to output\n", have); printf("failed to write %zd compressed bytes to output\n", have); return -1; } if (ctx) SHA1_Update(ctx, temp_data.data(), have); Loading
applypatch/imgdiff.h→applypatch/include/applypatch/imgdiff.h +15 −6 Original line number Diff line number Diff line Loading @@ -14,6 +14,11 @@ * limitations under the License. */ #ifndef _APPLYPATCH_IMGDIFF_H #define _APPLYPATCH_IMGDIFF_H #include <stddef.h> // Image patch chunk types #define CHUNK_NORMAL 0 #define CHUNK_GZIP 1 // version 1 only Loading @@ -24,7 +29,11 @@ // support gzipped data with any of the optional fields, so for now it // will always be ten bytes. See RFC 1952 for the definition of the // gzip format. #define GZIP_HEADER_LEN 10 static constexpr size_t GZIP_HEADER_LEN = 10; // The gzip footer size really is fixed. #define GZIP_FOOTER_LEN 8 static constexpr size_t GZIP_FOOTER_LEN = 8; int imgdiff(int argc, const char** argv); #endif // _APPLYPATCH_IMGDIFF_H