##// 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 43 #endif
44 44
45 45 static char mpatch_doc[] = "Efficient binary patching.";
46 static PyObject *mpatch_Error;
46 47
47 48 struct frag {
48 49 int start, end, len;
@@ -65,8 +66,11 b' static struct flist *lalloc(int size)'
65 66 a = NULL;
66 67 } else
67 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 76 static void lfree(struct flist *a)
@@ -215,6 +219,9 b' static struct flist *decode(char *bin, i'
215 219
216 220 /* assume worst case size, we won't have many of these lists */
217 221 l = lalloc(len / 12);
222 if (!l)
223 return NULL;
224
218 225 lt = l->tail;
219 226
220 227 while (bin < end) {
@@ -227,6 +234,13 b' static struct flist *decode(char *bin, i'
227 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 244 l->tail = lt;
231 245 return l;
232 246 }
@@ -238,6 +252,12 b' static int calcsize(int len, struct flis'
238 252 struct frag *f = l->head;
239 253
240 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 261 outlen += f->start - last;
242 262 last = f->end;
243 263 outlen += f->len;
@@ -248,13 +268,19 b' static int calcsize(int len, struct flis'
248 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 273 struct frag *f = l->head;
254 274 int last = 0;
255 275 char *p = buf;
256 276
257 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 284 memcpy(p, orig + last, f->start - last);
259 285 p += f->start - last;
260 286 memcpy(p, f->data, f->len);
@@ -263,6 +289,7 b' static void apply(char *buf, char *orig,'
263 289 f++;
264 290 }
265 291 memcpy(p, orig + last, len - last);
292 return 1;
266 293 }
267 294
268 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 332 patch = fold(bins, 0, len);
306 333 if (!patch)
307 return PyErr_NoMemory();
334 return NULL;
308 335
309 336 outlen = calcsize(PyString_Size(text), patch);
337 if (outlen < 0) {
338 result = NULL;
339 goto cleanup;
340 }
310 341 result = PyString_FromStringAndSize(NULL, outlen);
311 if (result) {
312 in = PyString_AsString(text);
313 out = PyString_AsString(result);
314 apply(out, in, PyString_Size(text), patch);
342 if (!result) {
343 result = NULL;
344 goto cleanup;
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 353 lfree(patch);
318 354 return result;
319 355 }
@@ -327,5 +363,6 b' PyMODINIT_FUNC'
327 363 initmpatch(void)
328 364 {
329 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