rebase -x: sanity check command

If the user gives an empty argument to --exec then git creates a todo list that it cannot parse. The rebase starts to run before erroring out with error: missing arguments for exec error: invalid line 2: exec You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'. Or you can abort the rebase with 'git rebase --abort'. Instead check for empty commands before starting the rebase. Also check that the command does not contain any newlines as the todo-list format is unable to cope with multiline commands. Note that this changes the behavior, before this change one could do git rebase --exec='echo one exec echo two' and it would insert two exec lines in the todo list, now it will error out. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Phillip Wood committed Jan 29, 2019 at 18:43 UTC c762aada1ab3a2c428c462e0e6964d9f37107da7
2 files changed +36
builtin/rebase.c
+17
@@ -793,6 +793,19 @@ static void set_reflog_action(struct rebase_options *options)
793 strbuf_release(&buf);
794 }
795
796 +static int check_exec_cmd(const char *cmd)
797 +{
798 + if (strchr(cmd, '\n'))
799 + return error(_("exec commands cannot contain newlines"));
800 +
801 + /* Does the command consist purely of whitespace? */
802 + if (!cmd[strspn(cmd, " \t\r\f\v")])
803 + return error(_("empty exec command"));
804 +
805 + return 0;
806 +}
807 +
808 +
809 int cmd_rebase(int argc, const char **argv, const char *prefix)
810 {
811 struct rebase_options options = {
@@ -1130,6 +1143,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1143 }
1144 }
1145
1146 + for (i = 0; i < exec.nr; i++)
1147 + if (check_exec_cmd(exec.items[i].string))
1148 + exit(1);
1149 +
1150 if (!(options.flags & REBASE_NO_QUIET))
1151 argv_array_push(&options.git_am_opts, "-q");
1152
t/t3404-rebase-interactive.sh
+19
@@ -147,6 +147,25 @@ test_expect_success 'rebase -i with the exec command checks tree cleanness' '
147 git rebase --continue
148 '
149
150 +test_expect_success 'rebase -x with empty command fails' '
151 + test_when_finished "git rebase --abort ||:" &&
152 + test_must_fail git rebase -x "" @ 2>actual &&
153 + test_write_lines "error: empty exec command" >expected &&
154 + test_i18ncmp expected actual &&
155 + test_must_fail git rebase -x " " @ 2>actual &&
156 + test_i18ncmp expected actual
157 +'
158 +
159 +LF='
160 +'
161 +test_expect_success 'rebase -x with newline in command fails' '
162 + test_when_finished "git rebase --abort ||:" &&
163 + test_must_fail git rebase -x "a${LF}b" @ 2>actual &&
164 + test_write_lines "error: exec commands cannot contain newlines" \
165 + >expected &&
166 + test_i18ncmp expected actual
167 +'
168 +
169 test_expect_success 'rebase -i with exec of inexistent command' '
170 git checkout master &&
171 test_when_finished "git rebase --abort" &&