Fixed a memleak found by Zhenbo Xu, reportted on 11.04.2012 to bug-wget. 2012-04-12 Tim Ruehsen <tim.rueh...@gmx.de>
* rewrote home_dir() to fix memleak, removed need for freeing home
=== modified file 'src/init.c' --- src/init.c 2012-03-08 09:00:51 +0000 +++ src/init.c 2012-04-12 11:17:21 +0000 @@ -389,63 +389,62 @@ opt.warc_keep_log = true; } +#if defined(WINDOWS) || defined(MSDOS) +# define ISSEP(c) ((c) == '/' || (c) == '\\') +#else +# define ISSEP(c) ((c) == '/') +#endif + /* Return the user's home directory (strdup-ed), or NULL if none is found. */ -char * +const char * home_dir (void) { - static char *buf = NULL; - static char *home, *ret; + static char *home; + + if (!home) + home = getenv ("HOME"); if (!home) { - home = getenv ("HOME"); - if (!home) - { #if defined(MSDOS) - int len; - - /* Under MSDOS, if $HOME isn't defined, use the directory where - `wget.exe' resides. */ - const char *_w32_get_argv0 (void); /* in libwatt.a/pcconfig.c */ - char *p; - - buff = _w32_get_argv0 (); - - p = strrchr (buf, '/'); /* djgpp */ - if (!p) - p = strrchr (buf, '\\'); /* others */ - assert (p); - - len = p - buff + 1; - buff = malloc (len + 1); - if (buff == NULL) - return NULL; - - strncpy (buff, _w32_get_argv0 (), len); - buff[len] = '\0'; - - home = buf; + /* Under MSDOS, if $HOME isn't defined, use the directory where + `wget.exe' resides. */ + const char *_w32_get_argv0 (void); /* in libwatt.a/pcconfig.c */ + char *p, *path; + int len; + + path = _w32_get_argv0 (); + + p = strrchr (path, '/'); /* djgpp */ + if (!p) + p = strrchr (path, '\\'); /* others */ + assert (p); + + if (!p || !asprintf(&home,"%.*s", (int)(p - path), path)) + return NULL; + #elif !defined(WINDOWS) - /* If HOME is not defined, try getting it from the password + /* If HOME is not defined, try getting it from the password file. */ - struct passwd *pwd = getpwuid (getuid ()); - if (!pwd || !pwd->pw_dir) - return NULL; - home = pwd->pw_dir; + size_t homelen; + struct passwd *pwd = getpwuid (getuid ()); + if (!pwd || !pwd->pw_dir) + return NULL; + home = xstrdup(pwd->pw_dir); + + /* moved from setval_internal_tilde() - do we need it ? */ + homelen = strlen (home); + while (homelen && ISSEP (home[homelen - 1])) + home[--homelen] = '\0'; #else /* !WINDOWS */ - /* Under Windows, if $HOME isn't defined, use the directory where - `wget.exe' resides. */ - home = ws_mypath (); + /* Under Windows, if $HOME isn't defined, use the directory where + `wget.exe' resides. */ + home = ws_mypath (); #endif /* WINDOWS */ - } - } - - ret = home ? xstrdup (home) : NULL; - if (buf) - free (buf); - - return ret; + } + + return home; } /* Check the 'WGETRC' environment variable and return the file name @@ -474,7 +473,7 @@ char * wgetrc_user_file_name (void) { - char *home; + const char *home; char *file = NULL; /* If that failed, try $HOME/.wgetrc (or equivalent). */ @@ -484,7 +483,6 @@ home = home_dir (); if (home) file = aprintf ("%s/.wgetrc", home); - xfree_null (home); #endif /* def __VMS [else] */ if (!file) @@ -521,7 +519,6 @@ char *home = home_dir (); xfree_null (file); file = NULL; - home = ws_mypath (); if (home) { file = aprintf ("%s/wget.ini", home); @@ -530,7 +527,6 @@ xfree (file); file = NULL; } - xfree (home); } } #endif /* WINDOWS */ @@ -761,12 +757,6 @@ return line_ok; } -#if defined(WINDOWS) || defined(MSDOS) -# define ISSEP(c) ((c) == '/' || (c) == '\\') -#else -# define ISSEP(c) ((c) == '/') -#endif - /* Run commands[comind].action. */ static bool @@ -781,8 +771,7 @@ setval_internal_tilde (int comind, const char *com, const char *val) { bool ret; - int homelen; - char *home; + const char *home; char **pstring; ret = setval_internal (comind, com, val); @@ -795,10 +784,6 @@ home = home_dir (); if (home) { - homelen = strlen (home); - while (homelen && ISSEP (home[homelen - 1])) - home[--homelen] = '\0'; - /* Skip the leading "~/". */ for (++val; ISSEP (*val); val++) ; === modified file 'src/init.h' --- src/init.h 2011-01-01 12:19:37 +0000 +++ src/init.h 2012-04-12 10:20:54 +0000 @@ -38,7 +38,7 @@ void initialize (void); void run_command (const char *); void setoptval (const char *, const char *, const char *); -char *home_dir (void); +const char *home_dir (void); void cleanup (void); void defaults (void); bool run_wgetrc (const char *file); === modified file 'src/netrc.c' --- src/netrc.c 2011-01-01 12:19:37 +0000 +++ src/netrc.c 2012-04-12 11:05:56 +0000 @@ -81,7 +81,7 @@ #else /* def __VMS */ - char *home = home_dir (); + const char *home = home_dir (); netrc_list = NULL; processed_netrc = 1; @@ -92,7 +92,6 @@ char *path = (char *)alloca (strlen (home) + 1 + strlen (NETRC_FILE_NAME) + 1); sprintf (path, "%s/%s", home, NETRC_FILE_NAME); - xfree (home); err = stat (path, &buf); if (err == 0) netrc_list = parse_netrc (path);