##// END OF EJS Templates
index parser: fix refcounting in case of errors, refactor...
Benoit Boissinot -
r7154:7fdf7a0a default
parent child Browse files
Show More
@@ -238,6 +238,40 b' quit:'
238 238 const char nullid[20];
239 239 const int nullrev = -1;
240 240
241 /* create an index tuple, insert into the nodemap */
242 static PyObject * _build_idx_entry(PyObject *nodemap, int n, uint64_t offset_flags,
243 int comp_len, int uncomp_len, int base_rev,
244 int link_rev, int parent_1, int parent_2,
245 const char *c_node_id)
246 {
247 int err;
248 PyObject *entry, *node_id, *n_obj;
249
250 node_id = PyString_FromStringAndSize(c_node_id, 20);
251 n_obj = PyInt_FromLong(n);
252 if (!node_id || !n_obj)
253 err = -1;
254 else
255 err = PyDict_SetItem(nodemap, node_id, n_obj);
256
257 Py_XDECREF(n_obj);
258 if (err)
259 goto error_dealloc;
260
261 entry = Py_BuildValue("LiiiiiiN", offset_flags, comp_len,
262 uncomp_len, base_rev, link_rev,
263 parent_1, parent_2, node_id);
264 if (!entry)
265 goto error_dealloc;
266 PyObject_GC_UnTrack(entry); /* don't waste time with this */
267
268 return entry;
269
270 error_dealloc:
271 Py_XDECREF(node_id);
272 return NULL;
273 }
274
241 275 /* RevlogNG format (all in big endian, data may be inlined):
242 276 * 6 bytes: offset
243 277 * 2 bytes: flags
@@ -252,11 +286,11 b' const int nullrev = -1;'
252 286 static int _parse_index_ng (const char *data, int size, int inlined,
253 287 PyObject *index, PyObject *nodemap)
254 288 {
255 PyObject *entry = NULL, *node_id = NULL, *n_obj = NULL;
256 PyObject *nullrev_obj = NULL, *nullid_obj = NULL;
289 PyObject *entry;
290 int n = 0, err;
291 uint64_t offset_flags;
257 292 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
258 uint64_t offset_flags;
259 int n = 0;
293 const char *c_node_id;
260 294 const char *end = data + size;
261 295
262 296 while (data < end) {
@@ -268,35 +302,28 b' static int _parse_index_ng (const char *'
268 302 offset_flags |= ((uint64_t) offset_high) << 32;
269 303 }
270 304
271
272 305 comp_len = ntohl(*((uint32_t *) (data + 8)));
273 306 uncomp_len = ntohl(*((uint32_t *) (data + 12)));
274 307 base_rev = ntohl(*((uint32_t *) (data + 16)));
275 308 link_rev = ntohl(*((uint32_t *) (data + 20)));
276 309 parent_1 = ntohl(*((uint32_t *) (data + 24)));
277 310 parent_2 = ntohl(*((uint32_t *) (data + 28)));
278 node_id = PyString_FromStringAndSize(data + 32, 20);
279 n_obj = PyInt_FromLong(n);
280 if (!node_id || !n_obj ||
281 PyDict_SetItem(nodemap, node_id, n_obj) != 0)
282 goto quit;
283 Py_DECREF(n_obj);
311 c_node_id = data + 32;
284 312
285 entry = Py_BuildValue("LiiiiiiN", offset_flags, comp_len,
286 uncomp_len, base_rev, link_rev,
287 parent_1, parent_2, node_id);
288 PyObject_GC_UnTrack(entry); /* don't waste time with this */
313 entry = _build_idx_entry(nodemap, n, offset_flags,
314 comp_len, uncomp_len, base_rev,
315 link_rev, parent_1, parent_2,
316 c_node_id);
289 317 if (!entry)
290 goto quit;
318 return 0;
291 319
292 /* append to or set value in the index list */
293 320 if (inlined) {
294 if (PyList_Append(index, entry) != 0)
295 goto quit;
321 err = PyList_Append(index, entry);
296 322 Py_DECREF(entry);
297 } else {
323 if (err)
324 return 0;
325 } else
298 326 PyList_SET_ITEM(index, n, entry); /* steals reference */
299 }
300 327
301 328 data += 64 + (inlined ? comp_len : 0);
302 329 n++;
@@ -304,43 +331,26 b' static int _parse_index_ng (const char *'
304 331 if (data > end) {
305 332 if (!PyErr_Occurred())
306 333 PyErr_SetString(PyExc_ValueError, "corrupt index file");
307 goto quit;
334 return 0;
308 335 }
309 336
310 337 /* create the nullid/nullrev entry in the nodemap and the
311 338 * magic nullid entry in the index at [-1] */
312 nullid_obj = PyString_FromStringAndSize(nullid, 20);
313 nullrev_obj = PyInt_FromLong(nullrev);
314 if (!nodemap || !nullid_obj || !nullrev_obj ||
315 PyDict_SetItem(nodemap, nullid_obj, nullrev_obj) != 0)
316 goto quit;
317 Py_DECREF(nullrev_obj);
318
319 entry = Py_BuildValue("iiiiiiiN", 0, 0, 0, -1, -1, -1, -1, nullid_obj);
320 PyObject_GC_UnTrack(entry); /* don't waste time with this */
339 entry = _build_idx_entry(nodemap,
340 nullrev, 0, 0, 0, -1, -1, -1, -1, nullid);
321 341 if (!entry)
322 goto quit;
342 return 0;
323 343 if (inlined) {
324 if (PyList_Append(index, entry) != 0)
325 goto quit;
344 err = PyList_Append(index, entry);
326 345 Py_DECREF(entry);
327 } else {
346 if (err)
347 return 0;
348 } else
328 349 PyList_SET_ITEM(index, n, entry); /* steals reference */
329 }
330 350
331 351 return 1;
332
333 quit:
334 Py_XDECREF(n_obj);
335 Py_XDECREF(node_id);
336 Py_XDECREF(entry);
337 Py_XDECREF(nullrev_obj);
338 Py_XDECREF(nullid_obj);
339 return 0;
340 352 }
341 353
342
343
344 354 /* This function parses a index file and returns a Python tuple of the
345 355 * following format: (index, nodemap, cache)
346 356 *
@@ -367,6 +377,8 b' static PyObject *parse_index(PyObject *s'
367 377 goto quit;
368 378
369 379 nodemap = PyDict_New();
380 if (!nodemap)
381 goto quit;
370 382
371 383 /* set up the cache return value */
372 384 if (inlined) {
General Comments 0
You need to be logged in to leave comments. Login now