git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Cc: Max L <infthi.inbox@gmail.com>
Subject: [PATCH 1/6] run_external_diff: use an argv_array for the command line
Date: Sat, 19 Apr 2014 15:17:06 -0400	[thread overview]
Message-ID: <20140419191706.GA8981@sigill.intra.peff.net> (raw)
In-Reply-To: <20140419191128.GA9266@sigill.intra.peff.net>

We currently generate the command-line for the external
command using a fixed-length array of size 10. But if there
is a rename, we actually need 11 elements (10 items, plus a
NULL), and end up writing a random NULL onto the stack.

Rather than bump the limit, let's just an argv_array, which
makes this sort of error impossible.

Noticed-by: Max L <infthi.inbox@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
---
This was actually noticed by a GitHub user, who proposed bumping
the array size to 11:

  https://github.com/git/git/pull/92

Even though this fix is a bigger change, I'd rather do it this way, as
it is more obviously correct to a reader (and it solves the problem
forever). I pulled the name/email from that commit, but please let me
know if you'd prefer to be credited differently.

 diff.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/diff.c b/diff.c
index 539997f..b154284 100644
--- a/diff.c
+++ b/diff.c
@@ -16,6 +16,7 @@
 #include "submodule.h"
 #include "ll-merge.h"
 #include "string-list.h"
+#include "argv-array.h"
 
 #ifdef NO_FAST_WORKING_DIRECTORY
 #define FAST_WORKING_DIRECTORY 0
@@ -2902,9 +2903,8 @@ static void run_external_diff(const char *pgm,
 			      int complete_rewrite,
 			      struct diff_options *o)
 {
-	const char *spawn_arg[10];
+	struct argv_array argv = ARGV_ARRAY_INIT;
 	int retval;
-	const char **arg = &spawn_arg[0];
 	struct diff_queue_struct *q = &diff_queued_diff;
 	const char *env[3] = { NULL };
 	char env_counter[50];
@@ -2915,23 +2915,22 @@ static void run_external_diff(const char *pgm,
 		const char *othername = (other ? other : name);
 		temp_one = prepare_temp_file(name, one);
 		temp_two = prepare_temp_file(othername, two);
-		*arg++ = pgm;
-		*arg++ = name;
-		*arg++ = temp_one->name;
-		*arg++ = temp_one->hex;
-		*arg++ = temp_one->mode;
-		*arg++ = temp_two->name;
-		*arg++ = temp_two->hex;
-		*arg++ = temp_two->mode;
+		argv_array_push(&argv, pgm);
+		argv_array_push(&argv, name);
+		argv_array_push(&argv, temp_one->name);
+		argv_array_push(&argv, temp_one->hex);
+		argv_array_push(&argv, temp_one->mode);
+		argv_array_push(&argv, temp_two->name);
+		argv_array_push(&argv, temp_two->hex);
+		argv_array_push(&argv, temp_two->mode);
 		if (other) {
-			*arg++ = other;
-			*arg++ = xfrm_msg;
+			argv_array_push(&argv, other);
+			argv_array_push(&argv, xfrm_msg);
 		}
 	} else {
-		*arg++ = pgm;
-		*arg++ = name;
+		argv_array_push(&argv, pgm);
+		argv_array_push(&argv, name);
 	}
-	*arg = NULL;
 	fflush(NULL);
 
 	env[0] = env_counter;
@@ -2940,8 +2939,9 @@ static void run_external_diff(const char *pgm,
 	env[1] = env_total;
 	snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr);
 
-	retval = run_command_v_opt_cd_env(spawn_arg, RUN_USING_SHELL, NULL, env);
+	retval = run_command_v_opt_cd_env(argv.argv, RUN_USING_SHELL, NULL, env);
 	remove_tempfile();
+	argv_array_clear(&argv);
 	if (retval) {
 		fprintf(stderr, "external diff died, stopping at %s.\n", name);
 		exit(1);
-- 
1.9.1.656.ge8a0637

  reply	other threads:[~2014-04-19 19:17 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-19 19:11 [PATCH 0/6] run_external_diff cleanups Jeff King
2014-04-19 19:17 ` Jeff King [this message]
2014-04-19 22:09   ` [PATCH 1/6] run_external_diff: use an argv_array for the command line Max L
2014-04-20  1:35     ` Jeff King
2014-04-20  1:20   ` Eric Sunshine
2014-04-19 19:17 ` [PATCH 2/6] run_external_diff: use an argv_array for the environment Jeff King
2014-04-19 19:19 ` [PATCH 3/6] run_external_diff: clean up error handling Jeff King
2014-04-19 19:19 ` [PATCH 4/6] run_external_diff: drop fflush(NULL) Jeff King
2014-04-19 19:20 ` [PATCH 5/6] run_external_diff: hoist common bits out of conditional Jeff King
2014-04-19 19:22 ` [PATCH 6/6] run_external_diff: refactor cmdline setup logic Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140419191706.GA8981@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=infthi.inbox@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).