Merge branch 'jk/save-getenv-result'
authorJunio C Hamano <gitster@pobox.com>
Tue, 29 Jan 2019 20:47:53 +0000 (12:47 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 29 Jan 2019 20:47:54 +0000 (12:47 -0800)
There were many places the code relied on the string returned from
getenv() to be non-volatile, which is not true, that have been
corrected.

* jk/save-getenv-result:
builtin_diff(): read $GIT_DIFF_OPTS closer to use
merge-recursive: copy $GITHEAD strings
init: make a copy of $GIT_DIR string
config: make a copy of $GIT_CONFIG string
commit: copy saved getenv() result
get_super_prefix(): copy getenv() result

builtin/commit.c
builtin/config.c
builtin/init-db.c
builtin/merge-recursive.c
diff.c
environment.c
index 004b816635bf1628bfe7697f737a22cbcd27622b..7d2e0b61e5fc73a9b338a4f37b9a51ddc6cbf306 100644 (file)
@@ -351,7 +351,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
                if (write_locked_index(&the_index, &index_lock, 0))
                        die(_("unable to create temporary index"));
 
-               old_index_env = getenv(INDEX_ENVIRONMENT);
+               old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
                setenv(INDEX_ENVIRONMENT, get_lock_file_path(&index_lock), 1);
 
                if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
@@ -361,6 +361,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
                        setenv(INDEX_ENVIRONMENT, old_index_env, 1);
                else
                        unsetenv(INDEX_ENVIRONMENT);
+               FREE_AND_NULL(old_index_env);
 
                discard_cache();
                read_cache_from(get_lock_file_path(&index_lock));
index 99bc7ef64ec6f7f0ab0e6dc1d0dc3fd149969a16..98d65bc0ad4fd4bee8bd2755b9d7444d9862eae8 100644 (file)
@@ -599,7 +599,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
        int nongit = !startup_info->have_repository;
        char *value;
 
-       given_config_source.file = getenv(CONFIG_ENVIRONMENT);
+       given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
 
        argc = parse_options(argc, argv, prefix, builtin_config_options,
                             builtin_config_usage,
index 41faffd28db8850fb97daa52c6d481375b380504..93eff7618cf1b98e3c69a7f1f159063e9e73dbe3 100644 (file)
@@ -542,8 +542,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
         * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
         * without --bare.  Catch the error early.
         */
-       git_dir = getenv(GIT_DIR_ENVIRONMENT);
-       work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT);
+       git_dir = xstrdup_or_null(getenv(GIT_DIR_ENVIRONMENT));
+       work_tree = xstrdup_or_null(getenv(GIT_WORK_TREE_ENVIRONMENT));
        if ((!git_dir || is_bare_repository_cfg == 1) && work_tree)
                die(_("%s (or --work-tree=<directory>) not allowed without "
                          "specifying %s (or --git-dir=<directory>)"),
@@ -582,6 +582,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
        }
 
        UNLEAK(real_git_dir);
+       UNLEAK(git_dir);
+       UNLEAK(work_tree);
 
        flags |= INIT_DB_EXIST_OK;
        return init_db(git_dir, real_git_dir, template_dir, flags);
index 9b2f707c291cf903b9151c2f3673b6fe0e0ca6d5..7545136c2a6da526ab7998106f2a28bfcbe8bd81 100644 (file)
@@ -7,16 +7,16 @@
 static const char builtin_merge_recursive_usage[] =
        "git %s <base>... -- <head> <remote> ...";
 
-static const char *better_branch_name(const char *branch)
+static char *better_branch_name(const char *branch)
 {
        static char githead_env[8 + GIT_MAX_HEXSZ + 1];
        char *name;
 
        if (strlen(branch) != the_hash_algo->hexsz)
-               return branch;
+               return xstrdup(branch);
        xsnprintf(githead_env, sizeof(githead_env), "GITHEAD_%s", branch);
        name = getenv(githead_env);
-       return name ? name : branch;
+       return xstrdup(name ? name : branch);
 }
 
 int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
@@ -26,6 +26,7 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
        int i, failed;
        struct object_id h1, h2;
        struct merge_options o;
+       char *better1, *better2;
        struct commit *result;
 
        init_merge_options(&o);
@@ -70,13 +71,17 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
        if (get_oid(o.branch2, &h2))
                die(_("could not resolve ref '%s'"), o.branch2);
 
-       o.branch1 = better_branch_name(o.branch1);
-       o.branch2 = better_branch_name(o.branch2);
+       o.branch1 = better1 = better_branch_name(o.branch1);
+       o.branch2 = better2 = better_branch_name(o.branch2);
 
        if (o.verbosity >= 3)
                printf(_("Merging %s with %s\n"), o.branch1, o.branch2);
 
        failed = merge_recursive_generic(&o, &h1, &h2, bases_count, bases, &result);
+
+       free(better1);
+       free(better2);
+
        if (failed < 0)
                return 128; /* die() error code */
        return failed;
diff --git a/diff.c b/diff.c
index 084bf542931e09c03a7627740f9177e5c9fac5d9..e8c3e8081f9be0c4e9560a834b0f3df75ca81b72 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3544,7 +3544,7 @@ static void builtin_diff(const char *name_a,
                o->found_changes = 1;
        } else {
                /* Crazy xdl interfaces.. */
-               const char *diffopts = getenv("GIT_DIFF_OPTS");
+               const char *diffopts;
                const char *v;
                xpparam_t xpp;
                xdemitconf_t xecfg;
@@ -3587,12 +3587,15 @@ static void builtin_diff(const char *name_a,
                        xecfg.flags |= XDL_EMIT_FUNCCONTEXT;
                if (pe)
                        xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
+
+               diffopts = getenv("GIT_DIFF_OPTS");
                if (!diffopts)
                        ;
                else if (skip_prefix(diffopts, "--unified=", &v))
                        xecfg.ctxlen = strtoul(v, NULL, 10);
                else if (skip_prefix(diffopts, "-u", &v))
                        xecfg.ctxlen = strtoul(v, NULL, 10);
+
                if (o->word_diff)
                        init_diff_words_data(&ecbdata, o, one, two);
                if (xdi_diff_outf(&mf1, &mf2, NULL, fn_out_consume,
index 0e37741d838256d196b2ec9f3ca4e54395c66d31..89af47cb8504903b90460d5faa91be9f61bd2fc3 100644 (file)
@@ -107,7 +107,7 @@ char *git_work_tree_cfg;
 
 static char *git_namespace;
 
-static const char *super_prefix;
+static char *super_prefix;
 
 /*
  * Repository-local GIT_* environment variables; see cache.h for details.
@@ -240,7 +240,7 @@ const char *get_super_prefix(void)
 {
        static int initialized;
        if (!initialized) {
-               super_prefix = getenv(GIT_SUPER_PREFIX_ENVIRONMENT);
+               super_prefix = xstrdup_or_null(getenv(GIT_SUPER_PREFIX_ENVIRONMENT));
                initialized = 1;
        }
        return super_prefix;