DO NOT MERGE: Build a static bspatch for recovery. am: 2eea58f169
am: fb97da5a93 -s ours
Change-Id: Ia8374b9a7fa8ac750620827e1fdfbd0d5fa89bd0
diff --git a/Android.mk b/Android.mk
index 4341eef..12ee3e8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,9 +26,10 @@
libbz
# "bsdiff" program.
-bsdiff_shared_libs := \
+bsdiff_static_libs := \
libdivsufsort64 \
- libdivsufsort
+ libdivsufsort \
+ $(bsdiff_common_static_libs)
bsdiff_src_files := \
bsdiff.cc
@@ -49,17 +50,54 @@
extents_unittest.cc \
test_utils.cc
+# Target static libraries.
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbspatch
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(bspatch_src_files)
+LOCAL_CFLAGS := $(bsdiff_common_cflags)
+LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbsdiff
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(bsdiff_src_files)
+LOCAL_CFLAGS := $(bsdiff_common_cflags)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+LOCAL_STATIC_LIBRARIES := $(bsdiff_static_libs)
+include $(BUILD_STATIC_LIBRARY)
+
+# Host static libraries.
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbspatch
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(bspatch_src_files)
+LOCAL_CFLAGS := $(bsdiff_common_cflags)
+LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbsdiff
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(bsdiff_src_files)
+LOCAL_CFLAGS := $(bsdiff_common_cflags)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+LOCAL_STATIC_LIBRARIES := $(bsdiff_static_libs)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
# Target executables.
include $(CLEAR_VARS)
LOCAL_MODULE := bspatch
LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
- $(bspatch_src_files) \
- bspatch_main.cc
+LOCAL_SRC_FILES := bspatch_main.cc
LOCAL_CFLAGS := $(bsdiff_common_cflags)
-LOCAL_C_INCLUDES += external/bzip2
-LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
+LOCAL_STATIC_LIBRARIES := \
+ libbspatch \
+ $(bsdiff_common_static_libs)
include $(BUILD_EXECUTABLE)
# bspatch used in recovery by update_engine_sideload.
@@ -69,11 +107,10 @@
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
- $(bspatch_src_files) \
- bspatch_main.cc
+LOCAL_SRC_FILES := bspatch_main.cc
LOCAL_CFLAGS := $(bsdiff_common_cflags)
LOCAL_STATIC_LIBRARIES := \
+ libbspatch \
$(bsdiff_common_static_libs)
include $(BUILD_EXECUTABLE)
@@ -82,40 +119,36 @@
include $(CLEAR_VARS)
LOCAL_MODULE := bsdiff
LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
- $(bsdiff_src_files) \
- bsdiff_main.cc
+LOCAL_SRC_FILES := bsdiff_main.cc
LOCAL_CFLAGS := $(bsdiff_common_cflags)
-LOCAL_C_INCLUDES += external/bzip2
-LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
-LOCAL_SHARED_LIBRARIES := $(bsdiff_shared_libs)
+LOCAL_STATIC_LIBRARIES := \
+ libbsdiff \
+ $(bsdiff_static_libs)
include $(BUILD_HOST_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := bspatch
LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
- $(bspatch_src_files) \
- bspatch_main.cc
+LOCAL_SRC_FILES := bspatch_main.cc
LOCAL_CFLAGS := $(bsdiff_common_cflags)
-LOCAL_C_INCLUDES += external/bzip2
-LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
+LOCAL_STATIC_LIBRARIES := \
+ libbspatch \
+ $(bsdiff_common_static_libs)
include $(BUILD_HOST_EXECUTABLE)
+# Unit tests.
+
include $(CLEAR_VARS)
LOCAL_MODULE := bsdiff_unittest
LOCAL_MODULE_TAGS := debug tests
LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
- $(bsdiff_src_files) \
- $(bspatch_src_files) \
- $(bsdiff_common_unittests) \
+LOCAL_SRC_FILES := $(bsdiff_common_unittests) \
testrunner.cc
-LOCAL_CFLAGS := $(bsdiff_common_cflags)
-LOCAL_C_INCLUDES += external/bzip2
+LOCAL_CFLAGS := $(bsdiff_common_cflags) \
+ -DBSDIFF_TARGET_UNITTEST
LOCAL_STATIC_LIBRARIES := \
- $(bsdiff_common_static_libs) \
- libgtest_host \
- libgmock_host
-LOCAL_SHARED_LIBRARIES := $(bsdiff_shared_libs)
-include $(BUILD_HOST_EXECUTABLE)
+ libbsdiff \
+ libbspatch \
+ libgmock \
+ $(bsdiff_static_libs)
+include $(BUILD_NATIVE_TEST)
diff --git a/bsdiff.cc b/bsdiff.cc
index dab0d82..669a1e5 100644
--- a/bsdiff.cc
+++ b/bsdiff.cc
@@ -28,6 +28,8 @@
__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 cperciva Exp $");
#endif
+#include "bsdiff.h"
+
#include <sys/types.h>
#include <bzlib.h>
@@ -50,7 +52,7 @@
namespace bsdiff {
-static off_t matchlen(u_char *old, off_t oldsize, u_char *new_buf,
+static off_t matchlen(const u_char* old, off_t oldsize, const u_char* new_buf,
off_t newsize) {
off_t i;
@@ -60,9 +62,14 @@
return i;
}
-static off_t search(saidx_t *I,u_char *old,off_t oldsize,
- u_char *new_buf,off_t newsize,off_t st,off_t en,off_t *pos)
-{
+// This is a binary search of the string |new_buf| of size |newsize| (or a
+// prefix of it) in the |old| string with size |oldsize| using the suffix array
+// |I|. |st| and |en| is the start and end of the search range (inclusive).
+// Returns the length of the longest prefix found and stores the position of the
+// string found in |*pos|.
+static off_t search(saidx_t* I, const u_char* old, off_t oldsize,
+ const u_char* new_buf, off_t newsize, off_t st, off_t en,
+ off_t* pos) {
off_t x,y;
if(en-st<2) {
@@ -109,6 +116,35 @@
int fd;
u_char *old_buf,*new_buf;
off_t oldsize,newsize;
+
+ /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
+ that we never try to malloc(0) and get a NULL pointer */
+ if(((fd=open(old_filename,O_RDONLY,0))<0) ||
+ ((oldsize=lseek(fd,0,SEEK_END))==-1) ||
+ ((old_buf=static_cast<u_char*>(malloc(oldsize+1)))==NULL) ||
+ (lseek(fd,0,SEEK_SET)!=0) ||
+ (read(fd,old_buf,oldsize)!=oldsize) ||
+ (close(fd)==-1)) err(1,"%s",old_filename);
+
+ /* Allocate newsize+1 bytes instead of newsize bytes to ensure
+ that we never try to malloc(0) and get a NULL pointer */
+ if(((fd=open(new_filename,O_RDONLY,0))<0) ||
+ ((newsize=lseek(fd,0,SEEK_END))==-1) ||
+ ((new_buf = static_cast<u_char*>(malloc(newsize+1)))==NULL) ||
+ (lseek(fd,0,SEEK_SET)!=0) ||
+ (read(fd,new_buf,newsize)!=newsize) ||
+ (close(fd)==-1)) err(1,"%s",new_filename);
+
+ int ret = bsdiff(old_buf, oldsize, new_buf, newsize, patch_filename);
+
+ free(old_buf);
+ free(new_buf);
+
+ return ret;
+}
+
+int bsdiff(const u_char* old_buf, off_t oldsize, const u_char* new_buf,
+ off_t newsize, const char* patch_filename) {
saidx_t *I;
off_t scan,pos=0,len;
off_t lastscan,lastpos,lastoffset;
@@ -124,29 +160,11 @@
BZFILE * pfbz2;
int bz2err;
- /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
- that we never try to malloc(0) and get a NULL pointer */
- if(((fd=open(old_filename,O_RDONLY,0))<0) ||
- ((oldsize=lseek(fd,0,SEEK_END))==-1) ||
- ((old_buf=static_cast<u_char*>(malloc(oldsize+1)))==NULL) ||
- (lseek(fd,0,SEEK_SET)!=0) ||
- (read(fd,old_buf,oldsize)!=oldsize) ||
- (close(fd)==-1)) err(1,"%s",old_filename);
-
if((I=static_cast<saidx_t*>(malloc((oldsize+1)*sizeof(saidx_t))))==NULL)
err(1,NULL);
if(divsufsort(old_buf, I, oldsize)) err(1, "divsufsort");
- /* Allocate newsize+1 bytes instead of newsize bytes to ensure
- that we never try to malloc(0) and get a NULL pointer */
- if(((fd=open(new_filename,O_RDONLY,0))<0) ||
- ((newsize=lseek(fd,0,SEEK_END))==-1) ||
- ((new_buf = static_cast<u_char*>(malloc(newsize+1)))==NULL) ||
- (lseek(fd,0,SEEK_SET)!=0) ||
- (read(fd,new_buf,newsize)!=newsize) ||
- (close(fd)==-1)) err(1,"%s",new_filename);
-
if(((db=static_cast<u_char*>(malloc(newsize+1)))==NULL) ||
((eb=static_cast<u_char*>(malloc(newsize+1)))==NULL)) err(1,NULL);
dblen=0;
@@ -193,7 +211,7 @@
prev_pos=pos;
len=search(I,old_buf,oldsize,new_buf+scan,newsize-scan,
- 0,oldsize,&pos);
+ 0,oldsize-1,&pos);
for(;scsc<scan+len;scsc++)
if((scsc+lastoffset<oldsize) &&
@@ -325,8 +343,6 @@
free(db);
free(eb);
free(I);
- free(old_buf);
- free(new_buf);
return 0;
}
diff --git a/bsdiff.h b/bsdiff.h
index c86b6f8..370ee03 100644
--- a/bsdiff.h
+++ b/bsdiff.h
@@ -5,12 +5,20 @@
#ifndef _BSDIFF_BSDIFF_H_
#define _BSDIFF_BSDIFF_H_
+#include <sys/types.h>
+
namespace bsdiff {
int bsdiff(const char* old_filename,
const char* new_filename,
const char* patch_filename);
+int bsdiff(const u_char* old_buf,
+ off_t oldsize,
+ const u_char* new_buf,
+ off_t newsize,
+ const char* patch_filename);
+
} // namespace bsdiff
#endif // _BSDIFF_BSDIFF_H_
diff --git a/file.h b/file.h
index e9659c7..ad1fd2f 100644
--- a/file.h
+++ b/file.h
@@ -29,7 +29,7 @@
private:
// Creates the File instance for the |fd|. Takes ownership of the file
// descriptor.
- File(int fd);
+ explicit File(int fd);
int fd_;
};
diff --git a/test_utils.cc b/test_utils.cc
index 2ad8fc8..f369f80 100644
--- a/test_utils.cc
+++ b/test_utils.cc
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <gtest/gtest.h>
@@ -51,6 +52,16 @@
namespace test_utils {
+void BsdiffTestEnvironment::SetUp() {
+#ifdef BSDIFF_TARGET_UNITTEST
+#define BSDIFF_TARGET_TMP_BASE "/data/tmp"
+ if (access(BSDIFF_TARGET_TMP_BASE, F_OK) == -1) {
+ mkdir(BSDIFF_TARGET_TMP_BASE, S_IRWXU | S_IRWXG | S_IROTH | S_IWOTH);
+ }
+ setenv("TMPDIR", BSDIFF_TARGET_TMP_BASE, 1);
+#endif // defined (BSDIFF_TARGET_UNITTEST)
+}
+
bool ReadFile(const string& path, vector<uint8_t>* out) {
FILE* fp = fopen(path.c_str(), "r");
if (!fp)
@@ -101,13 +112,15 @@
memcpy(&diff_len, contents.data() + 16, sizeof(diff_len));
memcpy(&new_file_len, contents.data() + 24, sizeof(new_file_len));
- TEST_AND_RETURN_FALSE(file_size >= kHeaderSize + ctrl_len + diff_len);
- extra_len = file_size - kHeaderSize - ctrl_len - diff_len;
-
// Sanity check before we attempt to parse the bz2 streams.
TEST_AND_RETURN_FALSE(ctrl_len >= 0);
TEST_AND_RETURN_FALSE(diff_len >= 0);
+ // The cast is safe since ctrl_len and diff_len are both positive.
+ TEST_AND_RETURN_FALSE(file_size >=
+ static_cast<uint64_t>(kHeaderSize + ctrl_len + diff_len));
+ extra_len = file_size - kHeaderSize - ctrl_len - diff_len;
+
uint8_t* ptr = contents.data() + kHeaderSize;
bz2_ctrl = vector<uint8_t>(ptr, ptr + ctrl_len);
ptr += ctrl_len;
diff --git a/test_utils.h b/test_utils.h
index 186d9e6..7132fe5 100644
--- a/test_utils.h
+++ b/test_utils.h
@@ -5,6 +5,7 @@
#ifndef _BSDIFF_TEST_UTILS_H_
#define _BSDIFF_TEST_UTILS_H_
+#include <gtest/gtest.h>
#include <string>
#include <vector>
@@ -18,6 +19,11 @@
namespace test_utils {
+class BsdiffTestEnvironment : public ::testing::Environment {
+ public:
+ virtual void SetUp();
+};
+
// Reads all the contents of the file |path| into |out|. Returns whether it
// read up to the end of file.
bool ReadFile(const std::string& path, std::vector<uint8_t>* out);
diff --git a/testrunner.cc b/testrunner.cc
index 44f0b5e..8b598e2 100644
--- a/testrunner.cc
+++ b/testrunner.cc
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "test_utils.h"
+
#include <gtest/gtest.h>
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
+ ::testing::AddGlobalTestEnvironment(new test_utils::BsdiffTestEnvironment);
return RUN_ALL_TESTS();
}