xdiff: handle allocation failure in patience diff

Other users of libxdiff such as libgit2 need to be able to handle allocation failures. As NULL is a valid return value the function signature is changed to be able report allocation failures. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Phillip Wood committed Feb 16, 2022 at 10:15 UTC 61f883965f79308b849a55936bee69a33c476c5c
1 file changed +12 -5
xdiff/xpatience.c
+12 -5
@@ -198,7 +198,7 @@ static int binary_search(struct entry **sequence, int longest,
198 * item per sequence length: the sequence with the smallest last
199 * element (in terms of line2).
200 */
201 -static struct entry *find_longest_common_sequence(struct hashmap *map)
201 +static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
202 {
203 struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
204 int longest = 0, i;
@@ -211,6 +211,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
211 */
212 int anchor_i = -1;
213
214 + if (!sequence)
215 + return -1;
216 +
217 for (entry = map->first; entry; entry = entry->next) {
218 if (!entry->line2 || entry->line2 == NON_UNIQUE)
219 continue;
@@ -230,8 +233,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
233
234 /* No common unique lines were found */
235 if (!longest) {
236 + *res = NULL;
237 xdl_free(sequence);
234 - return NULL;
238 + return 0;
239 }
240
241 /* Iterate starting at the last element, adjusting the "next" members */
@@ -241,8 +245,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
245 entry->previous->next = entry;
246 entry = entry->previous;
247 }
248 + *res = entry;
249 xdl_free(sequence);
245 - return entry;
250 + return 0;
251 }
252
253 static int match(struct hashmap *map, int line1, int line2)
@@ -358,14 +363,16 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
363 return 0;
364 }
365
361 - first = find_longest_common_sequence(&map);
366 + result = find_longest_common_sequence(&map, &first);
367 + if (result)
368 + goto out;
369 if (first)
370 result = walk_common_sequence(&map, first,
371 line1, count1, line2, count2);
372 else
373 result = fall_back_to_classic_diff(&map,
374 line1, count1, line2, count2);
368 -
375 + out:
376 xdl_free(map.entries);
377 return result;
378 }