##// END OF EJS Templates
catch errors and throw exception with invalid binary patch data
Benoit Boissinot -
r1722:681c5c21 default
parent child Browse files
Show More
@@ -43,6 +43,7 b' static uint32_t ntohl(uint32_t x)'
43 #endif
43 #endif
44
44
45 static char mpatch_doc[] = "Efficient binary patching.";
45 static char mpatch_doc[] = "Efficient binary patching.";
46 static PyObject *mpatch_Error;
46
47
47 struct frag {
48 struct frag {
48 int start, end, len;
49 int start, end, len;
@@ -65,8 +66,11 b' static struct flist *lalloc(int size)'
65 a = NULL;
66 a = NULL;
66 } else
67 } else
67 a->head = a->tail = a->base;
68 a->head = a->tail = a->base;
69 return a;
68 }
70 }
69 return a;
71 if (!PyErr_Occurred())
72 PyErr_NoMemory();
73 return NULL;
70 }
74 }
71
75
72 static void lfree(struct flist *a)
76 static void lfree(struct flist *a)
@@ -215,6 +219,9 b' static struct flist *decode(char *bin, i'
215
219
216 /* assume worst case size, we won't have many of these lists */
220 /* assume worst case size, we won't have many of these lists */
217 l = lalloc(len / 12);
221 l = lalloc(len / 12);
222 if (!l)
223 return NULL;
224
218 lt = l->tail;
225 lt = l->tail;
219
226
220 while (bin < end) {
227 while (bin < end) {
@@ -227,6 +234,13 b' static struct flist *decode(char *bin, i'
227 lt++;
234 lt++;
228 }
235 }
229
236
237 if (bin != end) {
238 if (!PyErr_Occurred())
239 PyErr_SetString(mpatch_Error, "patch cannot be decoded");
240 lfree(l);
241 return NULL;
242 }
243
230 l->tail = lt;
244 l->tail = lt;
231 return l;
245 return l;
232 }
246 }
@@ -238,6 +252,12 b' static int calcsize(int len, struct flis'
238 struct frag *f = l->head;
252 struct frag *f = l->head;
239
253
240 while (f != l->tail) {
254 while (f != l->tail) {
255 if (f->start < last || f->end > len) {
256 if (!PyErr_Occurred())
257 PyErr_SetString(mpatch_Error,
258 "invalid patch");
259 return -1;
260 }
241 outlen += f->start - last;
261 outlen += f->start - last;
242 last = f->end;
262 last = f->end;
243 outlen += f->len;
263 outlen += f->len;
@@ -248,13 +268,19 b' static int calcsize(int len, struct flis'
248 return outlen;
268 return outlen;
249 }
269 }
250
270
251 static void apply(char *buf, char *orig, int len, struct flist *l)
271 static int apply(char *buf, char *orig, int len, struct flist *l)
252 {
272 {
253 struct frag *f = l->head;
273 struct frag *f = l->head;
254 int last = 0;
274 int last = 0;
255 char *p = buf;
275 char *p = buf;
256
276
257 while (f != l->tail) {
277 while (f != l->tail) {
278 if (f->start < last || f->end > len) {
279 if (!PyErr_Occurred())
280 PyErr_SetString(mpatch_Error,
281 "invalid patch");
282 return 0;
283 }
258 memcpy(p, orig + last, f->start - last);
284 memcpy(p, orig + last, f->start - last);
259 p += f->start - last;
285 p += f->start - last;
260 memcpy(p, f->data, f->len);
286 memcpy(p, f->data, f->len);
@@ -263,6 +289,7 b' static void apply(char *buf, char *orig,'
263 f++;
289 f++;
264 }
290 }
265 memcpy(p, orig + last, len - last);
291 memcpy(p, orig + last, len - last);
292 return 1;
266 }
293 }
267
294
268 /* recursively generate a patch of all bins between start and end */
295 /* recursively generate a patch of all bins between start and end */
@@ -304,16 +331,25 b' patches(PyObject *self, PyObject *args)'
304
331
305 patch = fold(bins, 0, len);
332 patch = fold(bins, 0, len);
306 if (!patch)
333 if (!patch)
307 return PyErr_NoMemory();
334 return NULL;
308
335
309 outlen = calcsize(PyString_Size(text), patch);
336 outlen = calcsize(PyString_Size(text), patch);
337 if (outlen < 0) {
338 result = NULL;
339 goto cleanup;
340 }
310 result = PyString_FromStringAndSize(NULL, outlen);
341 result = PyString_FromStringAndSize(NULL, outlen);
311 if (result) {
342 if (!result) {
312 in = PyString_AsString(text);
343 result = NULL;
313 out = PyString_AsString(result);
344 goto cleanup;
314 apply(out, in, PyString_Size(text), patch);
315 }
345 }
316
346 in = PyString_AsString(text);
347 out = PyString_AsString(result);
348 if (!apply(out, in, PyString_Size(text), patch)) {
349 Py_DECREF(result);
350 result = NULL;
351 }
352 cleanup:
317 lfree(patch);
353 lfree(patch);
318 return result;
354 return result;
319 }
355 }
@@ -327,5 +363,6 b' PyMODINIT_FUNC'
327 initmpatch(void)
363 initmpatch(void)
328 {
364 {
329 Py_InitModule3("mpatch", methods, mpatch_doc);
365 Py_InitModule3("mpatch", methods, mpatch_doc);
366 mpatch_Error = PyErr_NewException("mpatch.mpatchError", NULL, NULL);
330 }
367 }
331
368
General Comments 0
You need to be logged in to leave comments. Login now