21
return ref_iterator->vtable->peel(ref_iterator, peeled);
22
}
23
24
-int ref_iterator_abort(struct ref_iterator *ref_iterator)
24
+void ref_iterator_free(struct ref_iterator *ref_iterator)
25
{
26
- return ref_iterator->vtable->abort(ref_iterator);
26
+ if (ref_iterator) {
27
+ ref_iterator->vtable->release(ref_iterator);
28
+ /* Help make use-after-free bugs fail quickly: */
29
+ ref_iterator->vtable = NULL;
30
+ free(ref_iterator);
31
+ }
32
}
33
34
void base_ref_iterator_init(struct ref_iterator *iter,
41
iter->flags = 0;
42
}
43
39
-void base_ref_iterator_free(struct ref_iterator *iter)
40
-{
41
- /* Help make use-after-free bugs fail quickly: */
42
- iter->vtable = NULL;
43
- free(iter);
44
-}
45
-
44
struct empty_ref_iterator {
45
struct ref_iterator base;
46
};
47
50
-static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator)
48
+static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator UNUSED)
49
{
52
- return ref_iterator_abort(ref_iterator);
50
+ return ITER_DONE;
51
}
52
53
static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
56
BUG("peel called for empty iterator");
57
}
58
61
-static int empty_ref_iterator_abort(struct ref_iterator *ref_iterator)
59
+static void empty_ref_iterator_release(struct ref_iterator *ref_iterator UNUSED)
60
{
63
- base_ref_iterator_free(ref_iterator);
64
- return ITER_DONE;
61
}
62
63
static struct ref_iterator_vtable empty_ref_iterator_vtable = {
64
.advance = empty_ref_iterator_advance,
65
.peel = empty_ref_iterator_peel,
70
- .abort = empty_ref_iterator_abort,
66
+ .release = empty_ref_iterator_release,
67
};
68
69
struct ref_iterator *empty_ref_iterator_begin(void)
147
if (!iter->current) {
148
/* Initialize: advance both iterators to their first entries */
149
if ((ok = ref_iterator_advance(iter->iter0)) != ITER_OK) {
150
+ ref_iterator_free(iter->iter0);
151
iter->iter0 = NULL;
152
if (ok == ITER_ERROR)
153
goto error;
154
}
155
if ((ok = ref_iterator_advance(iter->iter1)) != ITER_OK) {
156
+ ref_iterator_free(iter->iter1);
157
iter->iter1 = NULL;
158
if (ok == ITER_ERROR)
159
goto error;
164
* entry:
165
*/
166
if ((ok = ref_iterator_advance(*iter->current)) != ITER_OK) {
167
+ ref_iterator_free(*iter->current);
168
*iter->current = NULL;
169
if (ok == ITER_ERROR)
170
goto error;
178
iter->select(iter->iter0, iter->iter1, iter->cb_data);
179
180
if (selection == ITER_SELECT_DONE) {
182
- return ref_iterator_abort(ref_iterator);
181
+ return ITER_DONE;
182
} else if (selection == ITER_SELECT_ERROR) {
184
- ref_iterator_abort(ref_iterator);
183
return ITER_ERROR;
184
}
185
193
194
if (selection & ITER_SKIP_SECONDARY) {
195
if ((ok = ref_iterator_advance(*secondary)) != ITER_OK) {
196
+ ref_iterator_free(*secondary);
197
*secondary = NULL;
198
if (ok == ITER_ERROR)
199
goto error;
210
}
211
212
error:
214
- ref_iterator_abort(ref_iterator);
213
return ITER_ERROR;
214
}
215
225
return ref_iterator_peel(*iter->current, peeled);
226
}
227
230
-static int merge_ref_iterator_abort(struct ref_iterator *ref_iterator)
228
+static void merge_ref_iterator_release(struct ref_iterator *ref_iterator)
229
{
230
struct merge_ref_iterator *iter =
231
(struct merge_ref_iterator *)ref_iterator;
234
- int ok = ITER_DONE;
235
-
236
- if (iter->iter0) {
237
- if (ref_iterator_abort(iter->iter0) != ITER_DONE)
238
- ok = ITER_ERROR;
239
- }
240
- if (iter->iter1) {
241
- if (ref_iterator_abort(iter->iter1) != ITER_DONE)
242
- ok = ITER_ERROR;
243
- }
244
- base_ref_iterator_free(ref_iterator);
245
- return ok;
232
+ ref_iterator_free(iter->iter0);
233
+ ref_iterator_free(iter->iter1);
234
}
235
236
static struct ref_iterator_vtable merge_ref_iterator_vtable = {
237
.advance = merge_ref_iterator_advance,
238
.peel = merge_ref_iterator_peel,
251
- .abort = merge_ref_iterator_abort,
239
+ .release = merge_ref_iterator_release,
240
};
241
242
struct ref_iterator *merge_ref_iterator_begin(
298
* them.
299
*/
300
if (is_empty_ref_iterator(front)) {
313
- ref_iterator_abort(front);
301
+ ref_iterator_free(front);
302
return back;
303
} else if (is_empty_ref_iterator(back)) {
316
- ref_iterator_abort(back);
304
+ ref_iterator_free(back);
305
return front;
306
}
307
338
339
while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) {
340
int cmp = compare_prefix(iter->iter0->refname, iter->prefix);
353
-
341
if (cmp < 0)
342
continue;
356
-
357
- if (cmp > 0) {
358
- /*
359
- * As the source iterator is ordered, we
360
- * can stop the iteration as soon as we see a
361
- * refname that comes after the prefix:
362
- */
363
- ok = ref_iterator_abort(iter->iter0);
364
- break;
365
- }
343
+ /*
344
+ * As the source iterator is ordered, we
345
+ * can stop the iteration as soon as we see a
346
+ * refname that comes after the prefix:
347
+ */
348
+ if (cmp > 0)
349
+ return ITER_DONE;
350
351
if (iter->trim) {
352
/*
370
return ITER_OK;
371
}
372
389
- iter->iter0 = NULL;
390
- if (ref_iterator_abort(ref_iterator) != ITER_DONE)
391
- return ITER_ERROR;
373
return ok;
374
}
375
382
return ref_iterator_peel(iter->iter0, peeled);
383
}
384
404
-static int prefix_ref_iterator_abort(struct ref_iterator *ref_iterator)
385
+static void prefix_ref_iterator_release(struct ref_iterator *ref_iterator)
386
{
387
struct prefix_ref_iterator *iter =
388
(struct prefix_ref_iterator *)ref_iterator;
408
- int ok = ITER_DONE;
409
-
410
- if (iter->iter0)
411
- ok = ref_iterator_abort(iter->iter0);
389
+ ref_iterator_free(iter->iter0);
390
free(iter->prefix);
413
- base_ref_iterator_free(ref_iterator);
414
- return ok;
391
}
392
393
static struct ref_iterator_vtable prefix_ref_iterator_vtable = {
394
.advance = prefix_ref_iterator_advance,
395
.peel = prefix_ref_iterator_peel,
420
- .abort = prefix_ref_iterator_abort,
396
+ .release = prefix_ref_iterator_release,
397
};
398
399
struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
429
current_ref_iter = iter;
430
while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
431
retval = fn(iter->refname, iter->referent, iter->oid, iter->flags, cb_data);
456
- if (retval) {
457
- /*
458
- * If ref_iterator_abort() returns ITER_ERROR,
459
- * we ignore that error in deference to the
460
- * callback function's return value.
461
- */
462
- ref_iterator_abort(iter);
432
+ if (retval)
433
goto out;
464
- }
434
}
435
436
out:
437
current_ref_iter = old_ref_iter;
438
if (ok == ITER_ERROR)
470
- return -1;
439
+ retval = -1;
440
+ ref_iterator_free(iter);
441
return retval;
442
}