mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
libfetch: Correctly free redirect target
When processing a redirect, if we get multiple Location headers, we free the previous one using free(new) instead of fetchFreeURL(new), which leaks new->doc. While here, rename new to loc since new is a reserved word in C++. MFC after: 1 week Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D60015
This commit is contained in:
1 parent
b319c3d6ac
commit
cd2fca49d3
1 file changed
+16
-16
+16
-16
@@ -1565,7 +1565,7 @@ http_request_body(struct url *URL, const char *op, struct url_stat *us,
|
||||
char timebuf[80];
|
||||
char hbuf[MAXHOSTNAMELEN + 7], *host;
|
||||
conn_t *conn;
|
||||
struct url *url, *new;
|
||||
struct url *url, *loc;
|
||||
int chunked, direct, ims, noredirect, verbose;
|
||||
int e, i, n, val;
|
||||
off_t offset, clength, length, size;
|
||||
@@ -1602,7 +1602,7 @@ http_request_body(struct url *URL, const char *op, struct url_stat *us,
|
||||
|
||||
e = HTTP_PROTOCOL_ERROR;
|
||||
do {
|
||||
new = NULL;
|
||||
loc = NULL;
|
||||
chunked = 0;
|
||||
offset = 0;
|
||||
clength = -1;
|
||||
@@ -1871,32 +1871,32 @@ http_request_body(struct url *URL, const char *op, struct url_stat *us,
|
||||
n = 1;
|
||||
break;
|
||||
}
|
||||
if (new)
|
||||
free(new);
|
||||
if (loc != NULL)
|
||||
fetchFreeURL(loc);
|
||||
if (verbose)
|
||||
fetch_info("%d redirect to %s",
|
||||
conn->err, p);
|
||||
if (*p == '/')
|
||||
/* absolute path */
|
||||
new = fetchMakeURL(url->scheme, url->host,
|
||||
loc = fetchMakeURL(url->scheme, url->host,
|
||||
url->port, p, url->user, url->pwd);
|
||||
else
|
||||
new = fetchParseURL(p);
|
||||
if (new == NULL) {
|
||||
loc = fetchParseURL(p);
|
||||
if (loc == NULL) {
|
||||
/* XXX should set an error code */
|
||||
DEBUGF("failed to parse new URL\n");
|
||||
goto ouch;
|
||||
}
|
||||
|
||||
/* Only copy credentials if the host matches */
|
||||
if (strcmp(new->host, url->host) == 0 &&
|
||||
!*new->user && !*new->pwd) {
|
||||
strcpy(new->user, url->user);
|
||||
strcpy(new->pwd, url->pwd);
|
||||
if (strcmp(loc->host, url->host) == 0 &&
|
||||
!*loc->user && !*loc->pwd) {
|
||||
strcpy(loc->user, url->user);
|
||||
strcpy(loc->pwd, url->pwd);
|
||||
}
|
||||
new->offset = url->offset;
|
||||
new->length = url->length;
|
||||
new->ims_time = url->ims_time;
|
||||
loc->offset = url->offset;
|
||||
loc->length = url->length;
|
||||
loc->ims_time = url->ims_time;
|
||||
break;
|
||||
case hdr_transfer_encoding:
|
||||
/* XXX weak test*/
|
||||
@@ -1965,13 +1965,13 @@ http_request_body(struct url *URL, const char *op, struct url_stat *us,
|
||||
clean_http_auth_challenges(&server_challenges);
|
||||
fetch_close(conn);
|
||||
conn = NULL;
|
||||
if (!new) {
|
||||
if (loc == NULL) {
|
||||
DEBUGF("redirect with no new location\n");
|
||||
break;
|
||||
}
|
||||
if (url != URL)
|
||||
fetchFreeURL(url);
|
||||
url = new;
|
||||
url = loc;
|
||||
} while (++i < n);
|
||||
|
||||
/* we failed, or ran out of retries */
|
||||
|
||||
Reference in new issue
Block a user