Imported Upstream version 2.3.1
[platform/upstream/git.git] / builtin / apply.c
index 0aad912..c484b53 100644 (file)
@@ -657,11 +657,6 @@ static size_t diff_timestamp_len(const char *line, size_t len)
        return line + len - end;
 }
 
-static char *null_strdup(const char *s)
-{
-       return s ? xstrdup(s) : NULL;
-}
-
 static char *find_name_common(const char *line, const char *def,
                              int p_value, const char *end, int terminate)
 {
@@ -684,10 +679,10 @@ static char *find_name_common(const char *line, const char *def,
                        start = line;
        }
        if (!start)
-               return squash_slash(null_strdup(def));
+               return squash_slash(xstrdup_or_null(def));
        len = line - start;
        if (!len)
-               return squash_slash(null_strdup(def));
+               return squash_slash(xstrdup_or_null(def));
 
        /*
         * Generally we prefer the shorter name, especially
@@ -909,7 +904,7 @@ static void parse_traditional_patch(const char *first, const char *second, struc
                        patch->old_name = name;
                } else {
                        patch->old_name = name;
-                       patch->new_name = null_strdup(name);
+                       patch->new_name = xstrdup_or_null(name);
                }
        }
        if (!name)
@@ -998,7 +993,7 @@ static int gitdiff_delete(const char *line, struct patch *patch)
 {
        patch->is_delete = 1;
        free(patch->old_name);
-       patch->old_name = null_strdup(patch->def_name);
+       patch->old_name = xstrdup_or_null(patch->def_name);
        return gitdiff_oldmode(line, patch);
 }
 
@@ -1006,7 +1001,7 @@ static int gitdiff_newfile(const char *line, struct patch *patch)
 {
        patch->is_new = 1;
        free(patch->new_name);
-       patch->new_name = null_strdup(patch->def_name);
+       patch->new_name = xstrdup_or_null(patch->def_name);
        return gitdiff_newmode(line, patch);
 }
 
@@ -2235,6 +2230,12 @@ static void update_pre_post_images(struct image *preimage,
                ctx++;
        }
 
+       if (postlen
+           ? postlen < new - postimage->buf
+           : postimage->len < new - postimage->buf)
+               die("BUG: caller miscounted postlen: asked %d, orig = %d, used = %d",
+                   (int)postlen, (int) postimage->len, (int)(new - postimage->buf));
+
        /* Fix the length of the whole thing */
        postimage->len = new - postimage->buf;
        postimage->nr -= reduced;
@@ -2390,10 +2391,27 @@ static int match_fragment(struct image *img,
 
        /*
         * The hunk does not apply byte-by-byte, but the hash says
-        * it might with whitespace fuzz. We haven't been asked to
+        * it might with whitespace fuzz. We weren't asked to
         * ignore whitespace, we were asked to correct whitespace
         * errors, so let's try matching after whitespace correction.
         *
+        * While checking the preimage against the target, whitespace
+        * errors in both fixed, we count how large the corresponding
+        * postimage needs to be.  The postimage prepared by
+        * apply_one_fragment() has whitespace errors fixed on added
+        * lines already, but the common lines were propagated as-is,
+        * which may become longer when their whitespace errors are
+        * fixed.
+        */
+
+       /* First count added lines in postimage */
+       postlen = 0;
+       for (i = 0; i < postimage->nr; i++) {
+               if (!(postimage->line[i].flag & LINE_COMMON))
+                       postlen += postimage->line[i].len;
+       }
+
+       /*
         * The preimage may extend beyond the end of the file,
         * but in this loop we will only handle the part of the
         * preimage that falls within the file.
@@ -2401,7 +2419,6 @@ static int match_fragment(struct image *img,
        strbuf_init(&fixed, preimage->len + 1);
        orig = preimage->buf;
        target = img->buf + try;
-       postlen = 0;
        for (i = 0; i < preimage_limit; i++) {
                size_t oldlen = preimage->line[i].len;
                size_t tgtlen = img->line[try_lno + i].len;
@@ -2429,7 +2446,10 @@ static int match_fragment(struct image *img,
                match = (tgtfix.len == fixed.len - fixstart &&
                         !memcmp(tgtfix.buf, fixed.buf + fixstart,
                                             fixed.len - fixstart));
-               postlen += tgtfix.len;
+
+               /* Add the length if this is common with the postimage */
+               if (preimage->line[i].flag & LINE_COMMON)
+                       postlen += tgtfix.len;
 
                strbuf_release(&tgtfix);
                if (!match)