]> git.ipfire.org Git - thirdparty/git.git/commitdiff
xdiff: handle allocation failure in patience diff
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Wed, 16 Feb 2022 10:15:07 +0000 (10:15 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 16 Feb 2022 18:58:13 +0000 (10:58 -0800)
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>
xdiff/xpatience.c

index e8de8d150cede1d1c5ad1627e9cc5bc7a490725d..1a21c6a74b368cb094e20c708a43071c72558d7e 100644 (file)
@@ -198,7 +198,7 @@ static int binary_search(struct entry **sequence, int longest,
  * item per sequence length: the sequence with the smallest last
  * element (in terms of line2).
  */
-static struct entry *find_longest_common_sequence(struct hashmap *map)
+static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
 {
        struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
        int longest = 0, i;
@@ -211,6 +211,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
         */
        int anchor_i = -1;
 
+       if (!sequence)
+               return -1;
+
        for (entry = map->first; entry; entry = entry->next) {
                if (!entry->line2 || entry->line2 == NON_UNIQUE)
                        continue;
@@ -230,8 +233,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
 
        /* No common unique lines were found */
        if (!longest) {
+               *res = NULL;
                xdl_free(sequence);
-               return NULL;
+               return 0;
        }
 
        /* Iterate starting at the last element, adjusting the "next" members */
@@ -241,8 +245,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
                entry->previous->next = entry;
                entry = entry->previous;
        }
+       *res = entry;
        xdl_free(sequence);
-       return entry;
+       return 0;
 }
 
 static int match(struct hashmap *map, int line1, int line2)
@@ -358,14 +363,16 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
                return 0;
        }
 
-       first = find_longest_common_sequence(&map);
+       result = find_longest_common_sequence(&map, &first);
+       if (result)
+               goto out;
        if (first)
                result = walk_common_sequence(&map, first,
                        line1, count1, line2, count2);
        else
                result = fall_back_to_classic_diff(&map,
                        line1, count1, line2, count2);
-
+ out:
        xdl_free(map.entries);
        return result;
 }