mirror of
https://github.com/curl/curl.git
synced 2026-07-26 16:07:21 +03:00
urlapi: fix memleaks on error in parse_hostname_login()
Detected by GitHub Code Quality Follow-up toacd82c8bfd#11006 Follow-up to4183b8fe9a#8049 Closes #21879
This commit is contained in:
parent
9c1ebea359
commit
7c34365cce
2 changed files with 75 additions and 10 deletions
26
lib/urlapi.c
26
lib/urlapi.c
|
|
@ -253,12 +253,18 @@ CURLUcode Curl_junkscan(const char *url, size_t *urllen, bool allowspace)
|
|||
* Parse the login details (username, password and options) from the URL and
|
||||
* strip them out of the hostname
|
||||
*
|
||||
* @unittest 1675
|
||||
*/
|
||||
static CURLUcode parse_hostname_login(struct Curl_URL *u,
|
||||
const char *login,
|
||||
size_t len,
|
||||
unsigned int flags,
|
||||
size_t *offset) /* to the hostname */
|
||||
UNITTEST CURLUcode parse_hostname_login(struct Curl_URL *u,
|
||||
const char *login,
|
||||
size_t len,
|
||||
unsigned int flags,
|
||||
size_t *hostname_offset);
|
||||
UNITTEST CURLUcode parse_hostname_login(struct Curl_URL *u,
|
||||
const char *login,
|
||||
size_t len,
|
||||
unsigned int flags,
|
||||
size_t *hostname_offset)
|
||||
{
|
||||
CURLUcode ures = CURLUE_OK;
|
||||
CURLcode result;
|
||||
|
|
@ -278,7 +284,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
|
|||
|
||||
DEBUGASSERT(login);
|
||||
|
||||
*offset = 0;
|
||||
*hostname_offset = 0;
|
||||
ptr = memchr(login, '@', len);
|
||||
if(!ptr)
|
||||
goto out;
|
||||
|
|
@ -326,7 +332,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
|
|||
}
|
||||
|
||||
/* the hostname starts at this offset */
|
||||
*offset = ptr - login;
|
||||
*hostname_offset = ptr - login;
|
||||
return CURLUE_OK;
|
||||
|
||||
out:
|
||||
|
|
@ -334,9 +340,9 @@ out:
|
|||
curlx_free(userp);
|
||||
curlx_free(passwdp);
|
||||
curlx_free(optionsp);
|
||||
u->user = NULL;
|
||||
u->password = NULL;
|
||||
u->options = NULL;
|
||||
curlx_safefree(u->user);
|
||||
curlx_safefree(u->password);
|
||||
curlx_safefree(u->options);
|
||||
|
||||
return ures;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -383,5 +383,64 @@ loop_end:
|
|||
}
|
||||
#endif /* !CURL_DISABLE_HTTP */
|
||||
|
||||
/* Test parse_hostname_login */
|
||||
{
|
||||
struct Curl_URL u;
|
||||
int fails = 0;
|
||||
unsigned int i;
|
||||
struct test {
|
||||
CURLUcode uc;
|
||||
const char *in;
|
||||
const char *scheme;
|
||||
unsigned int flags;
|
||||
const char *user;
|
||||
const char *password;
|
||||
const char *options;
|
||||
size_t offset;
|
||||
};
|
||||
const struct test tests[] = {
|
||||
{ CURLUE_OK, "foo:bar@host", NULL, 0, "foo", "bar", "o", 8 },
|
||||
{ CURLUE_OK, "foo:bar;abc@host", "imap", 0, "foo", "bar", "abc", 12 },
|
||||
{ CURLUE_OK, "foo:bar;abc@host", NULL, 0, "foo", "bar;abc", "o", 12 },
|
||||
{ CURLUE_USER_NOT_ALLOWED, "foo:bar@host", NULL, CURLU_DISALLOW_USER,
|
||||
NULL, NULL, NULL, 0 },
|
||||
{ CURLUE_OK, "host", NULL, 0, NULL, NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
for(i = 0; i < CURL_ARRAYSIZE(tests); i++) {
|
||||
CURLUcode uc;
|
||||
size_t offset = 0;
|
||||
memset(&u, 0, sizeof(u));
|
||||
u.scheme = CURL_UNCONST(tests[i].scheme);
|
||||
u.user = curlx_strdup("u");
|
||||
u.password = curlx_strdup("p");
|
||||
u.options = curlx_strdup("o");
|
||||
uc = parse_hostname_login(&u, tests[i].in, strlen(tests[i].in),
|
||||
tests[i].flags, &offset);
|
||||
if(uc != tests[i].uc ||
|
||||
!!u.user != !!tests[i].user ||
|
||||
(u.user && tests[i].user &&
|
||||
strcmp(u.user, tests[i].user)) ||
|
||||
!!u.password != !!tests[i].password ||
|
||||
(u.password && tests[i].password &&
|
||||
strcmp(u.password, tests[i].password)) ||
|
||||
!!u.options != !!tests[i].options ||
|
||||
(u.options && tests[i].options &&
|
||||
strcmp(u.options, tests[i].options)) ||
|
||||
offset != tests[i].offset) {
|
||||
curl_mfprintf(stderr, "%d: parse_hostname_login('%s') host failed:"
|
||||
" expected '%d/%s/%s/%s/%zu', got '%d/%s/%s/%s/%zu'\n",
|
||||
i, tests[i].in, (int)tests[i].uc, tests[i].user,
|
||||
tests[i].password, tests[i].options, tests[i].offset,
|
||||
(int)uc, u.user, u.password, u.options, offset);
|
||||
fails++;
|
||||
}
|
||||
curlx_safefree(u.user);
|
||||
curlx_safefree(u.password);
|
||||
curlx_safefree(u.options);
|
||||
}
|
||||
abort_if(fails, "parse_hostname_login tests failed");
|
||||
}
|
||||
|
||||
UNITTEST_END_SIMPLE
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue