##// END OF EJS Templates
mpatch: rewrite pointer overflow checks
Matt Mackall -
r20167:09e41ac6 stable
parent child Browse files
Show More
@@ -202,7 +202,7 b' static struct flist *decode(const char *'
202 {
202 {
203 struct flist *l;
203 struct flist *l;
204 struct frag *lt;
204 struct frag *lt;
205 const char *data = bin + 12, *end = bin + len;
205 int pos = 0;
206
206
207 /* assume worst case size, we won't have many of these lists */
207 /* assume worst case size, we won't have many of these lists */
208 l = lalloc(len / 12);
208 l = lalloc(len / 12);
@@ -211,21 +211,18 b' static struct flist *decode(const char *'
211
211
212 lt = l->tail;
212 lt = l->tail;
213
213
214 while (data <= end) {
214 while (pos >= 0 && pos < len) {
215 lt->start = getbe32(bin);
215 lt->start = getbe32(bin + pos);
216 lt->end = getbe32(bin + 4);
216 lt->end = getbe32(bin + pos + 4);
217 lt->len = getbe32(bin + 8);
217 lt->len = getbe32(bin + pos + 8);
218 if (lt->start > lt->end)
218 if (lt->start > lt->end)
219 break; /* sanity check */
219 break; /* sanity check */
220 bin = data + lt->len;
220 lt->data = bin + pos + 12;
221 if (bin < data)
221 pos += 12 + lt->len;
222 break; /* big data + big (bogus) len can wrap around */
223 lt->data = data;
224 data = bin + 12;
225 lt++;
222 lt++;
226 }
223 }
227
224
228 if (bin != end) {
225 if (pos != len) {
229 if (!PyErr_Occurred())
226 if (!PyErr_Occurred())
230 PyErr_SetString(mpatch_Error, "patch cannot be decoded");
227 PyErr_SetString(mpatch_Error, "patch cannot be decoded");
231 lfree(l);
228 lfree(l);
@@ -355,32 +352,26 b' cleanup:'
355 static PyObject *
352 static PyObject *
356 patchedsize(PyObject *self, PyObject *args)
353 patchedsize(PyObject *self, PyObject *args)
357 {
354 {
358 long orig, start, end, len, outlen = 0, last = 0;
355 long orig, start, end, len, outlen = 0, last = 0, pos = 0;
359 Py_ssize_t patchlen;
356 Py_ssize_t patchlen;
360 char *bin, *binend, *data;
357 char *bin;
361
358
362 if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
359 if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
363 return NULL;
360 return NULL;
364
361
365 binend = bin + patchlen;
362 while (pos >= 0 && pos < patchlen) {
366 data = bin + 12;
363 start = getbe32(bin + pos);
367
364 end = getbe32(bin + pos + 4);
368 while (data <= binend) {
365 len = getbe32(bin + pos + 8);
369 start = getbe32(bin);
370 end = getbe32(bin + 4);
371 len = getbe32(bin + 8);
372 if (start > end)
366 if (start > end)
373 break; /* sanity check */
367 break; /* sanity check */
374 bin = data + len;
368 pos += 12 + len;
375 if (bin < data)
376 break; /* big data + big (bogus) len can wrap around */
377 data = bin + 12;
378 outlen += start - last;
369 outlen += start - last;
379 last = end;
370 last = end;
380 outlen += len;
371 outlen += len;
381 }
372 }
382
373
383 if (bin != binend) {
374 if (pos != patchlen) {
384 if (!PyErr_Occurred())
375 if (!PyErr_Occurred())
385 PyErr_SetString(mpatch_Error, "patch cannot be decoded");
376 PyErr_SetString(mpatch_Error, "patch cannot be decoded");
386 return NULL;
377 return NULL;
@@ -155,10 +155,10 b' static PyObject *parse_dirstate(PyObject'
155 {
155 {
156 PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
156 PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
157 PyObject *fname = NULL, *cname = NULL, *entry = NULL;
157 PyObject *fname = NULL, *cname = NULL, *entry = NULL;
158 char state, *str, *cur, *end, *cpos;
158 char state, *cur, *str, *cpos;
159 int mode, size, mtime;
159 int mode, size, mtime;
160 unsigned int flen;
160 unsigned int flen;
161 int len;
161 int len, pos = 40;
162
162
163 if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
163 if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
164 &PyDict_Type, &dmap,
164 &PyDict_Type, &dmap,
@@ -175,18 +175,17 b' static PyObject *parse_dirstate(PyObject'
175 goto quit;
175 goto quit;
176
176
177 /* read filenames */
177 /* read filenames */
178 cur = str + 40;
178 while (pos >= 40 && pos < len) {
179 end = str + len;
179 cur = str + pos;
180
181 while (cur < end - 17) {
182 /* unpack header */
180 /* unpack header */
183 state = *cur;
181 state = *cur;
184 mode = getbe32(cur + 1);
182 mode = getbe32(cur + 1);
185 size = getbe32(cur + 5);
183 size = getbe32(cur + 5);
186 mtime = getbe32(cur + 9);
184 mtime = getbe32(cur + 9);
187 flen = getbe32(cur + 13);
185 flen = getbe32(cur + 13);
186 pos += 17;
188 cur += 17;
187 cur += 17;
189 if (cur + flen > end || cur + flen < cur) {
188 if (flen > len - pos || flen < 0) {
190 PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
189 PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
191 goto quit;
190 goto quit;
192 }
191 }
@@ -212,10 +211,10 b' static PyObject *parse_dirstate(PyObject'
212 PyDict_SetItem(dmap, fname, entry) == -1)
211 PyDict_SetItem(dmap, fname, entry) == -1)
213 goto quit;
212 goto quit;
214 }
213 }
215 cur += flen;
216 Py_DECREF(fname);
214 Py_DECREF(fname);
217 Py_DECREF(entry);
215 Py_DECREF(entry);
218 fname = cname = entry = NULL;
216 fname = cname = entry = NULL;
217 pos += flen;
219 }
218 }
220
219
221 ret = parents;
220 ret = parents;
@@ -1678,28 +1677,23 b' static int index_assign_subscript(indexO'
1678 static long inline_scan(indexObject *self, const char **offsets)
1677 static long inline_scan(indexObject *self, const char **offsets)
1679 {
1678 {
1680 const char *data = PyString_AS_STRING(self->data);
1679 const char *data = PyString_AS_STRING(self->data);
1681 const char *end = data + PyString_GET_SIZE(self->data);
1680 Py_ssize_t pos = 0;
1681 Py_ssize_t end = PyString_GET_SIZE(self->data);
1682 long incr = v1_hdrsize;
1682 long incr = v1_hdrsize;
1683 Py_ssize_t len = 0;
1683 Py_ssize_t len = 0;
1684
1684
1685 while (data + v1_hdrsize <= end) {
1685 while (pos + v1_hdrsize <= end && pos >= 0) {
1686 uint32_t comp_len;
1686 uint32_t comp_len;
1687 const char *old_data;
1688 /* 3rd element of header is length of compressed inline data */
1687 /* 3rd element of header is length of compressed inline data */
1689 comp_len = getbe32(data + 8);
1688 comp_len = getbe32(data + pos + 8);
1690 incr = v1_hdrsize + comp_len;
1689 incr = v1_hdrsize + comp_len;
1691 if (incr < v1_hdrsize)
1692 break;
1693 if (offsets)
1690 if (offsets)
1694 offsets[len] = data;
1691 offsets[len] = data + pos;
1695 len++;
1692 len++;
1696 old_data = data;
1693 pos += incr;
1697 data += incr;
1698 if (data <= old_data)
1699 break;
1700 }
1694 }
1701
1695
1702 if (data != end && data + v1_hdrsize != end) {
1696 if (pos != end) {
1703 if (!PyErr_Occurred())
1697 if (!PyErr_Occurred())
1704 PyErr_SetString(PyExc_ValueError, "corrupt index file");
1698 PyErr_SetString(PyExc_ValueError, "corrupt index file");
1705 return -1;
1699 return -1;
General Comments 0
You need to be logged in to leave comments. Login now