From: Junio C Hamano Date: Wed, 19 Oct 2011 17:48:29 +0000 (-0700) Subject: Merge branch 'jm/maint-apply-detects-corrupt-patch-header' X-Git-Tag: v1.7.8-rc0~41 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/c31b87d111f6df359255979ea94e8648a51c3647?hp=-c Merge branch 'jm/maint-apply-detects-corrupt-patch-header' * jm/maint-apply-detects-corrupt-patch-header: fix "git apply --index ..." not to deref NULL --- c31b87d111f6df359255979ea94e8648a51c3647 diff --combined builtin/apply.c index 694f55dc5a,97ade776f3..84a8a0b521 --- a/builtin/apply.c +++ b/builtin/apply.c @@@ -43,7 -43,6 +43,7 @@@ static int apply = 1 static int apply_in_reverse; static int apply_with_reject; static int apply_verbosely; +static int allow_overlap; static int no_add; static const char *fake_ancestor; static int line_termination = '\n'; @@@ -205,7 -204,6 +205,7 @@@ struct line unsigned hash : 24; unsigned flag : 8; #define LINE_COMMON 1 +#define LINE_PATCHED 2 }; /* @@@ -1407,6 -1405,9 +1407,9 @@@ static int find_header(char *line, unsi "%d leading pathname components (line %d)" , p_value, linenr); patch->old_name = patch->new_name = patch->def_name; } + if (!patch->is_delete && !patch->new_name) + die("git diff header lacks filename information " + "(line %d)", linenr); patch->is_toplevel_relative = 1; *hdrsize = git_hdr_len; return offset; @@@ -1634,7 -1635,7 +1637,7 @@@ static inline int metadata_changes(stru static char *inflate_it(const void *data, unsigned long size, unsigned long inflated_size) { - z_stream stream; + git_zstream stream; void *out; int st; @@@ -2087,8 -2088,7 +2090,8 @@@ static int match_fragment(struct image /* Quick hash check */ for (i = 0; i < preimage_limit; i++) - if (preimage->line[i].hash != img->line[try_lno + i].hash) + if ((img->line[try_lno + i].flag & LINE_PATCHED) || + (preimage->line[i].hash != img->line[try_lno + i].hash)) return 0; if (preimage_limit == preimage->nr) { @@@ -2431,15 -2431,11 +2434,15 @@@ static void update_image(struct image * memcpy(img->line + applied_pos, postimage->line, postimage->nr * sizeof(*img->line)); + if (!allow_overlap) + for (i = 0; i < postimage->nr; i++) + img->line[applied_pos + i].flag |= LINE_PATCHED; img->nr = nr; } static int apply_one_fragment(struct image *img, struct fragment *frag, - int inaccurate_eof, unsigned ws_rule) + int inaccurate_eof, unsigned ws_rule, + int nth_fragment) { int match_beginning, match_end; const char *patch = frag->patch; @@@ -2447,8 -2443,6 +2450,8 @@@ char *old, *oldlines; struct strbuf newlines; int new_blank_lines_at_end = 0; + int found_new_blank_lines_at_end = 0; + int hunk_linenr = frag->linenr; unsigned long leading, trailing; int pos, applied_pos; struct image preimage; @@@ -2542,18 -2536,14 +2545,18 @@@ error("invalid start of line: '%c'", first); return -1; } - if (added_blank_line) + if (added_blank_line) { + if (!new_blank_lines_at_end) + found_new_blank_lines_at_end = hunk_linenr; new_blank_lines_at_end++; + } else if (is_blank_context) ; else new_blank_lines_at_end = 0; patch += len; size -= len; + hunk_linenr++; } if (inaccurate_eof && old > oldlines && old[-1] == '\n' && @@@ -2635,8 -2625,7 +2638,8 @@@ preimage.nr + applied_pos >= img->nr && (ws_rule & WS_BLANK_AT_EOF) && ws_error_action != nowarn_ws_error) { - record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr); + record_ws_error(WS_BLANK_AT_EOF, "+", 1, + found_new_blank_lines_at_end); if (ws_error_action == correct_ws_error) { while (new_blank_lines_at_end--) remove_last_line(&postimage); @@@ -2652,15 -2641,6 +2655,15 @@@ apply = 0; } + if (apply_verbosely && applied_pos != pos) { + int offset = applied_pos - pos; + if (apply_in_reverse) + offset = 0 - offset; + fprintf(stderr, + "Hunk #%d succeeded at %d (offset %d lines).\n", + nth_fragment, applied_pos + 1, offset); + } + /* * Warn if it was necessary to reduce the number * of context lines. @@@ -2808,14 -2788,12 +2811,14 @@@ static int apply_fragments(struct imag const char *name = patch->old_name ? patch->old_name : patch->new_name; unsigned ws_rule = patch->ws_rule; unsigned inaccurate_eof = patch->inaccurate_eof; + int nth = 0; if (patch->is_binary) return apply_binary(img, patch); while (frag) { - if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule)) { + nth++; + if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule, nth)) { error("patch failed: %s:%ld", name, frag->oldpos); if (!apply_with_reject) return -1; @@@ -3838,6 -3816,7 +3841,6 @@@ int cmd_apply(int argc, const char **ar int i; int errs = 0; int is_not_gitdir = !startup_info->have_repository; - int binary; int force_apply = 0; const char *whitespace_option = NULL; @@@ -3856,8 -3835,12 +3859,8 @@@ "ignore additions made by the patch"), OPT_BOOLEAN(0, "stat", &diffstat, "instead of applying the patch, output diffstat for the input"), - { OPTION_BOOLEAN, 0, "allow-binary-replacement", &binary, - NULL, "old option, now no-op", - PARSE_OPT_HIDDEN | PARSE_OPT_NOARG }, - { OPTION_BOOLEAN, 0, "binary", &binary, - NULL, "old option, now no-op", - PARSE_OPT_HIDDEN | PARSE_OPT_NOARG }, + OPT_NOOP_NOARG(0, "allow-binary-replacement"), + OPT_NOOP_NOARG(0, "binary"), OPT_BOOLEAN(0, "numstat", &numstat, "shows number of added and deleted lines in decimal notation"), OPT_BOOLEAN(0, "summary", &summary, @@@ -3892,8 -3875,6 +3895,8 @@@ "don't expect at least one line of context"), OPT_BOOLEAN(0, "reject", &apply_with_reject, "leave the rejected hunks in corresponding *.rej files"), + OPT_BOOLEAN(0, "allow-overlap", &allow_overlap, + "allow overlapping hunks"), OPT__VERBOSE(&apply_verbosely, "be verbose"), OPT_BIT(0, "inaccurate-eof", &options, "tolerate incorrectly detected missing new-line at the end of file",