Mercurial > hg
comparison mercurial/mpatch.c @ 128:d6afb6dbf9f2
Add safety checking to mpatch
author | mpm@selenic.com |
---|---|
date | Sat, 21 May 2005 13:14:58 -0800 |
parents | 7ed96baa7caa |
children | 97d83e7fbf2f |
comparison
equal
deleted
inserted
replaced
127:44538462d3c8 | 128:d6afb6dbf9f2 |
---|---|
37 struct frag *base, *head, *tail; | 37 struct frag *base, *head, *tail; |
38 }; | 38 }; |
39 | 39 |
40 static struct flist *lalloc(int size) | 40 static struct flist *lalloc(int size) |
41 { | 41 { |
42 struct flist *a; | 42 struct flist *a = NULL; |
43 | 43 |
44 a = malloc(sizeof(struct flist)); | 44 a = malloc(sizeof(struct flist)); |
45 a->head = a->tail = a->base = malloc(sizeof(struct frag) * size); | 45 if (a) { |
46 a->base = malloc(sizeof(struct frag) * size); | |
47 if (!a->base) | |
48 free(a); | |
49 else | |
50 a->head = a->tail = a->base; | |
51 } | |
46 return a; | 52 return a; |
47 } | 53 } |
48 | 54 |
49 static void lfree(struct flist *a) | 55 static void lfree(struct flist *a) |
50 { | 56 { |
51 free(a->base); | 57 if (a) { |
52 free(a); | 58 free(a->base); |
59 free(a); | |
60 } | |
53 } | 61 } |
54 | 62 |
55 static int lsize(struct flist *a) | 63 static int lsize(struct flist *a) |
56 { | 64 { |
57 return a->tail - a->head; | 65 return a->tail - a->head; |
142 | 150 |
143 /* combine hunk lists a and b, while adjusting b for offset changes in a/ | 151 /* combine hunk lists a and b, while adjusting b for offset changes in a/ |
144 this deletes a and b and returns the resultant list. */ | 152 this deletes a and b and returns the resultant list. */ |
145 static struct flist *combine(struct flist *a, struct flist *b) | 153 static struct flist *combine(struct flist *a, struct flist *b) |
146 { | 154 { |
147 struct flist *c; | 155 struct flist *c = NULL; |
148 struct frag *bh = b->head, *ct; | 156 struct frag *bh, *ct; |
149 int offset = 0, post; | 157 int offset = 0, post; |
150 | 158 |
151 c = lalloc((lsize(a) + lsize(b)) * 2); | 159 if (a && b) |
152 | 160 c = lalloc((lsize(a) + lsize(b)) * 2); |
153 while (bh != b->tail) { | 161 |
154 /* save old hunks */ | 162 if (c) { |
155 offset = gather(c, a, bh->start, offset); | 163 |
156 | 164 for (bh = b->head; bh != b->tail; bh++) { |
157 /* discard replaced hunks */ | 165 /* save old hunks */ |
158 post = discard(a, bh->end, offset); | 166 offset = gather(c, a, bh->start, offset); |
159 | 167 |
160 /* insert new hunk */ | 168 /* discard replaced hunks */ |
161 ct = c->tail; | 169 post = discard(a, bh->end, offset); |
162 ct->start = bh->start - offset; | 170 |
163 ct->end = bh->end - post; | 171 /* insert new hunk */ |
164 ct->len = bh->len; | 172 ct = c->tail; |
165 ct->data = bh->data; | 173 ct->start = bh->start - offset; |
166 c->tail++; | 174 ct->end = bh->end - post; |
167 bh++; | 175 ct->len = bh->len; |
168 offset = post; | 176 ct->data = bh->data; |
169 } | 177 c->tail++; |
170 | 178 offset = post; |
171 /* hold on to tail from a */ | 179 } |
172 memcpy(c->tail, a->head, sizeof(struct frag) * lsize(a)); | 180 |
173 c->tail += lsize(a); | 181 /* hold on to tail from a */ |
182 memcpy(c->tail, a->head, sizeof(struct frag) * lsize(a)); | |
183 c->tail += lsize(a); | |
184 } | |
185 | |
174 lfree(a); | 186 lfree(a); |
175 lfree(b); | 187 lfree(b); |
176 return c; | 188 return c; |
177 } | 189 } |
178 | 190 |
240 int len; | 252 int len; |
241 | 253 |
242 if (start + 1 == end) { | 254 if (start + 1 == end) { |
243 /* trivial case, output a decoded list */ | 255 /* trivial case, output a decoded list */ |
244 PyObject *tmp = PyList_GetItem(bins, start); | 256 PyObject *tmp = PyList_GetItem(bins, start); |
257 if (!tmp) | |
258 return NULL; | |
245 return decode(PyString_AsString(tmp), PyString_Size(tmp)); | 259 return decode(PyString_AsString(tmp), PyString_Size(tmp)); |
246 } | 260 } |
247 | 261 |
248 /* divide and conquer, memory management is elsewhere */ | 262 /* divide and conquer, memory management is elsewhere */ |
249 len = (end - start) / 2; | 263 len = (end - start) / 2; |
257 PyObject *text, *bins, *result; | 271 PyObject *text, *bins, *result; |
258 struct flist *patch; | 272 struct flist *patch; |
259 char *in, *out; | 273 char *in, *out; |
260 int len, outlen; | 274 int len, outlen; |
261 | 275 |
262 if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins)) | 276 if (!PyArg_ParseTuple(args, "SO:mpatch", &text, &bins)) |
263 return NULL; | 277 return NULL; |
264 | 278 |
265 len = PyList_Size(bins); | 279 len = PyList_Size(bins); |
266 if (!len) { | 280 if (!len) { |
267 /* nothing to do */ | 281 /* nothing to do */ |
268 Py_INCREF(text); | 282 Py_INCREF(text); |
269 return text; | 283 return text; |
270 } | 284 } |
271 | 285 |
272 patch = fold(bins, 0, len); | 286 patch = fold(bins, 0, len); |
287 if (!patch) | |
288 return PyErr_NoMemory(); | |
289 | |
273 outlen = calcsize(PyString_Size(text), patch); | 290 outlen = calcsize(PyString_Size(text), patch); |
274 result = PyString_FromStringAndSize(NULL, outlen); | 291 result = PyString_FromStringAndSize(NULL, outlen); |
275 in = PyString_AsString(text); | 292 if (result) { |
276 out = PyString_AsString(result); | 293 in = PyString_AsString(text); |
277 apply(out, in, PyString_Size(text), patch); | 294 out = PyString_AsString(result); |
295 apply(out, in, PyString_Size(text), patch); | |
296 } | |
297 | |
278 lfree(patch); | 298 lfree(patch); |
279 | |
280 return result; | 299 return result; |
281 } | 300 } |
282 | 301 |
283 static PyMethodDef methods[] = { | 302 static PyMethodDef methods[] = { |
284 {"patches", patches, METH_VARARGS, "apply a series of patches\n"}, | 303 {"patches", patches, METH_VARARGS, "apply a series of patches\n"}, |