git_mkstemp(): be careful not to overflow the path buffer.
[gitweb.git] / builtin-apply.c
index ac7c82437eced245c20089ab56df925c4f5084f0..0a0b4a9e3f6550b6a4729e94242811dcb6e8d09a 100644 (file)
@@ -55,7 +55,7 @@ static enum whitespace_eol {
 } new_whitespace = warn_on_whitespace;
 static int whitespace_error;
 static int squelch_whitespace_errors = 5;
-static int applied_after_stripping;
+static int applied_after_fixing_ws;
 static const char *patch_input_file;
 
 static void parse_whitespace_option(const char *option)
@@ -1003,12 +1003,16 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s
                        trailing++;
                        break;
                case '-':
+                       if (apply_in_reverse &&
+                                       new_whitespace != nowarn_whitespace)
+                               check_whitespace(line, len);
                        deleted++;
                        oldlines--;
                        trailing = 0;
                        break;
                case '+':
-                       if (new_whitespace != nowarn_whitespace)
+                       if (!apply_in_reverse &&
+                                       new_whitespace != nowarn_whitespace)
                                check_whitespace(line, len);
                        added++;
                        newlines--;
@@ -1657,7 +1661,7 @@ static int apply_line(char *output, const char *patch, int plen)
        if (add_nl_to_tail)
                output[plen++] = '\n';
        if (fixed)
-               applied_after_stripping++;
+               applied_after_fixing_ws++;
        return output + plen - buf;
 }
 
@@ -1671,7 +1675,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
        char *new = xmalloc(size);
        const char *oldlines, *newlines;
        int oldsize = 0, newsize = 0;
-       int trailing_added_lines = 0;
+       int new_blank_lines_at_end = 0;
        unsigned long leading, trailing;
        int pos, lines;
 
@@ -1679,6 +1683,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                char first;
                int len = linelen(patch, size);
                int plen;
+               int added_blank_line = 0;
 
                if (!len)
                        break;
@@ -1700,16 +1705,6 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                        else if (first == '+')
                                first = '-';
                }
-               /*
-                * Count lines added at the end of the file.
-                * This is not enough to get things right in case of
-                * patches generated with --unified=0, but it's a
-                * useful upper bound.
-               */
-               if (first == '+')
-                       trailing_added_lines++;
-               else
-                       trailing_added_lines = 0;
 
                switch (first) {
                case '\n':
@@ -1728,9 +1723,14 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                                break;
                /* Fall-through for ' ' */
                case '+':
-                       if (first != '+' || !no_add)
-                               newsize += apply_line(new + newsize, patch,
-                                                     plen);
+                       if (first != '+' || !no_add) {
+                               int added = apply_line(new + newsize, patch,
+                                                      plen);
+                               newsize += added;
+                               if (first == '+' &&
+                                   added == 1 && new[newsize-1] == '\n')
+                                       added_blank_line = 1;
+                       }
                        break;
                case '@': case '\\':
                        /* Ignore it, we already handled it */
@@ -1740,6 +1740,10 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                                error("invalid start of line: '%c'", first);
                        return -1;
                }
+               if (added_blank_line)
+                       new_blank_lines_at_end++;
+               else
+                       new_blank_lines_at_end = 0;
                patch += len;
                size -= len;
        }
@@ -1750,24 +1754,6 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                newsize--;
        }
 
-       if (new_whitespace == strip_whitespace) {
-               /* Any added empty lines is already cleaned-up here
-                * becuase of 'strip_whitespace' flag, so just count '\n'
-               */
-               int empty = 0;
-               while (   empty < trailing_added_lines
-                      && newsize - empty > 0
-                      && new[newsize - empty - 1] == '\n')
-                       empty++;
-
-               if (empty < trailing_added_lines)
-                       empty--;
-
-               /* these are the empty lines added at
-                * the end of the file, modulo u0 patches.
-                */
-               trailing_added_lines = empty;
-       }
        oldlines = old;
        newlines = new;
        leading = frag->leading;
@@ -1805,7 +1791,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
 
                        if (new_whitespace == strip_whitespace &&
                            (desc->size - oldsize - offset == 0)) /* end of file? */
-                               newsize -= trailing_added_lines;
+                               newsize -= new_blank_lines_at_end;
 
                        diff = newsize - oldsize;
                        size = desc->size + diff;
@@ -2902,18 +2888,17 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
                                squelched == 1 ? "" : "s");
                }
                if (new_whitespace == error_on_whitespace)
-                       die("%d line%s add%s trailing whitespaces.",
+                       die("%d line%s add%s whitespace errors.",
                            whitespace_error,
                            whitespace_error == 1 ? "" : "s",
                            whitespace_error == 1 ? "s" : "");
-               if (applied_after_stripping)
+               if (applied_after_fixing_ws)
                        fprintf(stderr, "warning: %d line%s applied after"
-                               " stripping trailing whitespaces.\n",
-                               applied_after_stripping,
-                               applied_after_stripping == 1 ? "" : "s");
+                               " fixing whitespace errors.\n",
+                               applied_after_fixing_ws,
+                               applied_after_fixing_ws == 1 ? "" : "s");
                else if (whitespace_error)
-                       fprintf(stderr, "warning: %d line%s add%s trailing"
-                               " whitespaces.\n",
+                       fprintf(stderr, "warning: %d line%s add%s whitespace errors.\n",
                                whitespace_error,
                                whitespace_error == 1 ? "" : "s",
                                whitespace_error == 1 ? "s" : "");