toolkit/mozapps/update/updater/bspatch.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:08ab625c67b9
1 /*-
2 * Copyright 2003,2004 Colin Percival
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 *
26 * Changelog:
27 * 2005-04-26 - Define the header as a C structure, add a CRC32 checksum to
28 * the header, and make all the types 32-bit.
29 * --Benjamin Smedberg <benjamin@smedbergs.us>
30 */
31
32 #include "bspatch.h"
33 #include "errors.h"
34
35 #include <sys/stat.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <fcntl.h>
39 #include <string.h>
40 #include <limits.h>
41
42 #if defined(XP_WIN)
43 # include <io.h>
44 #else
45 # include <unistd.h>
46 #endif
47
48 #ifdef XP_WIN
49 # include <winsock2.h>
50 #else
51 # include <arpa/inet.h>
52 #endif
53
54 #ifndef SSIZE_MAX
55 # define SSIZE_MAX LONG_MAX
56 #endif
57
58 int
59 MBS_ReadHeader(FILE* file, MBSPatchHeader *header)
60 {
61 size_t s = fread(header, 1, sizeof(MBSPatchHeader), file);
62 if (s != sizeof(MBSPatchHeader))
63 return READ_ERROR;
64
65 header->slen = ntohl(header->slen);
66 header->scrc32 = ntohl(header->scrc32);
67 header->dlen = ntohl(header->dlen);
68 header->cblen = ntohl(header->cblen);
69 header->difflen = ntohl(header->difflen);
70 header->extralen = ntohl(header->extralen);
71
72 struct stat hs;
73 s = fstat(fileno(file), &hs);
74 if (s)
75 return READ_ERROR;
76
77 if (memcmp(header->tag, "MBDIFF10", 8) != 0)
78 return UNEXPECTED_BSPATCH_ERROR;
79
80 if (sizeof(MBSPatchHeader) +
81 header->cblen +
82 header->difflen +
83 header->extralen != uint32_t(hs.st_size))
84 return UNEXPECTED_BSPATCH_ERROR;
85
86 return OK;
87 }
88
89 int
90 MBS_ApplyPatch(const MBSPatchHeader *header, FILE* patchFile,
91 unsigned char *fbuffer, FILE* file)
92 {
93 unsigned char *fbufend = fbuffer + header->slen;
94
95 unsigned char *buf = (unsigned char*) malloc(header->cblen +
96 header->difflen +
97 header->extralen);
98 if (!buf)
99 return BSPATCH_MEM_ERROR;
100
101 int rv = OK;
102
103 size_t r = header->cblen + header->difflen + header->extralen;
104 unsigned char *wb = buf;
105 while (r) {
106 const size_t count = (r > SSIZE_MAX) ? SSIZE_MAX : r;
107 size_t c = fread(wb, 1, count, patchFile);
108 if (c != count) {
109 rv = READ_ERROR;
110 goto end;
111 }
112
113 r -= c;
114 wb += c;
115 }
116
117 {
118 MBSPatchTriple *ctrlsrc = (MBSPatchTriple*) buf;
119 unsigned char *diffsrc = buf + header->cblen;
120 unsigned char *extrasrc = diffsrc + header->difflen;
121
122 MBSPatchTriple *ctrlend = (MBSPatchTriple*) diffsrc;
123 unsigned char *diffend = extrasrc;
124 unsigned char *extraend = extrasrc + header->extralen;
125
126 do {
127 ctrlsrc->x = ntohl(ctrlsrc->x);
128 ctrlsrc->y = ntohl(ctrlsrc->y);
129 ctrlsrc->z = ntohl(ctrlsrc->z);
130
131 #ifdef DEBUG_bsmedberg
132 printf("Applying block:\n"
133 " x: %u\n"
134 " y: %u\n"
135 " z: %i\n",
136 ctrlsrc->x,
137 ctrlsrc->y,
138 ctrlsrc->z);
139 #endif
140
141 /* Add x bytes from oldfile to x bytes from the diff block */
142
143 if (fbuffer + ctrlsrc->x > fbufend ||
144 diffsrc + ctrlsrc->x > diffend) {
145 rv = UNEXPECTED_BSPATCH_ERROR;
146 goto end;
147 }
148 for (uint32_t i = 0; i < ctrlsrc->x; ++i) {
149 diffsrc[i] += fbuffer[i];
150 }
151 if ((uint32_t) fwrite(diffsrc, 1, ctrlsrc->x, file) != ctrlsrc->x) {
152 rv = WRITE_ERROR;
153 goto end;
154 }
155 fbuffer += ctrlsrc->x;
156 diffsrc += ctrlsrc->x;
157
158 /* Copy y bytes from the extra block */
159
160 if (extrasrc + ctrlsrc->y > extraend) {
161 rv = UNEXPECTED_BSPATCH_ERROR;
162 goto end;
163 }
164 if ((uint32_t) fwrite(extrasrc, 1, ctrlsrc->y, file) != ctrlsrc->y) {
165 rv = WRITE_ERROR;
166 goto end;
167 }
168 extrasrc += ctrlsrc->y;
169
170 /* "seek" forwards in oldfile by z bytes */
171
172 if (fbuffer + ctrlsrc->z > fbufend) {
173 rv = UNEXPECTED_BSPATCH_ERROR;
174 goto end;
175 }
176 fbuffer += ctrlsrc->z;
177
178 /* and on to the next control block */
179
180 ++ctrlsrc;
181 } while (ctrlsrc < ctrlend);
182 }
183
184 end:
185 free(buf);
186 return rv;
187 }

mercurial