Add delta.ua - a binary to apply an upgrade of DELTA_FS type.
[platform/core/system/upgrade.git] / src / delta-ua / engine / SS_ApplyPatch.c
1 /*-
2  * Copyright 2003-2005 Colin Percival
3  * Copyright 2012 Matthew Endsley
4  * All rights reserved
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted providing that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in the
13  *      documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  *
27  * Modifications are made in reimplementing suffix sort array generation
28  * and how the data is read and written to.Iterative part replaced the
29  * recursive implementation to avoid buffer overflow problems
30  */
31 #include <string.h>
32 #include <err.h>
33 #include "SS_PatchDelta.h"
34 #include "fota_common.h"
35 #include "sha1.h"
36 #include "SS_Engine_Errors.h"
37 #include "SS_FSUpdate.h"
38
39 #include "ss_bspatch_common.h"
40 #include <Alloc.h>
41 #include <7zFile.h>
42 #include <7zVersion.h>
43 #include <LzmaDec.h>
44 #include <LzmaEnc.h>
45
46
47 int SS_ApplyBsdiff(char *oldfile, char *newfile, char *patch, SinkFn sink, void *token, SHA1_CTX * ctx1)
48 {
49         UInt64 unpackSize = 0;
50         CFileSeqInStream inStream;
51         ISeqOutStream outStream;
52         unsigned char *buf_res = NULL;
53         unsigned char *new_data = NULL;
54         char buf[256];
55         ssize_t new_size = 0;
56         int result = E_SS_FAILURE;
57
58         FileSeqInStream_CreateVTable(&inStream);
59         File_Construct(&inStream.file);
60         FileOutStream_CreateVTable((CFileOutStream *) & outStream);
61
62         if (InFile_Open(&inStream.file, patch) != 0)
63                 return E_SS_FAILURE;
64
65         UInt64 i;
66         CLzmaDec state;
67         unsigned char header[LZMA_PROPS_SIZE + 8];
68
69         RINOK(SeqInStream_Read(&inStream.s, header, sizeof(header)));
70
71         unpackSize = 0;
72         for (i = 0; i < 8; i++)
73                 unpackSize += (UInt64) header[LZMA_PROPS_SIZE + i] << (i * 8);
74
75         LzmaDec_Construct(&state);
76         RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc));
77
78         //decompress the patch file into buf_res
79         buf_res = (unsigned char *)SS_Malloc(unpackSize);
80         if (!buf_res) {
81                 LOGE("Bad memory allocation\n");
82                 goto Cleanup;
83         }
84         result = Decode2(&state, &outStream, &inStream.s, &unpackSize, buf_res);
85
86         LzmaDec_Free(&state, &g_Alloc);
87         File_Close(&inStream.file);
88
89         if (result != S_SS_SUCCESS) {
90                 LOGE("Error decompression failed with code : [%d]\n", result);
91                 goto Cleanup;
92         }
93         //apply patch using buffer decoded by Decode2
94         result = apply_patch(oldfile, buf_res, &new_data, &new_size);
95         if (result != S_SS_SUCCESS)
96                 goto Cleanup;
97
98         result = (sink(new_data, new_size, token) < new_size) ? E_SS_FAILURE : S_SS_SUCCESS;
99         if (result != S_SS_SUCCESS) {
100                 strerror_r(errno, buf, sizeof(buf));
101                 LOGE("short write of output: %d (%s)\n", errno, buf);
102                 goto Cleanup;
103         }
104
105         if (ctx1)
106                 SHA1Update(ctx1, new_data, new_size);
107 Cleanup:
108         if (new_data)
109                 SS_Free(new_data);
110         if (buf_res)
111                 SS_Free(buf_res);
112         File_Close(&inStream.file);//wgid: 27007
113         return result;
114
115 }