From 2ebe436c5531319e820571d04024f7bcae383450 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Mon, 17 Aug 2020 13:23:07 +0000 Subject: add -p: use ALLOC_GROW_BY instead of ALLOW_GROW This simplifies the code slightly, especially the third case where hunk_nr was incremented a few lines before ALLOC_GROW(). Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- add-patch.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'add-patch.c') diff --git a/add-patch.c b/add-patch.c index f899389e2c..a15fa407be 100644 --- a/add-patch.c +++ b/add-patch.c @@ -457,11 +457,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) eol = pend; if (starts_with(p, "diff ")) { - s->file_diff_nr++; - ALLOC_GROW(s->file_diff, s->file_diff_nr, + ALLOC_GROW_BY(s->file_diff, s->file_diff_nr, 1, file_diff_alloc); file_diff = s->file_diff + s->file_diff_nr - 1; - memset(file_diff, 0, sizeof(*file_diff)); hunk = &file_diff->head; hunk->start = p - plain->buf; if (colored_p) @@ -483,11 +481,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) */ hunk->splittable_into++; - file_diff->hunk_nr++; - ALLOC_GROW(file_diff->hunk, file_diff->hunk_nr, + ALLOC_GROW_BY(file_diff->hunk, file_diff->hunk_nr, 1, file_diff->hunk_alloc); hunk = file_diff->hunk + file_diff->hunk_nr - 1; - memset(hunk, 0, sizeof(*hunk)); hunk->start = p - plain->buf; if (colored) @@ -511,7 +507,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) if (file_diff->mode_change) BUG("double mode change?\n\n%.*s", (int)(eol - plain->buf), plain->buf); - if (file_diff->hunk_nr++) + if (file_diff->hunk_nr) BUG("mode change in the middle?\n\n%.*s", (int)(eol - plain->buf), plain->buf); @@ -520,9 +516,8 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) * is _part of_ the header "hunk". */ file_diff->mode_change = 1; - ALLOC_GROW(file_diff->hunk, file_diff->hunk_nr, + ALLOC_GROW_BY(file_diff->hunk, file_diff->hunk_nr, 1, file_diff->hunk_alloc); - memset(file_diff->hunk, 0, sizeof(struct hunk)); file_diff->hunk->start = p - plain->buf; if (colored_p) file_diff->hunk->colored_start = -- cgit v1.2.3 From ce910287e727e5b534d806df725c68a8dfc4790a Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Mon, 17 Aug 2020 13:23:08 +0000 Subject: add -p: fix checking of user input When a file has been deleted the C version of add -p allows the user to edit a hunk even though 'e' is not in the list of allowed responses. (I think 'e' is disallowed because if the file is edited it is no longer a deletion and we're not set up to rewrite the diff header). The invalid response was allowed because the test that determines whether to display 'e' was not duplicated correctly in the code that processes the user's choice. Fix this by using flags that are set when constructing the prompt and checked when processing the user's choice rather than repeating the check itself. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- add-patch.c | 54 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 16 deletions(-) (limited to 'add-patch.c') diff --git a/add-patch.c b/add-patch.c index a15fa407be..907c05b3c1 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1352,6 +1352,15 @@ static int patch_update_file(struct add_p_state *s, struct child_process cp = CHILD_PROCESS_INIT; int colored = !!s->colored.len, quit = 0; enum prompt_mode_type prompt_mode_type; + enum { + ALLOW_GOTO_PREVIOUS_HUNK = 1 << 0, + ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1, + ALLOW_GOTO_NEXT_HUNK = 1 << 2, + ALLOW_GOTO_NEXT_UNDECIDED_HUNK = 1 << 3, + ALLOW_SEARCH_AND_GOTO = 1 << 4, + ALLOW_SPLIT = 1 << 5, + ALLOW_EDIT = 1 << 6 + } permitted = 0; if (!file_diff->hunk_nr) return 0; @@ -1388,22 +1397,35 @@ static int patch_update_file(struct add_p_state *s, fputs(s->buf.buf, stdout); strbuf_reset(&s->buf); - if (undecided_previous >= 0) + if (undecided_previous >= 0) { + permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK; strbuf_addstr(&s->buf, ",k"); - if (hunk_index) + } + if (hunk_index) { + permitted |= ALLOW_GOTO_PREVIOUS_HUNK; strbuf_addstr(&s->buf, ",K"); - if (undecided_next >= 0) + } + if (undecided_next >= 0) { + permitted |= ALLOW_GOTO_NEXT_UNDECIDED_HUNK; strbuf_addstr(&s->buf, ",j"); - if (hunk_index + 1 < file_diff->hunk_nr) + } + if (hunk_index + 1 < file_diff->hunk_nr) { + permitted |= ALLOW_GOTO_NEXT_HUNK; strbuf_addstr(&s->buf, ",J"); - if (file_diff->hunk_nr > 1) + } + if (file_diff->hunk_nr > 1) { + permitted |= ALLOW_SEARCH_AND_GOTO; strbuf_addstr(&s->buf, ",g,/"); - if (hunk->splittable_into > 1) + } + if (hunk->splittable_into > 1) { + permitted |= ALLOW_SPLIT; strbuf_addstr(&s->buf, ",s"); + } if (hunk_index + 1 > file_diff->mode_change && - !file_diff->deleted) + !file_diff->deleted) { + permitted |= ALLOW_EDIT; strbuf_addstr(&s->buf, ",e"); - + } if (file_diff->deleted) prompt_mode_type = PROMPT_DELETION; else if (file_diff->added) @@ -1452,22 +1474,22 @@ soft_increment: break; } } else if (s->answer.buf[0] == 'K') { - if (hunk_index) + if (permitted & ALLOW_GOTO_PREVIOUS_HUNK) hunk_index--; else err(s, _("No previous hunk")); } else if (s->answer.buf[0] == 'J') { - if (hunk_index + 1 < file_diff->hunk_nr) + if (permitted & ALLOW_GOTO_NEXT_HUNK) hunk_index++; else err(s, _("No next hunk")); } else if (s->answer.buf[0] == 'k') { - if (undecided_previous >= 0) + if (permitted & ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK) hunk_index = undecided_previous; else err(s, _("No previous hunk")); } else if (s->answer.buf[0] == 'j') { - if (undecided_next >= 0) + if (permitted & ALLOW_GOTO_NEXT_UNDECIDED_HUNK) hunk_index = undecided_next; else err(s, _("No next hunk")); @@ -1475,7 +1497,7 @@ soft_increment: char *pend; unsigned long response; - if (file_diff->hunk_nr < 2) { + if (!(permitted & ALLOW_SEARCH_AND_GOTO)) { err(s, _("No other hunks to goto")); continue; } @@ -1512,7 +1534,7 @@ soft_increment: regex_t regex; int ret; - if (file_diff->hunk_nr < 2) { + if (!(permitted & ALLOW_SEARCH_AND_GOTO)) { err(s, _("No other hunks to search")); continue; } @@ -1557,7 +1579,7 @@ soft_increment: hunk_index = i; } else if (s->answer.buf[0] == 's') { size_t splittable_into = hunk->splittable_into; - if (splittable_into < 2) + if (!(permitted & ALLOW_SPLIT)) err(s, _("Sorry, cannot split this hunk")); else if (!split_hunk(s, file_diff, hunk - file_diff->hunk)) @@ -1565,7 +1587,7 @@ soft_increment: _("Split into %d hunks."), (int)splittable_into); } else if (s->answer.buf[0] == 'e') { - if (hunk_index + 1 == file_diff->mode_change) + if (!(permitted & ALLOW_EDIT)) err(s, _("Sorry, cannot edit this hunk")); else if (edit_hunk_loop(s, file_diff, hunk) >= 0) { hunk->use = USE_HUNK; -- cgit v1.2.3