LibreOffice Module onlineupdate (master) 1
bspatch.cxx
Go to the documentation of this file.
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 <algorithm>
36#include <sys/stat.h>
37#include <stdlib.h>
38#include <stdio.h>
39#include <fcntl.h>
40#include <string.h>
41#include <limits.h>
42
43#if defined(_WIN32)
44# include <io.h>
45#else
46# include <unistd.h>
47#endif
48
49#ifdef _WIN32
50# include <winsock2.h>
51#else
52# include <arpa/inet.h>
53#endif
54
55#ifndef SSIZE_MAX
56# define SSIZE_MAX LONG_MAX
57#endif
58
59int
60MBS_ReadHeader(FILE* file, MBSPatchHeader *header)
61{
62 size_t s = fread(header, 1, sizeof(MBSPatchHeader), file);
63 if (s != sizeof(MBSPatchHeader))
64 return READ_ERROR;
65
66 header->slen = ntohl(header->slen);
67 header->scrc32 = ntohl(header->scrc32);
68 header->dlen = ntohl(header->dlen);
69 header->cblen = ntohl(header->cblen);
70 header->difflen = ntohl(header->difflen);
71 header->extralen = ntohl(header->extralen);
72
73 struct stat hs;
74 s = fstat(fileno(file), &hs);
75 if (s)
76 return READ_ERROR;
77
78 if (memcmp(header->tag, "MBDIFF10", 8) != 0)
80
81 if (sizeof(MBSPatchHeader) +
82 header->cblen +
83 header->difflen +
84 header->extralen != uint32_t(hs.st_size))
86
87 return OK;
88}
89
90int
91MBS_ApplyPatch(const MBSPatchHeader *header, FILE* patchFile,
92 unsigned char *fbuffer, FILE* file)
93{
94 unsigned char *fbufend = fbuffer + header->slen;
95
96 unsigned char *buf = (unsigned char*) malloc(header->cblen +
97 header->difflen +
98 header->extralen);
99 if (!buf)
100 return BSPATCH_MEM_ERROR;
101
102 int rv = OK;
103
104 size_t r = header->cblen + header->difflen + header->extralen;
105 unsigned char *wb = buf;
106 while (r)
107 {
108 const size_t count = std::min(r, size_t(SSIZE_MAX));
109 size_t c = fread(wb, 1, count, patchFile);
110 if (c != count)
111 {
112 rv = READ_ERROR;
113 goto end;
114 }
115
116 r -= c;
117 wb += c;
118 }
119
120 {
121 MBSPatchTriple *ctrlsrc = (MBSPatchTriple*) buf;
122 unsigned char *diffsrc = buf + header->cblen;
123 unsigned char *extrasrc = diffsrc + header->difflen;
124
125 MBSPatchTriple *ctrlend = (MBSPatchTriple*) diffsrc;
126 unsigned char *diffend = extrasrc;
127 unsigned char *extraend = extrasrc + header->extralen;
128
129 do
130 {
131 ctrlsrc->x = ntohl(ctrlsrc->x);
132 ctrlsrc->y = ntohl(ctrlsrc->y);
133 ctrlsrc->z = ntohl(ctrlsrc->z);
134
135#ifdef DEBUG_bsmedberg
136 printf("Applying block:\n"
137 " x: %u\n"
138 " y: %u\n"
139 " z: %i\n",
140 ctrlsrc->x,
141 ctrlsrc->y,
142 ctrlsrc->z);
143#endif
144
145 /* Add x bytes from oldfile to x bytes from the diff block */
146
147 if (fbuffer + ctrlsrc->x > fbufend ||
148 diffsrc + ctrlsrc->x > diffend)
149 {
151 goto end;
152 }
153 for (uint32_t i = 0; i < ctrlsrc->x; ++i)
154 {
155 diffsrc[i] += fbuffer[i];
156 }
157 if ((uint32_t) fwrite(diffsrc, 1, ctrlsrc->x, file) != ctrlsrc->x)
158 {
160 goto end;
161 }
162 fbuffer += ctrlsrc->x;
163 diffsrc += ctrlsrc->x;
164
165 /* Copy y bytes from the extra block */
166
167 if (extrasrc + ctrlsrc->y > extraend)
168 {
170 goto end;
171 }
172 if ((uint32_t) fwrite(extrasrc, 1, ctrlsrc->y, file) != ctrlsrc->y)
173 {
175 goto end;
176 }
177 extrasrc += ctrlsrc->y;
178
179 /* "seek" forwards in oldfile by z bytes */
180
181 if (fbuffer + ctrlsrc->z > fbufend)
182 {
184 goto end;
185 }
186 fbuffer += ctrlsrc->z;
187
188 /* and on to the next control block */
189
190 ++ctrlsrc;
191 }
192 while (ctrlsrc < ctrlend);
193 }
194
195end:
196 free(buf);
197 return rv;
198}
constexpr sal_Int8 header[]
#define SSIZE_MAX
Definition: bspatch.cxx:56
int MBS_ApplyPatch(const MBSPatchHeader *header, FILE *patchFile, unsigned char *fbuffer, FILE *file)
Apply a patch.
Definition: bspatch.cxx:91
int MBS_ReadHeader(FILE *file, MBSPatchHeader *header)
Read the header of a patch file into the MBSPatchHeader structure.
Definition: bspatch.cxx:60
#define BSPATCH_MEM_ERROR
Definition: errors.h:29
#define OK
Definition: errors.h:10
#define UNEXPECTED_BSPATCH_ERROR
Definition: errors.h:63
#define READ_ERROR
Definition: errors.h:23
#define WRITE_ERROR_PATCH_FILE
Definition: errors.h:78
int i
end
sal_uInt32 ntohl(sal_uInt32 n)
int32_t z
Definition: bspatch.h:92
uint32_t y
Definition: bspatch.h:91
uint32_t x
Definition: bspatch.h:90