path.c: make get_pathname() call sites return const char *
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 30 Nov 2014 08:24:27 +0000 (15:24 +0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 1 Dec 2014 19:00:10 +0000 (11:00 -0800)
Before the previous commit, get_pathname returns an array of PATH_MAX
length. Even if git_path() and similar functions does not use the
whole array, git_path() caller can, in theory.

After the commit, get_pathname() may return a buffer that has just
enough room for the returned string and git_path() caller should never
write beyond that.

Make git_path(), mkpath() and git_path_submodule() return a const
buffer to make sure callers do not write in it at all.

This could have been part of the previous commit, but the "const"
conversion is too much distraction from the core changes in path.c.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
15 files changed:
builtin/checkout.c
builtin/clone.c
builtin/fetch.c
builtin/fsck.c
builtin/receive-pack.c
builtin/remote.c
builtin/repack.c
cache.h
fast-import.c
notes-merge.c
path.c
refs.c
run-command.c
run-command.h
sha1_file.c
index 5410dacea0699f70cd942837394c06eac99873d1..c600ec14c71dc100669f57fbc989480e9a799e73 100644 (file)
@@ -589,7 +589,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
                        if (opts->new_branch_log && !log_all_ref_updates) {
                                int temp;
                                char log_file[PATH_MAX];
-                               char *ref_name = mkpath("refs/heads/%s", opts->new_orphan_branch);
+                               const char *ref_name = mkpath("refs/heads/%s", opts->new_orphan_branch);
 
                                temp = log_all_ref_updates;
                                log_all_ref_updates = 1;
index d5e7532105aa66c5b7e04e170489cf905928b5bb..a9af3f2bdec263742e52e30875502b5f6893f9ef 100644 (file)
@@ -290,16 +290,17 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst,
        struct strbuf line = STRBUF_INIT;
 
        while (strbuf_getline(&line, in, '\n') != EOF) {
-               char *abs_path, abs_buf[PATH_MAX];
+               char *abs_path;
                if (!line.len || line.buf[0] == '#')
                        continue;
                if (is_absolute_path(line.buf)) {
                        add_to_alternates_file(line.buf);
                        continue;
                }
-               abs_path = mkpath("%s/objects/%s", src_repo, line.buf);
-               normalize_path_copy(abs_buf, abs_path);
-               add_to_alternates_file(abs_buf);
+               abs_path = mkpathdup("%s/objects/%s", src_repo, line.buf);
+               normalize_path_copy(abs_path, abs_path);
+               add_to_alternates_file(abs_path);
+               free(abs_path);
        }
        strbuf_release(&line);
        fclose(in);
index 7b84d35d83498bc51b06915818f63d1f365eec91..cb54936df02516d91a4902a91e45692fc8c23d92 100644 (file)
@@ -587,7 +587,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
        struct strbuf note = STRBUF_INIT;
        const char *what, *kind;
        struct ref *rm;
-       char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
+       char *url;
+       const char *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
        int want_status;
 
        fp = fopen(filename, "a");
@@ -821,7 +822,7 @@ static void check_not_current_branch(struct ref *ref_map)
 
 static int truncate_fetch_head(void)
 {
-       char *filename = git_path("FETCH_HEAD");
+       const char *filename = git_path("FETCH_HEAD");
        FILE *fp = fopen(filename, "w");
 
        if (!fp)
index a27515aeaa2debabdb14a03d271fe423d13b19d2..b92aefff422083e43afc624e90d982eb2ed9a876 100644 (file)
@@ -225,12 +225,12 @@ static void check_unreachable_object(struct object *obj)
                        printf("dangling %s %s\n", typename(obj->type),
                               sha1_to_hex(obj->sha1));
                if (write_lost_and_found) {
-                       char *filename = git_path("lost-found/%s/%s",
+                       const char *filename = git_path("lost-found/%s/%s",
                                obj->type == OBJ_COMMIT ? "commit" : "other",
                                sha1_to_hex(obj->sha1));
                        FILE *f;
 
-                       if (safe_create_leading_directories(filename)) {
+                       if (safe_create_leading_directories_const(filename)) {
                                error("Could not create lost-found");
                                return;
                        }
index 32fc540ef3ddfc4d1bb33ae75a0e07b555bdc441..3b8f420d04c9693419ccbdf3bc30b73cd27836e6 100644 (file)
@@ -869,7 +869,7 @@ static void run_update_post_hook(struct command *commands)
        int argc;
        const char **argv;
        struct child_process proc = CHILD_PROCESS_INIT;
-       char *hook;
+       const char *hook;
 
        hook = find_hook("post-update");
        for (argc = 0, cmd = commands; cmd; cmd = cmd->next) {
index 7f28f92a378a4e89d8c938beac23cbe053f1ce33..4ce396fdffcd3f0b7742e5e1b9119691cd3fb5f6 100644 (file)
@@ -582,7 +582,7 @@ static int migrate_file(struct remote *remote)
 {
        struct strbuf buf = STRBUF_INIT;
        int i;
-       char *path = NULL;
+       const char *path = NULL;
 
        strbuf_addf(&buf, "remote.%s.url", remote->name);
        for (i = 0; i < remote->url_nr; i++)
index 28456206c5d135adba191c865e49aa75dc201691..9c04e1d8ec1c2e4ffe03c6ab1c0e7d8215f9788f 100644 (file)
@@ -284,7 +284,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        failed = 0;
        for_each_string_list_item(item, &names) {
                for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
-                       char *fname, *fname_old;
+                       const char *fname_old;
+                       char *fname;
                        fname = mkpathdup("%s/pack-%s%s", packdir,
                                                item->string, exts[ext].name);
                        if (!file_exists(fname)) {
@@ -312,7 +313,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        if (failed) {
                struct string_list rollback_failure = STRING_LIST_INIT_DUP;
                for_each_string_list_item(item, &rollback) {
-                       char *fname, *fname_old;
+                       const char *fname_old;
+                       char *fname;
                        fname = mkpathdup("%s/%s", packdir, item->string);
                        fname_old = mkpath("%s/old-%s", packdir, item->string);
                        if (rename(fname_old, fname))
@@ -365,7 +367,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        /* Remove the "old-" files */
        for_each_string_list_item(item, &names) {
                for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
-                       char *fname;
+                       const char *fname;
                        fname = mkpath("%s/old-%s%s",
                                        packdir,
                                        item->string,
diff --git a/cache.h b/cache.h
index 99ed096aed03b865dd6e263474e6e6a265681b91..dbee0a30b9379ebc4e3f9a3578fc9d330de983bf 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -687,9 +687,9 @@ extern char *mkpathdup(const char *fmt, ...)
        __attribute__((format (printf, 1, 2)));
 
 /* Return a statically allocated filename matching the sha1 signature */
-extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
-extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
-extern char *git_path_submodule(const char *path, const char *fmt, ...)
+extern const char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+extern const char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+extern const char *git_path_submodule(const char *path, const char *fmt, ...)
        __attribute__((format (printf, 2, 3)));
 
 /*
index d0bd285a16d0161b50d0b43e0315f8fa003e0e32..30181304d66100a8d0bc09579d6f8e9bca749a95 100644 (file)
@@ -405,7 +405,7 @@ static void dump_marks_helper(FILE *, uintmax_t, struct mark_set *);
 
 static void write_crash_report(const char *err)
 {
-       char *loc = git_path("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid());
+       const char *loc = git_path("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid());
        FILE *rpt = fopen(loc, "w");
        struct branch *b;
        unsigned long lu;
index 7eb9d7a0103ad8447e4fde50976a5669a75d8cdd..f39e906a34695d4f21b7c8d5f99ebdecf3ae861e 100644 (file)
@@ -280,7 +280,7 @@ static void check_notes_merge_worktree(struct notes_merge_options *o)
                                    "(%s exists).", git_path("NOTES_MERGE_*"));
                }
 
-               if (safe_create_leading_directories(git_path(
+               if (safe_create_leading_directories_const(git_path(
                                NOTES_MERGE_WORKTREE "/.test")))
                        die_errno("unable to create directory %s",
                                  git_path(NOTES_MERGE_WORKTREE));
@@ -295,8 +295,8 @@ static void write_buf_to_worktree(const unsigned char *obj,
                                  const char *buf, unsigned long size)
 {
        int fd;
-       char *path = git_path(NOTES_MERGE_WORKTREE "/%s", sha1_to_hex(obj));
-       if (safe_create_leading_directories(path))
+       const char *path = git_path(NOTES_MERGE_WORKTREE "/%s", sha1_to_hex(obj));
+       if (safe_create_leading_directories_const(path))
                die_errno("unable to create directory for '%s'", path);
        if (file_exists(path))
                die("found existing file at '%s'", path);
diff --git a/path.c b/path.c
index 015c0e4b390ddffad44767cf05a62eb1030505a7..a7ceea26fbdee5b8f94c5023d1a8de5f1f4a9fa8 100644 (file)
--- a/path.c
+++ b/path.c
@@ -106,7 +106,7 @@ char *mkpathdup(const char *fmt, ...)
        return strbuf_detach(&sb, NULL);
 }
 
-char *mkpath(const char *fmt, ...)
+const char *mkpath(const char *fmt, ...)
 {
        va_list args;
        struct strbuf *pathname = get_pathname();
@@ -116,7 +116,7 @@ char *mkpath(const char *fmt, ...)
        return cleanup_path(pathname->buf);
 }
 
-char *git_path(const char *fmt, ...)
+const char *git_path(const char *fmt, ...)
 {
        struct strbuf *pathname = get_pathname();
        va_list args;
@@ -154,7 +154,7 @@ void home_config_paths(char **global, char **xdg, char *file)
        free(to_free);
 }
 
-char *git_path_submodule(const char *path, const char *fmt, ...)
+const char *git_path_submodule(const char *path, const char *fmt, ...)
 {
        struct strbuf *buf = get_pathname();
        const char *git_dir;
diff --git a/refs.c b/refs.c
index 5ff457ebfce7aba9cd470f3e2e1f3f5dbe9d9741..23617e0c568aab244d17b1744c180ea9eb7c50e6 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1351,7 +1351,7 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
 {
        int fd, len;
        char buffer[128], *p;
-       char *path;
+       const char *path;
 
        if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN)
                return -1;
@@ -2229,7 +2229,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
                                            const struct string_list *skip,
                                            int flags, int *type_p)
 {
-       char *ref_file;
+       const char *ref_file;
        const char *orig_refname = refname;
        struct ref_lock *lock;
        int last_errno = 0;
@@ -2303,7 +2303,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
                lock->force_write = 1;
 
  retry:
-       switch (safe_create_leading_directories(ref_file)) {
+       switch (safe_create_leading_directories_const(ref_file)) {
        case SCLD_OK:
                break; /* success */
        case SCLD_VANISHED:
@@ -2743,7 +2743,7 @@ static int rename_tmp_log(const char *newrefname)
        int attempts_remaining = 4;
 
  retry:
-       switch (safe_create_leading_directories(git_path("logs/%s", newrefname))) {
+       switch (safe_create_leading_directories_const(git_path("logs/%s", newrefname))) {
        case SCLD_OK:
                break; /* success */
        case SCLD_VANISHED:
index a47699966c59f708683e439bcd3296d5fce8acf5..c4a62aa0e8fb8eba8d6972461eed07097a52a976 100644 (file)
@@ -794,9 +794,9 @@ int finish_async(struct async *async)
 #endif
 }
 
-char *find_hook(const char *name)
+const char *find_hook(const char *name)
 {
-       char *path = git_path("hooks/%s", name);
+       const char *path = git_path("hooks/%s", name);
        if (access(path, X_OK) < 0)
                path = NULL;
 
index 2137315ee46f672d945e0d3e011a8cbfbd5582a7..892892de128b9dc9673fedba823159be9e5fff4a 100644 (file)
@@ -52,7 +52,7 @@ int start_command(struct child_process *);
 int finish_command(struct child_process *);
 int run_command(struct child_process *);
 
-extern char *find_hook(const char *name);
+extern const char *find_hook(const char *name);
 LAST_ARG_MUST_BE_NULL
 extern int run_hook_le(const char *const *env, const char *name, ...);
 extern int run_hook_ve(const char *const *env, const char *name, va_list args);
index d7f1838c13f5a88448d0f2034347bfb6482b3edf..1ed74f955fa66ab15790d5e634ceca43d416a4e4 100644 (file)
@@ -405,7 +405,7 @@ void add_to_alternates_file(const char *reference)
 {
        struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
        int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), LOCK_DIE_ON_ERROR);
-       char *alt = mkpath("%s\n", reference);
+       const char *alt = mkpath("%s\n", reference);
        write_or_die(fd, alt, strlen(alt));
        if (commit_lock_file(lock))
                die("could not close alternates file");