Skip to content

Commit fcd12db

Browse files
peffgitster
authored andcommitted
prefer git_pathdup to git_path in some possibly-dangerous cases
Because git_path uses a static buffer that is shared with calls to git_path, mkpath, etc, it can be dangerous to assign the result to a variable or pass it to a non-trivial function. The value may change unexpectedly due to other calls. None of the cases changed here has a known bug, but they're worth converting away from git_path because: 1. It's easy to use git_pathdup in these cases. 2. They use constructs (like assignment) that make it hard to tell whether they're safe or not. The extra malloc overhead should be trivial, as an allocation should be an order of magnitude cheaper than a system call (which we are clearly about to make, since we are constructing a filename). The real cost is that we must remember to free the result. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 77b9b1d commit fcd12db

File tree

6 files changed

+21
-11
lines changed

6 files changed

+21
-11
lines changed

builtin/fsck.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,14 @@ static void check_unreachable_object(struct object *obj)
243243
printf("dangling %s %s\n", typename(obj->type),
244244
sha1_to_hex(obj->sha1));
245245
if (write_lost_and_found) {
246-
const char *filename = git_path("lost-found/%s/%s",
246+
char *filename = git_pathdup("lost-found/%s/%s",
247247
obj->type == OBJ_COMMIT ? "commit" : "other",
248248
sha1_to_hex(obj->sha1));
249249
FILE *f;
250250

251251
if (safe_create_leading_directories_const(filename)) {
252252
error("Could not create lost-found");
253+
free(filename);
253254
return;
254255
}
255256
if (!(f = fopen(filename, "w")))
@@ -262,6 +263,7 @@ static void check_unreachable_object(struct object *obj)
262263
if (fclose(f))
263264
die_errno("Could not finish '%s'",
264265
filename);
266+
free(filename);
265267
}
266268
return;
267269
}

fast-import.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,15 @@ static void dump_marks_helper(FILE *, uintmax_t, struct mark_set *);
407407

408408
static void write_crash_report(const char *err)
409409
{
410-
const char *loc = git_path("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid());
410+
char *loc = git_pathdup("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid());
411411
FILE *rpt = fopen(loc, "w");
412412
struct branch *b;
413413
unsigned long lu;
414414
struct recent_command *rc;
415415

416416
if (!rpt) {
417417
error("can't write crash report %s: %s", loc, strerror(errno));
418+
free(loc);
418419
return;
419420
}
420421

@@ -488,6 +489,7 @@ static void write_crash_report(const char *err)
488489
fputs("-------------------\n", rpt);
489490
fputs("END OF CRASH REPORT\n", rpt);
490491
fclose(rpt);
492+
free(loc);
491493
}
492494

493495
static void end_packfile(void);

http-backend.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static void send_strbuf(const char *type, struct strbuf *buf)
164164

165165
static void send_local_file(const char *the_type, const char *name)
166166
{
167-
const char *p = git_path("%s", name);
167+
char *p = git_pathdup("%s", name);
168168
size_t buf_alloc = 8192;
169169
char *buf = xmalloc(buf_alloc);
170170
int fd;
@@ -191,6 +191,7 @@ static void send_local_file(const char *the_type, const char *name)
191191
}
192192
close(fd);
193193
free(buf);
194+
free(p);
194195
}
195196

196197
static void get_text_file(char *name)

notes-merge.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ static void write_buf_to_worktree(const unsigned char *obj,
295295
const char *buf, unsigned long size)
296296
{
297297
int fd;
298-
const char *path = git_path(NOTES_MERGE_WORKTREE "/%s", sha1_to_hex(obj));
298+
char *path = git_pathdup(NOTES_MERGE_WORKTREE "/%s", sha1_to_hex(obj));
299299
if (safe_create_leading_directories_const(path))
300300
die_errno("unable to create directory for '%s'", path);
301301
if (file_exists(path))
@@ -320,6 +320,7 @@ static void write_buf_to_worktree(const unsigned char *obj,
320320
}
321321

322322
close(fd);
323+
free(path);
323324
}
324325

325326
static void write_note_to_worktree(const unsigned char *obj,

refs.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,12 +1288,12 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
12881288
*/
12891289
static struct packed_ref_cache *get_packed_ref_cache(struct ref_cache *refs)
12901290
{
1291-
const char *packed_refs_file;
1291+
char *packed_refs_file;
12921292

12931293
if (*refs->name)
1294-
packed_refs_file = git_path_submodule(refs->name, "packed-refs");
1294+
packed_refs_file = git_pathdup_submodule(refs->name, "packed-refs");
12951295
else
1296-
packed_refs_file = git_path("packed-refs");
1296+
packed_refs_file = git_pathdup("packed-refs");
12971297

12981298
if (refs->packed &&
12991299
!stat_validity_check(&refs->packed->validity, packed_refs_file))
@@ -1312,6 +1312,7 @@ static struct packed_ref_cache *get_packed_ref_cache(struct ref_cache *refs)
13121312
fclose(f);
13131313
}
13141314
}
1315+
free(packed_refs_file);
13151316
return refs->packed;
13161317
}
13171318

@@ -1481,14 +1482,15 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
14811482
{
14821483
int fd, len;
14831484
char buffer[128], *p;
1484-
const char *path;
1485+
char *path;
14851486

14861487
if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN)
14871488
return -1;
14881489
path = *refs->name
1489-
? git_path_submodule(refs->name, "%s", refname)
1490-
: git_path("%s", refname);
1490+
? git_pathdup_submodule(refs->name, "%s", refname)
1491+
: git_pathdup("%s", refname);
14911492
fd = open(path, O_RDONLY);
1493+
free(path);
14921494
if (fd < 0)
14931495
return resolve_gitlink_packed_ref(refs, refname, sha1);
14941496

unpack-trees.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1029,10 +1029,12 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
10291029
if (!core_apply_sparse_checkout || !o->update)
10301030
o->skip_sparse_checkout = 1;
10311031
if (!o->skip_sparse_checkout) {
1032-
if (add_excludes_from_file_to_list(git_path("info/sparse-checkout"), "", 0, &el, 0) < 0)
1032+
char *sparse = git_pathdup("info/sparse-checkout");
1033+
if (add_excludes_from_file_to_list(sparse, "", 0, &el, 0) < 0)
10331034
o->skip_sparse_checkout = 1;
10341035
else
10351036
o->el = &el;
1037+
free(sparse);
10361038
}
10371039

10381040
memset(&o->result, 0, sizeof(o->result));

0 commit comments

Comments
 (0)