From: Junio C Hamano Date: Mon, 22 Dec 2014 20:27:01 +0000 (-0800) Subject: Merge branch 'jc/exec-cmd-system-path-leak-fix' X-Git-Tag: v2.3.0-rc0~66 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/6bcaff1a4fe4a3088348e706c149941c74d1ad61?ds=inline;hp=-c Merge branch 'jc/exec-cmd-system-path-leak-fix' The function sometimes returned a non-freeable memory and some other times returned a piece of memory that must be freed. * jc/exec-cmd-system-path-leak-fix: system_path(): always return free'able memory to the caller --- 6bcaff1a4fe4a3088348e706c149941c74d1ad61 diff --combined builtin/help.c index b3c818ee01,76fbfe8b48..e78c135e01 --- a/builtin/help.c +++ b/builtin/help.c @@@ -79,11 -79,12 +79,11 @@@ static const char *get_man_viewer_info( static int check_emacsclient_version(void) { struct strbuf buffer = STRBUF_INIT; - struct child_process ec_process; + struct child_process ec_process = CHILD_PROCESS_INIT; const char *argv_ec[] = { "emacsclient", "--version", NULL }; int version; /* emacsclient prints its version number on stderr */ - memset(&ec_process, 0, sizeof(ec_process)); ec_process.argv = argv_ec; ec_process.err = -1; ec_process.stdout_to_stderr = 1; @@@ -321,16 -322,18 +321,18 @@@ static void setup_man_path(void { struct strbuf new_path = STRBUF_INIT; const char *old_path = getenv("MANPATH"); + char *git_man_path = system_path(GIT_MAN_PATH); /* We should always put ':' after our path. If there is no * old_path, the ':' at the end will let 'man' to try * system-wide paths after ours to find the manual page. If * there is old_path, we need ':' as delimiter. */ - strbuf_addstr(&new_path, system_path(GIT_MAN_PATH)); + strbuf_addstr(&new_path, git_man_path); strbuf_addch(&new_path, ':'); if (old_path) strbuf_addstr(&new_path, old_path); + free(git_man_path); setenv("MANPATH", new_path.buf, 1); strbuf_release(&new_path); @@@ -380,8 -383,10 +382,10 @@@ static void show_info_page(const char * static void get_html_page_path(struct strbuf *page_path, const char *page) { struct stat st; + char *to_free = NULL; + if (!html_path) - html_path = system_path(GIT_HTML_PATH); + html_path = to_free = system_path(GIT_HTML_PATH); /* Check that we have a git documentation directory. */ if (!strstr(html_path, "://")) { @@@ -392,6 -397,7 +396,7 @@@ strbuf_init(page_path, 0); strbuf_addf(page_path, "%s/%s.html", html_path, page); + free(to_free); } /* @@@ -421,7 -427,6 +426,7 @@@ static struct const char *help; } common_guides[] = { { "attributes", N_("Defining attributes per path") }, + { "everyday", N_("Everyday Git With 20 Commands Or So") }, { "glossary", N_("A Git glossary") }, { "ignore", N_("Specifies intentionally untracked files to ignore") }, { "modules", N_("Defining submodule properties") }, diff --combined builtin/init-db.c index 2619ca5881,86c8a30a31..9966522b4a --- a/builtin/init-db.c +++ b/builtin/init-db.c @@@ -119,15 -119,18 +119,18 @@@ static void copy_templates(const char * DIR *dir; const char *git_dir = get_git_dir(); int len = strlen(git_dir); + char *to_free = NULL; if (!template_dir) template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT); if (!template_dir) template_dir = init_db_template_dir; if (!template_dir) - template_dir = system_path(DEFAULT_GIT_TEMPLATE_DIR); - if (!template_dir[0]) + template_dir = to_free = system_path(DEFAULT_GIT_TEMPLATE_DIR); + if (!template_dir[0]) { + free(to_free); return; + } template_len = strlen(template_dir); if (PATH_MAX <= (template_len+strlen("/config"))) die(_("insanely long template path %s"), template_dir); @@@ -139,7 -142,7 +142,7 @@@ dir = opendir(template_path); if (!dir) { warning(_("templates not found %s"), template_dir); - return; + goto free_return; } /* Make sure that template is from the correct vintage */ @@@ -155,8 -158,7 +158,7 @@@ "a wrong format version %d from '%s'"), repository_format_version, template_dir); - closedir(dir); - return; + goto close_free_return; } memcpy(path, git_dir, len); @@@ -166,7 -168,10 +168,10 @@@ copy_templates_1(path, len, template_path, template_len, dir); + close_free_return: closedir(dir); + free_return: + free(to_free); } static int git_init_db_config(const char *k, const char *v, void *cb) @@@ -254,10 -259,7 +259,10 @@@ static int create_default_files(const c struct stat st2; filemode = (!chmod(path, st1.st_mode ^ S_IXUSR) && !lstat(path, &st2) && - st1.st_mode != st2.st_mode); + st1.st_mode != st2.st_mode && + !chmod(path, st1.st_mode)); + if (filemode && !reinit && (st1.st_mode & S_IXUSR)) + filemode = 0; } git_config_set("core.filemode", filemode ? "true" : "false"); @@@ -333,12 -335,12 +338,12 @@@ int set_git_dir_init(const char *git_di * moving the target repo later on in separate_git_dir() */ git_link = xstrdup(real_path(git_dir)); + set_git_dir(real_path(real_git_dir)); } else { - real_git_dir = real_path(git_dir); + set_git_dir(real_path(git_dir)); git_link = NULL; } - set_git_dir(real_path(real_git_dir)); return 0; } @@@ -429,9 -431,8 +434,9 @@@ int init_db(const char *template_dir, u static int guess_repository_type(const char *git_dir) { - char cwd[PATH_MAX]; const char *slash; + char *cwd; + int cwd_is_git_dir; /* * "GIT_DIR=. git init" is always bare. @@@ -439,10 -440,9 +444,10 @@@ */ if (!strcmp(".", git_dir)) return 1; - if (!getcwd(cwd, sizeof(cwd))) - die_errno(_("cannot tell cwd")); - if (!strcmp(git_dir, cwd)) + cwd = xgetcwd(); + cwd_is_git_dir = !strcmp(git_dir, cwd); + free(cwd); + if (cwd_is_git_dir) return 1; /* * "GIT_DIR=.git or GIT_DIR=something/.git is usually not. @@@ -540,9 -540,10 +545,9 @@@ int cmd_init_db(int argc, const char ** usage(init_db_usage[0]); } if (is_bare_repository_cfg == 1) { - static char git_dir[PATH_MAX+1]; - - setenv(GIT_DIR_ENVIRONMENT, - getcwd(git_dir, sizeof(git_dir)), argc > 0); + char *cwd = xgetcwd(); + setenv(GIT_DIR_ENVIRONMENT, cwd, argc > 0); + free(cwd); } if (init_shared_repository != -1) @@@ -576,10 -577,13 +581,10 @@@ git_work_tree_cfg = xstrdup(real_path(rel)); free(rel); } - if (!git_work_tree_cfg) { - git_work_tree_cfg = xcalloc(PATH_MAX, 1); - if (!getcwd(git_work_tree_cfg, PATH_MAX)) - die_errno (_("Cannot access current working directory")); - } + if (!git_work_tree_cfg) + git_work_tree_cfg = xgetcwd(); if (work_tree) - set_git_work_tree(real_path(work_tree)); + set_git_work_tree(work_tree); else set_git_work_tree(git_work_tree_cfg); if (access(get_git_work_tree(), X_OK)) @@@ -588,7 -592,7 +593,7 @@@ } else { if (work_tree) - set_git_work_tree(real_path(work_tree)); + set_git_work_tree(work_tree); } set_git_dir_init(git_dir, real_git_dir, 1); diff --combined exec_cmd.c index 698e7526c4,26ebef6686..8ab37b5f74 --- a/exec_cmd.c +++ b/exec_cmd.c @@@ -6,7 -6,7 +6,7 @@@ static const char *argv_exec_path; static const char *argv0_path; - const char *system_path(const char *path) + char *system_path(const char *path) { #ifdef RUNTIME_PREFIX static const char *prefix; @@@ -16,7 -16,7 +16,7 @@@ struct strbuf d = STRBUF_INIT; if (is_absolute_path(path)) - return path; + return xstrdup(path); #ifdef RUNTIME_PREFIX assert(argv0_path); @@@ -34,8 -34,7 +34,7 @@@ #endif strbuf_addf(&d, "%s/%s", prefix, path); - path = strbuf_detach(&d, NULL); - return path; + return strbuf_detach(&d, NULL); } const char *git_extract_argv0_path(const char *argv0) @@@ -86,7 -85,11 +85,7 @@@ const char *git_exec_path(void static void add_path(struct strbuf *out, const char *path) { if (path && *path) { - if (is_absolute_path(path)) - strbuf_addstr(out, path); - else - strbuf_addstr(out, absolute_path(path)); - + strbuf_add_absolute_path(out, path); strbuf_addch(out, PATH_SEP); } }