-
Notifications
You must be signed in to change notification settings - Fork 611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix null dereferences on unset format strings #1136
Conversation
Why not doing it in one line with: diff --git a/src/argv.c b/src/argv.c
index de0bcf4..27e6d31 100644
--- a/src/argv.c
+++ b/src/argv.c
@@ -472,7 +472,7 @@ argv_format(struct argv_env *argv_env, const char ***dst_argv, const char *src_a
}
}
- return src_argv[argc] == NULL;
+ return src_argv[argc] == NULL && *dst_argv;
} |
31e6496
to
0b3fa68
Compare
Ok the second version does that, which makes things simpler. |
I think we shouldn't fail on an empty arg. That should do the trick: diff --git a/src/argv.c b/src/argv.c
index 27e6d31..2fc0d0a 100644
--- a/src/argv.c
+++ b/src/argv.c
@@ -361,7 +361,7 @@ format_append_argv(struct format_context *format, const char ***dst_argv, const
int argc;
if (!src_argv)
- return true;
+ return argv_append(dst_argv, "");
for (argc = 0; src_argv[argc]; argc++)
if (!format_append_arg(format, dst_argv, src_argv[argc])) |
0b3fa68
to
fa49e75
Compare
Wow how could I miss that! Updated. |
I suggest adding the following test case (sorry not the best way to provide this diff).
diff --git a/test/regressions/github-1136-test b/test/regressions/github-1136-test
new file mode 100755
index 0000000..25f1271
--- /dev/null
+++ b/test/regressions/github-1136-test
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+. libtest.sh
+. libgit.sh
+
+LINES=10
+
+in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz"
+
+test_case bang-cmdlineargs-doesnt-crash \
+ --args='status' \
+ --script='
+ :!%(cmdlineargs)
+ ' <<EOF
+On branch master
+Changes to be committed:
+ (no files)
+Changes not staged for commit:
+ (no files)
+Untracked files:
+ (no files)
+
+[status] Nothing to update 100%
+EOF
+
+test_case echo-cmdlineargs-doesnt-crash \
+ --args='status' \
+ --script='
+ :echo %(cmdlineargs)
+ ' <<EOF
+On branch master
+Changes to be committed:
+ (no files)
+Changes not staged for commit:
+ (no files)
+Untracked files:
+ (no files)
+
+[status] Nothing to update 100%
+EOF
+
+run_test_cases |
If you prefer I can do it after merging. Just wanted to see if this could be tested. |
fa49e75
to
119638f
Compare
Tig knows three kinds of state variables that encode different information: 1. the state of the view (ARGV_ENV_INFO), like %(commit) 2. the state of the worktree (REPO_INFO), like %(repo:head) 3. the arguments given on the commandline, like %(fileargs) The values exposed by the first two kinds are never null, but most of the third kind default to null. Prior to this commit when trying to format a null value, argv_format() reported success but left the output string as null. Fix this by writing the empty string in format_append_argv(), because current callers (echo) don't really care about the difference between empty and null. Reproduce the null dereferences with :!%(fileargs) :echo %(fileargs) Surprisingly to me, this did not break this example: bind generic aaa !sh -c 'printf "%s\n" "$@" | wc -l' -- line1 %(fileargs) line2 # still prints 2 because of the early return in argv_appendn(). In future we should also fix format_append_arg(), which currently fails on :echo "%(fileargs)" because format_expand_arg() does not receive variables like %(fileargs).
119638f
to
a0506d9
Compare
Thanks |
Our argv_format() reports success but leaves the output at null
when the input is "%(cmdlineargs)" and the corresponding option
("opt_cmdline_args") is null.
Other callers already check if the output is null, do the same.
Fixes two null dereferences in prompt.c:
I don't know if there is a reproducer for the change in argv.c but
this seems better.