Skip to content

Commit a1be47e

Browse files
peffgitster
authored andcommitted
hash-object: fix buffer reuse with --path in a subdirectory
The hash-object command uses prefix_filename() without duplicating its return value. Since that function returns a static buffer, the value is overwritten by subsequent calls. This can cause incorrect results when we use --path along with hashing a file by its relative path, both of which need to call prefix_filename(). We overwrite the filename computed for --path, effectively ignoring it. We can fix this by calling xstrdup on the return value. Note that we don't bother freeing the "vpath" instance, as it remains valid until the program exit. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent c0f9c70 commit a1be47e

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

builtin/hash-object.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
115115

116116
prefix_length = prefix ? strlen(prefix) : 0;
117117
if (vpath && prefix)
118-
vpath = prefix_filename(prefix, prefix_length, vpath);
118+
vpath = xstrdup(prefix_filename(prefix, prefix_length, vpath));
119119

120120
git_config(git_default_config, NULL);
121121

@@ -144,11 +144,14 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
144144

145145
for (i = 0 ; i < argc; i++) {
146146
const char *arg = argv[i];
147+
char *to_free = NULL;
147148

148149
if (0 <= prefix_length)
149-
arg = prefix_filename(prefix, prefix_length, arg);
150+
arg = to_free =
151+
xstrdup(prefix_filename(prefix, prefix_length, arg));
150152
hash_object(arg, type, no_filters ? NULL : vpath ? vpath : arg,
151153
flags, literally);
154+
free(to_free);
152155
}
153156

154157
if (stdin_paths)

t/t1007-hash-object.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,16 @@ test_expect_success 'gitattributes also work in a subdirectory' '
134134
)
135135
'
136136

137+
test_expect_success '--path works in a subdirectory' '
138+
(
139+
cd subdir &&
140+
path1_sha=$(git hash-object --path=../file1 ../file0) &&
141+
path0_sha=$(git hash-object --path=../file0 ../file1) &&
142+
test "$file0_sha" = "$path0_sha" &&
143+
test "$file1_sha" = "$path1_sha"
144+
)
145+
'
146+
137147
test_expect_success 'check that --no-filters option works' '
138148
nofilters_file1=$(git hash-object --no-filters file1) &&
139149
test "$file0_sha" = "$nofilters_file1" &&

0 commit comments

Comments
 (0)