Hi micah & devs, I found memory leaks in wget, I have posted it on https://savannah.gnu.org/bugs/?25298
For example wget --no-proxy --timestamping http://www.google.com Wget will issue HEAD first, but when returned from gethttp( in http.c), it didn't free "char *head" allocated by "read_http_response_head (sock)". So wget will leak at least 512bytes memory for each url. Besides, there are several other potential memory leaks in http.c. Below is patch ------------------------ diff -ru wget.orig/src/http.c wget/src/http.c --- wget.orig/src/http.c 2008-12-31 12:39:03.000000000 +0800 +++ wget/src/http.c 2009-01-11 16:26:46.000000000 +0800 @@ -1885,6 +1885,9 @@ register_basic_auth_host (u->host); } xfree (pth); + xfree_null (message); + resp_free (resp); + xfree (head); goto retry_with_auth; } else @@ -1895,6 +1898,9 @@ } logputs (LOG_NOTQUIET, _("Authorization failed.\n")); request_free (req); + xfree_null (message); + resp_free (resp); + xfree (head); return AUTHFAILED; } else /* statcode != HTTP_STATUS_UNAUTHORIZED */ @@ -1938,6 +1944,8 @@ if (has_html_suffix_p (hs->local_file)) *dt |= TEXTHTML; + xfree (head); + xfree_null (message); return RETRUNNEEDED; } else if (!ALLOW_CLOBBER) @@ -2116,6 +2124,7 @@ else CLOSE_INVALIDATE (sock); xfree_null (type); + xfree (head); return NEWLOCATION; } } @@ -2171,6 +2180,7 @@ xfree_null (type); CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there might be more bytes in the body. */ + xfree (head); return RETRUNNEEDED; } if ((contrange != 0 && contrange != hs->restval) @@ -2180,6 +2190,7 @@ Bail out. */ xfree_null (type); CLOSE_INVALIDATE (sock); + xfree (head); return RANGEERR; } if (contlen == -1) @@ -2243,6 +2254,7 @@ CLOSE_FINISH (sock); else CLOSE_INVALIDATE (sock); + xfree (head); return RETRFINISHED; } @@ -2269,6 +2281,7 @@ _("%s has sprung into existence.\n"), hs->local_file); CLOSE_INVALIDATE (sock); + xfree (head); return FOPEN_EXCL_ERR; } } @@ -2276,6 +2289,7 @@ { logprintf (LOG_NOTQUIET, "%s: %s\n", hs->local_file, strerror (errno)); CLOSE_INVALIDATE (sock); + xfree (head); return FOPENERR; } } @@ -2347,6 +2361,7 @@ struct http_stat hstat; /* HTTP status */ struct_stat st; bool send_head_first = true; + char *file_name; /* Assert that no value for *LOCAL_FILE was passed. */ assert (local_file == NULL || *local_file == NULL); @@ -2419,10 +2434,12 @@ /* Send preliminary HEAD request if -N is given and we have an existing * destination file. */ + file_name = url_file_name (u); if (opt.timestamping && !opt.content_disposition - && file_exists_p (url_file_name (u))) + && file_exists_p (file_name)) send_head_first = true; + xfree (file_name); /* THE loop */ do
