Skip to content

Commit 5f11a7a

Browse files
committed
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
2 parents 35936f8 + 82fbf26 commit 5f11a7a

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

diff.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "submodule.h"
1717
#include "ll-merge.h"
1818
#include "string-list.h"
19+
#include "argv-array.h"
1920

2021
#ifdef NO_FAST_WORKING_DIRECTORY
2122
#define FAST_WORKING_DIRECTORY 0
@@ -2894,9 +2895,8 @@ static void run_external_diff(const char *pgm,
28942895
int complete_rewrite,
28952896
struct diff_options *o)
28962897
{
2897-
const char *spawn_arg[10];
2898+
struct argv_array argv = ARGV_ARRAY_INIT;
28982899
int retval;
2899-
const char **arg = &spawn_arg[0];
29002900
struct diff_queue_struct *q = &diff_queued_diff;
29012901
const char *env[3] = { NULL };
29022902
char env_counter[50];
@@ -2907,23 +2907,22 @@ static void run_external_diff(const char *pgm,
29072907
const char *othername = (other ? other : name);
29082908
temp_one = prepare_temp_file(name, one);
29092909
temp_two = prepare_temp_file(othername, two);
2910-
*arg++ = pgm;
2911-
*arg++ = name;
2912-
*arg++ = temp_one->name;
2913-
*arg++ = temp_one->hex;
2914-
*arg++ = temp_one->mode;
2915-
*arg++ = temp_two->name;
2916-
*arg++ = temp_two->hex;
2917-
*arg++ = temp_two->mode;
2910+
argv_array_push(&argv, pgm);
2911+
argv_array_push(&argv, name);
2912+
argv_array_push(&argv, temp_one->name);
2913+
argv_array_push(&argv, temp_one->hex);
2914+
argv_array_push(&argv, temp_one->mode);
2915+
argv_array_push(&argv, temp_two->name);
2916+
argv_array_push(&argv, temp_two->hex);
2917+
argv_array_push(&argv, temp_two->mode);
29182918
if (other) {
2919-
*arg++ = other;
2920-
*arg++ = xfrm_msg;
2919+
argv_array_push(&argv, other);
2920+
argv_array_push(&argv, xfrm_msg);
29212921
}
29222922
} else {
2923-
*arg++ = pgm;
2924-
*arg++ = name;
2923+
argv_array_push(&argv, pgm);
2924+
argv_array_push(&argv, name);
29252925
}
2926-
*arg = NULL;
29272926
fflush(NULL);
29282927

29292928
env[0] = env_counter;
@@ -2932,8 +2931,9 @@ static void run_external_diff(const char *pgm,
29322931
env[1] = env_total;
29332932
snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr);
29342933

2935-
retval = run_command_v_opt_cd_env(spawn_arg, RUN_USING_SHELL, NULL, env);
2934+
retval = run_command_v_opt_cd_env(argv.argv, RUN_USING_SHELL, NULL, env);
29362935
remove_tempfile();
2936+
argv_array_clear(&argv);
29372937
if (retval) {
29382938
fprintf(stderr, "external diff died, stopping at %s.\n", name);
29392939
exit(1);

0 commit comments

Comments
 (0)