ss_engine/fota_tar.c
ss_patch/ss_bspatch.c
ss_patch/ss_patchdelta.c
+ bsdiff/ss_bspatch_common.c
)
SET(HEADERS
ss_engine/fota_common.h
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/ss_engine)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/ss_patch)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/bsdiff)
INCLUDE(FindPkgConfig)
pkg_check_modules(packages REQUIRED
PROJECT(ss_bsdiff C)
SET(ss_bsdiff_SRCS ss_bsdiff.c)
-SET(ss_bspatch_SRCS ss_bspatch.c)
+SET(ss_bspatch_SRCS
+ ss_bspatch_common.c
+ ss_bspatch.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/bsdiff)
INCLUDE(FindPkgConfig)
pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED lib7zip libdivsufsort)
#endif
#ifdef SUFSORT_MOD
//supporting only 32 bit divsufsort for now.
-#include "divsufsort.h"
+#include <divsufsort.h>
#endif
#define MIN(x,y) (((x)<(y)) ? (x) : (y))
* recursive implementation to avoid buffer overflow problems
*/
#define _CRT_SECURE_NO_WARNINGS
-#define CONST_MEMORY_USAGE 16384
-#define PATCH_FILE_FORMAT_MOD
-#define BSDIFF_HEADER "BSDIFF40"
-#define SSDIFF_HEADER "SSDIFF40"
-#define MULTI_THREADING
-#include <stdbool.h>
#include <err.h>
#include <unistd.h>
#include <fcntl.h>
#include <LzmaDec.h>
#include <LzmaEnc.h>
+#include "ss_bspatch_common.h"
+
const char *kCantReadMessage = "Can not read input file";
const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory";
const char *kDataErrorMessage = "Data error";
-static void *SzAlloc(void *p, size_t size)
-{
- p = p;
- return MyAlloc(size);
-}
-
-static void SzFree(void *p, void *address)
-{
- p = p;
- MyFree(address);
-}
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
-static off_t offtin(u_char *buf)
-{
- off_t y;
-
- y = buf[7] & 0x7F;
- y = y * 256;
- y += buf[6];
- y = y * 256;
- y += buf[5];
- y = y * 256;
- y += buf[4];
- y = y * 256;
- y += buf[3];
- y = y * 256;
- y += buf[2];
- y = y * 256;
- y += buf[1];
- y = y * 256;
- y += buf[0];
-
- if (buf[7] & 0x80)
- y = -y;
-
- return y;
-}
-
void PrintHelp(char *buffer)
{
strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
return PrintError(buffer, "Incorrect command");
}
-#define IN_BUF_SIZE (1 << 16)
-#define OUT_BUF_SIZE (1 << 16)
-
-static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
- UInt64 *unpackSize,unsigned char *dec_data)
-{
- int thereIsSize = (*unpackSize != (UInt64)(Int64) - 1);
- UInt64 offset = 0;
- Byte inBuf[IN_BUF_SIZE];
- Byte outBuf[OUT_BUF_SIZE];
- size_t inPos = 0, inSize = 0, outPos = 0;
-
- LzmaDec_Init(state);
-
- offset = 0;
-
- for (;;) {
- if (inPos == inSize) {
- inSize = IN_BUF_SIZE;
- RINOK(inStream->Read(inStream, inBuf, &inSize));
- inPos = 0;
- }
-
- SRes res;
- SizeT inProcessed = inSize - inPos;
- SizeT outProcessed = OUT_BUF_SIZE - outPos;
- ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
- ELzmaStatus status;
-
- if (thereIsSize && outProcessed > *unpackSize) {
- outProcessed = (SizeT) * unpackSize;
- finishMode = LZMA_FINISH_END;
- }
-
- res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,
- inBuf + inPos, &inProcessed, finishMode, &status);
- inPos += inProcessed;
- outPos += outProcessed;
- *unpackSize -= outProcessed;
- memcpy(dec_data + offset, outBuf, outProcessed);
- offset += outProcessed;
-
- outPos = 0;
-
- if ((res != SZ_OK) || (thereIsSize && *unpackSize == 0))
- return res;
-
- if (inProcessed == 0 && outProcessed == 0) {
- if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
- return SZ_ERROR_DATA;
- return res;
- }
- }
-}
-
-int apply_patch(char *oldfile, char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size)
-{
- int fd = -1, result = 0;
- off_t oldsize, newsize;
- u_char header[16], buf[8];
- u_char *old = NULL;
- off_t oldpos, newpos;
- off_t ctrl[4]; /////////////////////////////////////THREAD
- off_t total_write; /////////////////////////////////////////THREAD
- off_t j;
- off_t memory_usage = CONST_MEMORY_USAGE;
- off_t match_size;
- off_t patch_buffer_offset = 0;
- bool flag;
-
- /*
- File format:
- 0 8 "BSDIFF40"
- 8 8 X
- 16 8 Y
- 24 8 sizeof(newfile)
- 32 X bzip2(control block)
- 32+X Y bzip2(diff block)
- 32+X+Y ??? bzip2(extra block)
- with control block a set of triples (x,y,z) meaning "add x bytes
- from oldfile to x bytes from the diff block; copy y bytes from the
- extra block; seek forwards in oldfile by z bytes".
- */
- // Read header
- if (patch_buffer)
- memcpy(header, patch_buffer, 16);
- else {
- printf("%s().%d Corrupt decoded patch buffer\n", __FUNCTION__, __LINE__);
- return 1;
- }
-
- /* Check for appropriate magic */
- if (memcmp(header, BSDIFF_HEADER, 8) != 0 && memcmp(header, SSDIFF_HEADER, 8) != 0) {
- printf("%s().%d Patch buffer header corrupt\n", __FUNCTION__, __LINE__ );
- return 1;
- }
-
- /* Read lengths from header */
- newsize = offtin(header + 8);
-
- if ((newsize < 0)) {
- printf("%s().%d Patch buffer corrupt\n", __FUNCTION__, __LINE__ );
- return 1;
- }
-
- /* Cset patch_buffer_offset at the right place */
- patch_buffer_offset += 16;
-
- if (((fd = open(oldfile, O_RDONLY, 0)) < 0) ||
- ((oldsize = lseek(fd, 0, SEEK_END)) == -1) ||
- ((old = malloc(memory_usage + 1)) == NULL) ||
- (lseek(fd, 0, SEEK_SET) != 0)) {
- printf("Corruption in old file %s\n", oldfile);
- result = 1;
- goto Cleanup;
- }
-
- if ((*dest_buf = malloc(newsize + 1)) == NULL) {
- printf("Corruption in old file %s\n", oldfile);
- result = 1;
- goto Cleanup;
- }
- oldpos = 0;
- newpos = 0;
-
- total_write = 0;
-
- while (total_write != newsize) {
- /* Read control data */
- for (j = 0; j <= 3; j++) {
- memcpy(buf, patch_buffer + patch_buffer_offset, 8);
- patch_buffer_offset += 8;
- ctrl[j] = offtin(buf);
- };
-
- total_write += (ctrl[0] + ctrl[1]);
- newpos = ctrl[3];
- oldpos = ctrl[2];
-
- //////////////////////////////////////////////////////////////////////////////////
- flag = true;
- match_size = ctrl[0];
- while (flag == true) {
- if (match_size <= memory_usage) {
- if (pread(fd, old, match_size, oldpos) != match_size) {
- printf("Corruption in old file %s\n", oldfile);
- result = 1;
- goto Cleanup;
- }
- if (newpos + match_size > newsize) {
- printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
- result = 1;
- goto Cleanup;
- }
- memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, match_size);
- patch_buffer_offset += match_size;
- for (j = 0; j < match_size; j++) {
- (*dest_buf)[newpos + j] += old[j];
- }
- newpos += match_size;
- flag = false;
- } else {
- if (pread(fd, old, memory_usage, oldpos) != memory_usage) {
- printf("%s().%d Corruption in old file %s\n", __FUNCTION__, __LINE__ , oldfile);
- result = 1;
- goto Cleanup;
- }
- if (newpos + memory_usage > newsize) {
- printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
- result = 1;
- goto Cleanup;
- }
- memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, memory_usage);
- patch_buffer_offset += memory_usage;
- for (j = 0; j < memory_usage; j++)
- (*dest_buf)[newpos + j] += old[j];
- match_size -= memory_usage;
- oldpos += memory_usage;
- newpos += memory_usage;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////
- /* Sanity-check */
- if (newpos + ctrl[1] > newsize) {
- printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
- result = 1;
- goto Cleanup;
- }
- /* Read extra string */
- memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, ctrl[1]);
- patch_buffer_offset += ctrl[1];
- };
- *dest_size = newsize;
-Cleanup:
- //close old file
- if (fd >= 0)
- close(fd);
- if (old)
- free(old);
- return result;
-}
-
int main2(int numArgs, const char *args[], char *rs)
{
CFileSeqInStream inStream;
dest_len = unpackSize;
LzmaDec_Construct(&state);
RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc));
- res = Decode2(&state, &outStream, &inStream.s, &unpackSize,buf_res);
+ res = Decode2(&state, &outStream, &inStream.s, &unpackSize, buf_res);
LzmaDec_Free(&state, &g_Alloc);
File_Close(&inStream.file);
if (apply_patch(args[1], buf_res, &new_data, &new_size) != 0) {
--- /dev/null
+/*-
+ * Copyright 2003-2005 Colin Percival
+ * Copyright 2012 Matthew Endsley
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted providing that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Modifications are made in reimplementing suffix sort array generation
+ * and how the data is read and written to.Iterative part replaced the
+ * recursive implementation to avoid buffer overflow problems
+ */
+//#define ZLIB_MOD //not stable yet.
+//#define MAX_MATCH_SIZE // define ( MAX_MATCH_SIZE or CONST_MEMORY_USAGE ) or ( none of them )
+#define CONST_MEMORY_USAGE (64*1024) //tests show smallest time when using 64 kb
+#define PATCH_FILE_FORMAT_MOD
+#define BSDIFF_HEADER "BSDIFF40"
+#define SSDIFF_HEADER "SSDIFF40"
+//#define MULTI_THREADING
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <Alloc.h>
+#include <7zFile.h>
+#include <7zVersion.h>
+#include <LzmaDec.h>
+#include <LzmaEnc.h>
+
+static void *SzAlloc(void *p, size_t size)
+{
+ p = p;
+ return MyAlloc(size);
+}
+
+static void SzFree(void *p, void *address)
+{
+ p = p;
+ MyFree(address);
+}
+ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+static off_t offtin(u_char *buf)
+{
+ off_t y;
+
+ y = buf[7] & 0x7F;
+ y = y * 256;
+ y += buf[6];
+ y = y * 256;
+ y += buf[5];
+ y = y * 256;
+ y += buf[4];
+ y = y * 256;
+ y += buf[3];
+ y = y * 256;
+ y += buf[2];
+ y = y * 256;
+ y += buf[1];
+ y = y * 256;
+ y += buf[0];
+
+ if (buf[7] & 0x80)
+ y = -y;
+
+ return y;
+}
+
+#define IN_BUF_SIZE (1 << 16)
+#define OUT_BUF_SIZE (1 << 16)
+
+SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
+ UInt64 *unpackSize, unsigned char *dec_data)
+{
+ int thereIsSize = (*unpackSize != (UInt64)(Int64) - 1);
+ UInt64 offset = 0;
+ Byte inBuf[IN_BUF_SIZE];
+ Byte outBuf[OUT_BUF_SIZE];
+ size_t inPos = 0, inSize = 0, outPos = 0;
+
+ LzmaDec_Init(state);
+
+ offset = 0;
+
+ for (;;) {
+ if (inPos == inSize) {
+ inSize = IN_BUF_SIZE;
+ RINOK(inStream->Read(inStream, inBuf, &inSize));
+ inPos = 0;
+ }
+
+ SRes res;
+ SizeT inProcessed = inSize - inPos;
+ SizeT outProcessed = OUT_BUF_SIZE - outPos;
+ ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
+ ELzmaStatus status;
+
+ if (thereIsSize && outProcessed > *unpackSize) {
+ outProcessed = (SizeT) * unpackSize;
+ finishMode = LZMA_FINISH_END;
+ }
+
+ res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,
+ inBuf + inPos, &inProcessed, finishMode, &status);
+ inPos += inProcessed;
+ outPos += outProcessed;
+ *unpackSize -= outProcessed;
+ memcpy(dec_data + offset, outBuf, outProcessed);
+ offset += outProcessed;
+
+ outPos = 0;
+
+ if ((res != SZ_OK) || (thereIsSize && *unpackSize == 0))
+ return res;
+
+ if (inProcessed == 0 && outProcessed == 0) {
+ if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
+ return SZ_ERROR_DATA;
+ return res;
+ }
+ }
+}
+
+int apply_patch(char *oldfile, char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size)
+{
+ int fd = -1, result = 0;
+ off_t oldsize, newsize;
+ u_char header[16], buf[8];
+ u_char *old = NULL;
+ off_t oldpos, newpos;
+ off_t ctrl[4]; /////////////////////////////////////THREAD
+ off_t total_write; /////////////////////////////////////////THREAD
+ off_t j;
+ off_t memory_usage = CONST_MEMORY_USAGE;
+ off_t match_size;
+ off_t patch_buffer_offset = 0;
+ bool flag;
+
+ /*
+ File format:
+ 0 8 "BSDIFF40"
+ 8 8 X
+ 16 8 Y
+ 24 8 sizeof(newfile)
+ 32 X bzip2(control block)
+ 32+X Y bzip2(diff block)
+ 32+X+Y ??? bzip2(extra block)
+ with control block a set of triples (x,y,z) meaning "add x bytes
+ from oldfile to x bytes from the diff block; copy y bytes from the
+ extra block; seek forwards in oldfile by z bytes".
+ */
+ // Read header
+ if (patch_buffer)
+ memcpy(header, patch_buffer, 16);
+ else {
+ printf("%s().%d Corrupt decoded patch buffer\n", __FUNCTION__, __LINE__);
+ return 1;
+ }
+
+ /* Check for appropriate magic */
+ if (memcmp(header, BSDIFF_HEADER, 8) != 0 && memcmp(header, SSDIFF_HEADER, 8) != 0) {
+ printf("%s().%d Patch buffer header corrupt\n", __FUNCTION__, __LINE__ );
+ return 1;
+ }
+
+ /* Read lengths from header */
+ newsize = offtin(header + 8);
+
+ if ((newsize < 0)) {
+ printf("%s().%d Patch buffer corrupt\n", __FUNCTION__, __LINE__ );
+ return 1;
+ }
+
+ /* Cset patch_buffer_offset at the right place */
+ patch_buffer_offset += 16;
+
+ if (((fd = open(oldfile, O_RDONLY, 0)) < 0) ||
+ ((oldsize = lseek(fd, 0, SEEK_END)) == -1) ||
+ ((old = malloc(memory_usage + 1)) == NULL) ||
+ (lseek(fd, 0, SEEK_SET) != 0)) {
+ printf("Corruption in old file %s\n", oldfile);
+ result = 1;
+ goto Cleanup;
+ }
+
+ if ((*dest_buf = malloc(newsize + 1)) == NULL) {
+ printf("Corruption in old file %s\n", oldfile);
+ result = 1;
+ goto Cleanup;
+ }
+ oldpos = 0;
+ newpos = 0;
+
+ total_write = 0;
+
+ while (total_write != newsize) {
+ /* Read control data */
+ for (j = 0; j <= 3; j++) {
+ memcpy(buf, patch_buffer + patch_buffer_offset, 8);
+ patch_buffer_offset += 8;
+ ctrl[j] = offtin(buf);
+ };
+
+ total_write += (ctrl[0] + ctrl[1]);
+ newpos = ctrl[3];
+ oldpos = ctrl[2];
+
+ //////////////////////////////////////////////////////////////////////////////////
+ flag = true;
+ match_size = ctrl[0];
+ while (flag == true) {
+ if (match_size <= memory_usage) {
+ if (pread(fd, old, match_size, oldpos) != match_size) {
+ printf("Corruption in old file %s\n", oldfile);
+ result = 1;
+ goto Cleanup;
+ }
+ if (newpos + match_size > newsize) {
+ printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
+ result = 1;
+ goto Cleanup;
+ }
+ memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, match_size);
+ patch_buffer_offset += match_size;
+ for (j = 0; j < match_size; j++) {
+ (*dest_buf)[newpos + j] += old[j];
+ }
+ newpos += match_size;
+ flag = false;
+ } else {
+ if (pread(fd, old, memory_usage, oldpos) != memory_usage) {
+ printf("%s().%d Corruption in old file %s\n", __FUNCTION__, __LINE__ , oldfile);
+ result = 1;
+ goto Cleanup;
+ }
+ if (newpos + memory_usage > newsize) {
+ printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
+ result = 1;
+ goto Cleanup;
+ }
+ memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, memory_usage);
+ patch_buffer_offset += memory_usage;
+ for (j = 0; j < memory_usage; j++)
+ (*dest_buf)[newpos + j] += old[j];
+ match_size -= memory_usage;
+ oldpos += memory_usage;
+ newpos += memory_usage;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ /* Sanity-check */
+ if (newpos + ctrl[1] > newsize) {
+ printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
+ result = 1;
+ goto Cleanup;
+ }
+ /* Read extra string */
+ memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, ctrl[1]);
+ patch_buffer_offset += ctrl[1];
+ };
+ *dest_size = newsize;
+Cleanup:
+ //close old file
+ if (fd >= 0)
+ close(fd);
+ if (old)
+ free(old);
+ return result;
+}
--- /dev/null
+#ifndef _SS_BSPATCH_COMMON_H
+#define _SS_BSPATCH_COMMON_H 1
+
+#include <Alloc.h>
+#include <7zFile.h>
+#include <7zVersion.h>
+#include <LzmaDec.h>
+#include <LzmaEnc.h>
+
+extern ISzAlloc g_Alloc;
+
+SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
+ UInt64 *unpackSize, unsigned char *dec_data);
+
+int apply_patch(char *oldfile, char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size);
+
+#endif /* _SS_BSPATCH_COMMON_H */
Name: libtota
Summary: fota update library
ExclusiveArch: %{arm}
-Version: 0.1.0
-Release: 1
+Version: 0.1.1
+Release: 2
Group: System
License: Apache-2.0 and BSD-2-Clause and BSD-3-Clause and PD
Source0: %{name}-%{version}.tar.gz
* and how the data is read and written to.Iterative part replaced the
* recursive implementation to avoid buffer overflow problems
*/
-//#define ZLIB_MOD //not stable yet.
-//#define MAX_MATCH_SIZE // define ( MAX_MATCH_SIZE or CONST_MEMORY_USAGE ) or ( none of them )
-#define CONST_MEMORY_USAGE (64*1024) //tests show smallest time when using 64 kb
-#define PATCH_FILE_FORMAT_MOD
-#define BSDIFF_HEADER "BSDIFF40"
-#define SSDIFF_HEADER "SSDIFF40"
-//#define MULTI_THREADING
-#include <stdbool.h>
+#include <string.h>
#include <err.h>
-#include <unistd.h>
-#include <fcntl.h>
#include "ss_patchdelta.h"
#include "fota_common.h"
#include "sha1.h"
#include "SS_Engine_Errors.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
+#include "ss_bspatch_common.h"
#include <Alloc.h>
#include <7zFile.h>
#include <7zVersion.h>
#include <LzmaDec.h>
#include <LzmaEnc.h>
-static void *SzAlloc(void *p, size_t size)
-{
- p = p;
- return MyAlloc(size);
-}
-
-static void SzFree(void *p, void *address)
-{
- p = p;
- MyFree(address);
-}
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
-static off_t offtin(u_char *buf)
-{
- off_t y;
-
- y = buf[7] & 0x7F;
- y = y * 256;
- y += buf[6];
- y = y * 256;
- y += buf[5];
- y = y * 256;
- y += buf[4];
- y = y * 256;
- y += buf[3];
- y = y * 256;
- y += buf[2];
- y = y * 256;
- y += buf[1];
- y = y * 256;
- y += buf[0];
-
- if (buf[7] & 0x80)
- y = -y;
-
- return y;
-}
-
-#define IN_BUF_SIZE (1 << 16)
-#define OUT_BUF_SIZE (1 << 16)
-
-static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
- UInt64 *unpackSize,unsigned char *dec_data)
-{
- int thereIsSize = (*unpackSize != (UInt64)(Int64) - 1);
- UInt64 offset = 0;
- Byte inBuf[IN_BUF_SIZE];
- Byte outBuf[OUT_BUF_SIZE];
- size_t inPos = 0, inSize = 0, outPos = 0;
-
- LzmaDec_Init(state);
-
- offset = 0;
-
- for (;;) {
- if (inPos == inSize) {
- inSize = IN_BUF_SIZE;
- RINOK(inStream->Read(inStream, inBuf, &inSize));
- inPos = 0;
- }
-
- SRes res;
- SizeT inProcessed = inSize - inPos;
- SizeT outProcessed = OUT_BUF_SIZE - outPos;
- ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
- ELzmaStatus status;
-
- if (thereIsSize && outProcessed > *unpackSize) {
- outProcessed = (SizeT) * unpackSize;
- finishMode = LZMA_FINISH_END;
- }
-
- res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,
- inBuf + inPos, &inProcessed, finishMode, &status);
- inPos += inProcessed;
- outPos += outProcessed;
- *unpackSize -= outProcessed;
- memcpy(dec_data + offset, outBuf, outProcessed);
- offset += outProcessed;
-
- outPos = 0;
-
- if ((res != SZ_OK) || (thereIsSize && *unpackSize == 0))
- return res;
-
- if (inProcessed == 0 && outProcessed == 0) {
- if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
- return SZ_ERROR_DATA;
- return res;
- }
- }
-}
-
-int apply_patch(char *oldfile, char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size)
-{
- int fd = -1, result = 0;
- off_t oldsize, newsize;
- u_char header[16], buf[8];
- u_char *old = NULL;
- off_t oldpos, newpos;
- off_t ctrl[4]; /////////////////////////////////////THREAD
- off_t total_write; /////////////////////////////////////////THREAD
- off_t j;
- off_t memory_usage = CONST_MEMORY_USAGE;
- off_t match_size;
- off_t patch_buffer_offset = 0;
- bool flag;
-
- /*
- File format:
- 0 8 "BSDIFF40"
- 8 8 X
- 16 8 Y
- 24 8 sizeof(newfile)
- 32 X bzip2(control block)
- 32+X Y bzip2(diff block)
- 32+X+Y ??? bzip2(extra block)
- with control block a set of triples (x,y,z) meaning "add x bytes
- from oldfile to x bytes from the diff block; copy y bytes from the
- extra block; seek forwards in oldfile by z bytes".
- */
- // Read header
- if (patch_buffer)
- memcpy(header, patch_buffer, 16);
- else {
- printf("%s().%d Corrupt decoded patch buffer\n", __FUNCTION__, __LINE__);
- return 1;
- }
-
- /* Check for appropriate magic */
- if (memcmp(header, BSDIFF_HEADER, 8) != 0 && memcmp(header, SSDIFF_HEADER, 8) != 0) {
- printf("%s().%d Patch buffer header corrupt\n", __FUNCTION__, __LINE__ );
- return 1;
- }
-
- /* Read lengths from header */
- newsize = offtin(header + 8);
-
- if ((newsize < 0)) {
- printf("%s().%d Patch buffer corrupt\n", __FUNCTION__, __LINE__ );
- return 1;
- }
-
- /* Cset patch_buffer_offset at the right place */
- patch_buffer_offset += 16;
-
- if (((fd = open(oldfile, O_RDONLY, 0)) < 0) ||
- ((oldsize = lseek(fd, 0, SEEK_END)) == -1) ||
- ((old = malloc(memory_usage + 1)) == NULL) ||
- (lseek(fd, 0, SEEK_SET) != 0)) {
- printf("Corruption in old file %s\n", oldfile);
- result = 1;
- goto Cleanup;
- }
-
- if ((*dest_buf = malloc(newsize + 1)) == NULL) {
- printf("Corruption in old file %s\n", oldfile);
- result = 1;
- goto Cleanup;
- }
- oldpos = 0;
- newpos = 0;
-
- total_write = 0;
-
- while (total_write != newsize) {
- /* Read control data */
- for (j = 0; j <= 3; j++) {
- memcpy(buf, patch_buffer + patch_buffer_offset, 8);
- patch_buffer_offset += 8;
- ctrl[j] = offtin(buf);
- };
-
- total_write += (ctrl[0] + ctrl[1]);
- newpos = ctrl[3];
- oldpos = ctrl[2];
-
- //////////////////////////////////////////////////////////////////////////////////
- flag = true;
- match_size = ctrl[0];
- while (flag == true) {
- if (match_size <= memory_usage) {
- if (pread(fd, old, match_size, oldpos) != match_size) {
- printf("Corruption in old file %s\n", oldfile);
- result = 1;
- goto Cleanup;
- }
- if (newpos + match_size > newsize) {
- printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
- result = 1;
- goto Cleanup;
- }
- memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, match_size);
- patch_buffer_offset += match_size;
- for (j = 0; j < match_size; j++) {
- (*dest_buf)[newpos + j] += old[j];
- }
- newpos += match_size;
- flag = false;
- } else {
- if (pread(fd, old, memory_usage, oldpos) != memory_usage) {
- printf("%s().%d Corruption in old file %s\n", __FUNCTION__, __LINE__ , oldfile);
- result = 1;
- goto Cleanup;
- }
- if (newpos + memory_usage > newsize) {
- printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
- result = 1;
- goto Cleanup;
- }
- memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, memory_usage);
- patch_buffer_offset += memory_usage;
- for (j = 0; j < memory_usage; j++)
- (*dest_buf)[newpos + j] += old[j];
- match_size -= memory_usage;
- oldpos += memory_usage;
- newpos += memory_usage;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////
- /* Sanity-check */
- if (newpos + ctrl[1] > newsize) {
- printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__ );
- result = 1;
- goto Cleanup;
- }
- /* Read extra string */
- memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, ctrl[1]);
- patch_buffer_offset += ctrl[1];
- };
- *dest_size = newsize;
-Cleanup:
- //close old file
- if (fd >= 0)
- close(fd);
- if (old)
- free(old);
- return result;
-}
int SS_ApplyBsdiff(char *oldfile, char *newfile, char *patch, SinkFn sink, void *token, sha1_ctx_t * ctx1)
{