Skip to content

Commit ce91028

Browse files
phillipwoodgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2ebe436 commit ce91028

File tree

1 file changed

+38
-16
lines changed

1 file changed

+38
-16
lines changed

add-patch.c

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,15 @@ static int patch_update_file(struct add_p_state *s,
13521352
struct child_process cp = CHILD_PROCESS_INIT;
13531353
int colored = !!s->colored.len, quit = 0;
13541354
enum prompt_mode_type prompt_mode_type;
1355+
enum {
1356+
ALLOW_GOTO_PREVIOUS_HUNK = 1 << 0,
1357+
ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1,
1358+
ALLOW_GOTO_NEXT_HUNK = 1 << 2,
1359+
ALLOW_GOTO_NEXT_UNDECIDED_HUNK = 1 << 3,
1360+
ALLOW_SEARCH_AND_GOTO = 1 << 4,
1361+
ALLOW_SPLIT = 1 << 5,
1362+
ALLOW_EDIT = 1 << 6
1363+
} permitted = 0;
13551364

13561365
if (!file_diff->hunk_nr)
13571366
return 0;
@@ -1388,22 +1397,35 @@ static int patch_update_file(struct add_p_state *s,
13881397
fputs(s->buf.buf, stdout);
13891398

13901399
strbuf_reset(&s->buf);
1391-
if (undecided_previous >= 0)
1400+
if (undecided_previous >= 0) {
1401+
permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK;
13921402
strbuf_addstr(&s->buf, ",k");
1393-
if (hunk_index)
1403+
}
1404+
if (hunk_index) {
1405+
permitted |= ALLOW_GOTO_PREVIOUS_HUNK;
13941406
strbuf_addstr(&s->buf, ",K");
1395-
if (undecided_next >= 0)
1407+
}
1408+
if (undecided_next >= 0) {
1409+
permitted |= ALLOW_GOTO_NEXT_UNDECIDED_HUNK;
13961410
strbuf_addstr(&s->buf, ",j");
1397-
if (hunk_index + 1 < file_diff->hunk_nr)
1411+
}
1412+
if (hunk_index + 1 < file_diff->hunk_nr) {
1413+
permitted |= ALLOW_GOTO_NEXT_HUNK;
13981414
strbuf_addstr(&s->buf, ",J");
1399-
if (file_diff->hunk_nr > 1)
1415+
}
1416+
if (file_diff->hunk_nr > 1) {
1417+
permitted |= ALLOW_SEARCH_AND_GOTO;
14001418
strbuf_addstr(&s->buf, ",g,/");
1401-
if (hunk->splittable_into > 1)
1419+
}
1420+
if (hunk->splittable_into > 1) {
1421+
permitted |= ALLOW_SPLIT;
14021422
strbuf_addstr(&s->buf, ",s");
1423+
}
14031424
if (hunk_index + 1 > file_diff->mode_change &&
1404-
!file_diff->deleted)
1425+
!file_diff->deleted) {
1426+
permitted |= ALLOW_EDIT;
14051427
strbuf_addstr(&s->buf, ",e");
1406-
1428+
}
14071429
if (file_diff->deleted)
14081430
prompt_mode_type = PROMPT_DELETION;
14091431
else if (file_diff->added)
@@ -1452,30 +1474,30 @@ static int patch_update_file(struct add_p_state *s,
14521474
break;
14531475
}
14541476
} else if (s->answer.buf[0] == 'K') {
1455-
if (hunk_index)
1477+
if (permitted & ALLOW_GOTO_PREVIOUS_HUNK)
14561478
hunk_index--;
14571479
else
14581480
err(s, _("No previous hunk"));
14591481
} else if (s->answer.buf[0] == 'J') {
1460-
if (hunk_index + 1 < file_diff->hunk_nr)
1482+
if (permitted & ALLOW_GOTO_NEXT_HUNK)
14611483
hunk_index++;
14621484
else
14631485
err(s, _("No next hunk"));
14641486
} else if (s->answer.buf[0] == 'k') {
1465-
if (undecided_previous >= 0)
1487+
if (permitted & ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK)
14661488
hunk_index = undecided_previous;
14671489
else
14681490
err(s, _("No previous hunk"));
14691491
} else if (s->answer.buf[0] == 'j') {
1470-
if (undecided_next >= 0)
1492+
if (permitted & ALLOW_GOTO_NEXT_UNDECIDED_HUNK)
14711493
hunk_index = undecided_next;
14721494
else
14731495
err(s, _("No next hunk"));
14741496
} else if (s->answer.buf[0] == 'g') {
14751497
char *pend;
14761498
unsigned long response;
14771499

1478-
if (file_diff->hunk_nr < 2) {
1500+
if (!(permitted & ALLOW_SEARCH_AND_GOTO)) {
14791501
err(s, _("No other hunks to goto"));
14801502
continue;
14811503
}
@@ -1512,7 +1534,7 @@ static int patch_update_file(struct add_p_state *s,
15121534
regex_t regex;
15131535
int ret;
15141536

1515-
if (file_diff->hunk_nr < 2) {
1537+
if (!(permitted & ALLOW_SEARCH_AND_GOTO)) {
15161538
err(s, _("No other hunks to search"));
15171539
continue;
15181540
}
@@ -1557,15 +1579,15 @@ static int patch_update_file(struct add_p_state *s,
15571579
hunk_index = i;
15581580
} else if (s->answer.buf[0] == 's') {
15591581
size_t splittable_into = hunk->splittable_into;
1560-
if (splittable_into < 2)
1582+
if (!(permitted & ALLOW_SPLIT))
15611583
err(s, _("Sorry, cannot split this hunk"));
15621584
else if (!split_hunk(s, file_diff,
15631585
hunk - file_diff->hunk))
15641586
color_fprintf_ln(stdout, s->s.header_color,
15651587
_("Split into %d hunks."),
15661588
(int)splittable_into);
15671589
} else if (s->answer.buf[0] == 'e') {
1568-
if (hunk_index + 1 == file_diff->mode_change)
1590+
if (!(permitted & ALLOW_EDIT))
15691591
err(s, _("Sorry, cannot edit this hunk"));
15701592
else if (edit_hunk_loop(s, file_diff, hunk) >= 0) {
15711593
hunk->use = USE_HUNK;

0 commit comments

Comments
 (0)