Skip to content

Commit

Permalink
Merge branch 'pw/rebase-i-validate-labels-early' into jch
Browse files Browse the repository at this point in the history
An invalid label or ref in the "rebase -i" todo file used to
trigger an runtime error. SUch an error is now diagnosed while the
todo file is parsed.

* pw/rebase-i-validate-labels-early:
  rebase -i: check labels and refs when parsing todo list
  • Loading branch information
gitster committed Feb 27, 2023
2 parents dadc8e6 + 16b3880 commit 605915f
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
39 changes: 38 additions & 1 deletion sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2487,6 +2487,34 @@ static int is_command(enum todo_command command, const char **bol)
(*bol = p));
}

static int check_label_or_ref_arg(enum todo_command command, const char *arg)
{
switch (command) {
case TODO_LABEL:
/*
* '#' is not a valid label as the merge command uses it to
* separate merge parents from the commit subject.
*/
if (!strcmp(arg, "#") ||
check_refname_format(arg, REFNAME_ALLOW_ONELEVEL))
return error(_("'%s' is not a valid label"), arg);
break;

case TODO_UPDATE_REF:
if (check_refname_format(arg, REFNAME_ALLOW_ONELEVEL))
return error(_("'%s' is not a valid refname"), arg);
if (check_refname_format(arg, 0))
return error(_("update-ref requires a fully qualified "
"refname e.g. refs/heads/%s"), arg);
break;

default:
BUG("unexpected todo_command");
}

return 0;
}

static int parse_insn_line(struct repository *r, struct todo_item *item,
const char *buf, const char *bol, char *eol)
{
Expand Down Expand Up @@ -2535,10 +2563,19 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,

if (item->command == TODO_EXEC || item->command == TODO_LABEL ||
item->command == TODO_RESET || item->command == TODO_UPDATE_REF) {
int ret = 0;

item->commit = NULL;
item->arg_offset = bol - buf;
item->arg_len = (int)(eol - bol);
return 0;
if (item->command == TODO_LABEL ||
item->command == TODO_UPDATE_REF) {
saved = *eol;
*eol = '\0';
ret = check_label_or_ref_arg(item->command, bol);
*eol = saved;
}
return ret;
}

if (item->command == TODO_FIXUP) {
Expand Down
23 changes: 23 additions & 0 deletions t/t3404-rebase-interactive.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,7 @@ test_expect_success '--update-refs: --edit-todo with no update-ref lines' '
'

test_expect_success '--update-refs: check failed ref update' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout -B update-refs-error no-conflict-branch &&
git branch -f base HEAD~4 &&
git branch -f first HEAD~3 &&
Expand Down Expand Up @@ -2123,6 +2124,28 @@ test_expect_success '--update-refs: check failed ref update' '
test_cmp expect err.trimmed
'

test_expect_success 'bad labels and refs rejected when parsing todo list' '
test_when_finished "test_might_fail git rebase --abort" &&
cat >todo <<-\EOF &&
exec >execed
label #
label :invalid
update-ref :bad
update-ref topic
EOF
rm -f execed &&
(
set_replace_editor todo &&
test_must_fail git rebase -i HEAD 2>err
) &&
grep "'\''#'\'' is not a valid label" err &&
grep "'\'':invalid'\'' is not a valid label" err &&
grep "'\'':bad'\'' is not a valid refname" err &&
grep "update-ref requires a fully qualified refname e.g. refs/heads/topic" \
err &&
test_path_is_missing execed
'

# This must be the last test in this file
test_expect_success '$EDITOR and friends are unchanged' '
test_editor_unchanged
Expand Down

0 comments on commit 605915f

Please sign in to comment.