Skip to content

Commit

Permalink
add -p: fix checking of user input
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
phillipwood authored and gitster committed Aug 17, 2020
1 parent 2ebe436 commit ce91028
Showing 1 changed file with 38 additions and 16 deletions.
54 changes: 38 additions & 16 deletions add-patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1452,30 +1474,30 @@ static int patch_update_file(struct add_p_state *s,
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"));
} else if (s->answer.buf[0] == 'g') {
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;
}
Expand Down Expand Up @@ -1512,7 +1534,7 @@ static int patch_update_file(struct add_p_state *s,
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;
}
Expand Down Expand Up @@ -1557,15 +1579,15 @@ static int patch_update_file(struct add_p_state *s,
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))
color_fprintf_ln(stdout, s->s.header_color,
_("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;
Expand Down

0 comments on commit ce91028

Please sign in to comment.