url: make parse_login_details use memdup0

Also make the user and password arguments mandatory, since all code
paths in libcurl used them anyway.

Adapted unit test case 1620 to the new rules.

Closes #13584
This commit is contained in:
Daniel Stenberg 2024-05-10 15:32:57 +02:00
parent fa9a564942
commit 0e37b42dc9
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 42 additions and 61 deletions

View File

@ -2568,14 +2568,15 @@ out:
* *
* Parameters: * Parameters:
* *
* login [in] - The login string. * login [in] - login string.
* len [in] - The length of the login string. * len [in] - length of the login string.
* userp [in/out] - The address where a pointer to newly allocated memory * userp [in/out] - address where a pointer to newly allocated memory
* holding the user will be stored upon completion. * holding the user will be stored upon completion.
* passwdp [in/out] - The address where a pointer to newly allocated memory * passwdp [in/out] - address where a pointer to newly allocated memory
* holding the password will be stored upon completion. * holding the password will be stored upon completion.
* optionsp [in/out] - The address where a pointer to newly allocated memory * optionsp [in/out] - OPTIONAL address where a pointer to newly allocated
* holding the options will be stored upon completion. * memory holding the options will be stored upon
* completion.
* *
* Returns CURLE_OK on success. * Returns CURLE_OK on success.
*/ */
@ -2583,18 +2584,18 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len,
char **userp, char **passwdp, char **userp, char **passwdp,
char **optionsp) char **optionsp)
{ {
CURLcode result = CURLE_OK;
char *ubuf = NULL; char *ubuf = NULL;
char *pbuf = NULL; char *pbuf = NULL;
char *obuf = NULL;
const char *psep = NULL; const char *psep = NULL;
const char *osep = NULL; const char *osep = NULL;
size_t ulen; size_t ulen;
size_t plen; size_t plen;
size_t olen; size_t olen;
DEBUGASSERT(userp);
DEBUGASSERT(passwdp);
/* Attempt to find the password separator */ /* Attempt to find the password separator */
if(passwdp)
psep = memchr(login, ':', len); psep = memchr(login, ':', len);
/* Attempt to find the options separator */ /* Attempt to find the options separator */
@ -2612,59 +2613,35 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len,
(psep && psep > osep ? (size_t)(psep - osep) : (psep && psep > osep ? (size_t)(psep - osep) :
(size_t)(login + len - osep)) - 1 : 0); (size_t)(login + len - osep)) - 1 : 0);
/* Allocate the user portion buffer, which can be zero length */ /* Clone the user portion buffer, which can be zero length */
if(userp) { ubuf = Curl_memdup0(login, ulen);
ubuf = malloc(ulen + 1);
if(!ubuf) if(!ubuf)
result = CURLE_OUT_OF_MEMORY; goto error;
}
/* Allocate the password portion buffer */ /* Clone the password portion buffer */
if(!result && passwdp && psep) { if(psep) {
pbuf = malloc(plen + 1); pbuf = Curl_memdup0(&psep[1], plen);
if(!pbuf) { if(!pbuf)
free(ubuf); goto error;
result = CURLE_OUT_OF_MEMORY;
}
} }
/* Allocate the options portion buffer */ /* Allocate the options portion buffer */
if(!result && optionsp && olen) { if(optionsp) {
obuf = malloc(olen + 1); char *obuf = NULL;
if(!obuf) { if(olen) {
free(pbuf); obuf = Curl_memdup0(&osep[1], olen);
free(ubuf); if(!obuf)
result = CURLE_OUT_OF_MEMORY; goto error;
} }
}
if(!result) {
/* Store the user portion if necessary */
if(ubuf) {
memcpy(ubuf, login, ulen);
ubuf[ulen] = '\0';
Curl_safefree(*userp);
*userp = ubuf;
}
/* Store the password portion if necessary */
if(pbuf) {
memcpy(pbuf, psep + 1, plen);
pbuf[plen] = '\0';
Curl_safefree(*passwdp);
*passwdp = pbuf;
}
/* Store the options portion if necessary */
if(obuf) {
memcpy(obuf, osep + 1, olen);
obuf[olen] = '\0';
Curl_safefree(*optionsp);
*optionsp = obuf; *optionsp = obuf;
} }
} *userp = ubuf;
*passwdp = pbuf;
return result; return CURLE_OK;
error:
free(ubuf);
free(pbuf);
return CURLE_OUT_OF_MEMORY;
} }
/************************************************************* /*************************************************************

View File

@ -46,6 +46,8 @@ UNITTEST_START
struct Curl_easy *empty; struct Curl_easy *empty;
const char *hostname = "hostname"; const char *hostname = "hostname";
enum dupstring i; enum dupstring i;
char *userstr = NULL;
char *passwdstr = NULL;
bool async = FALSE; bool async = FALSE;
bool protocol_connect = FALSE; bool protocol_connect = FALSE;
@ -73,10 +75,12 @@ UNITTEST_START
rc = Curl_init_do(empty, empty->conn); rc = Curl_init_do(empty, empty->conn);
fail_unless(rc == CURLE_OK, "Curl_init_do() failed"); fail_unless(rc == CURLE_OK, "Curl_init_do() failed");
rc = Curl_parse_login_details( rc = Curl_parse_login_details(hostname, strlen(hostname),
hostname, strlen(hostname), NULL, NULL, NULL); &userstr, &passwdstr, NULL);
fail_unless(rc == CURLE_OK, fail_unless(rc == CURLE_OK,
"Curl_parse_login_details() failed"); "Curl_parse_login_details() failed");
free(userstr);
free(passwdstr);
Curl_freeset(empty); Curl_freeset(empty);
for(i = (enum dupstring)0; i < STRING_LAST; i++) { for(i = (enum dupstring)0; i < STRING_LAST; i++) {