summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2014-04-28 15:47:35 -0700
committerJunio C Hamano <gitster@pobox.com>2014-04-28 15:47:35 -0700
commit5f11a7aad0704918fde4855500caba6a3f130648 (patch)
tree56072ffdd9cd2f85a7e46b4177ef675cf3782606
parent35936f8fc38a214cc7d2595070641d39a541dfb1 (diff)
parent82fbf269b9994d172719b2d456db5ef8453b323d (diff)
downloadgit-5f11a7aad0704918fde4855500caba6a3f130648.tar.gz
Merge branch 'jk/external-diff-use-argv-array' (early part)
Crash fix for codepath that miscounted the necessary size for an array when spawning an external diff program. * 'jk/external-diff-use-argv-array' (early part): run_external_diff: use an argv_array for the command line
-rw-r--r--diff.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/diff.c b/diff.c
index 54d5308268..f72769a1c4 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
@@ -2894,9 +2895,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];
@@ -2907,23 +2907,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;
@@ -2932,8 +2931,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);