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
maint
Junio C Hamano 2014-04-28 15:47:35 -07:00
commit 5f11a7aad0
1 changed files with 16 additions and 16 deletions

32
diff.c
View File

@ -16,6 +16,7 @@
#include "submodule.h" #include "submodule.h"
#include "ll-merge.h" #include "ll-merge.h"
#include "string-list.h" #include "string-list.h"
#include "argv-array.h"


#ifdef NO_FAST_WORKING_DIRECTORY #ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0 #define FAST_WORKING_DIRECTORY 0
@ -2894,9 +2895,8 @@ static void run_external_diff(const char *pgm,
int complete_rewrite, int complete_rewrite,
struct diff_options *o) struct diff_options *o)
{ {
const char *spawn_arg[10]; struct argv_array argv = ARGV_ARRAY_INIT;
int retval; int retval;
const char **arg = &spawn_arg[0];
struct diff_queue_struct *q = &diff_queued_diff; struct diff_queue_struct *q = &diff_queued_diff;
const char *env[3] = { NULL }; const char *env[3] = { NULL };
char env_counter[50]; char env_counter[50];
@ -2907,23 +2907,22 @@ static void run_external_diff(const char *pgm,
const char *othername = (other ? other : name); const char *othername = (other ? other : name);
temp_one = prepare_temp_file(name, one); temp_one = prepare_temp_file(name, one);
temp_two = prepare_temp_file(othername, two); temp_two = prepare_temp_file(othername, two);
*arg++ = pgm; argv_array_push(&argv, pgm);
*arg++ = name; argv_array_push(&argv, name);
*arg++ = temp_one->name; argv_array_push(&argv, temp_one->name);
*arg++ = temp_one->hex; argv_array_push(&argv, temp_one->hex);
*arg++ = temp_one->mode; argv_array_push(&argv, temp_one->mode);
*arg++ = temp_two->name; argv_array_push(&argv, temp_two->name);
*arg++ = temp_two->hex; argv_array_push(&argv, temp_two->hex);
*arg++ = temp_two->mode; argv_array_push(&argv, temp_two->mode);
if (other) { if (other) {
*arg++ = other; argv_array_push(&argv, other);
*arg++ = xfrm_msg; argv_array_push(&argv, xfrm_msg);
} }
} else { } else {
*arg++ = pgm; argv_array_push(&argv, pgm);
*arg++ = name; argv_array_push(&argv, name);
} }
*arg = NULL;
fflush(NULL); fflush(NULL);


env[0] = env_counter; env[0] = env_counter;
@ -2932,8 +2931,9 @@ static void run_external_diff(const char *pgm,
env[1] = env_total; env[1] = env_total;
snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr); 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(); remove_tempfile();
argv_array_clear(&argv);
if (retval) { if (retval) {
fprintf(stderr, "external diff died, stopping at %s.\n", name); fprintf(stderr, "external diff died, stopping at %s.\n", name);
exit(1); exit(1);