Fixed a memleak found by Zhenbo Xu, reportted on 11.04.2012 to bug-wget.
2012-04-12 Tim Ruehsen <[email protected]>
* 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);