From 0e37b42dc956bd8ab462aa0d9ccef977a2de81c6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 May 2024 15:32:57 +0200 Subject: [PATCH] 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 --- lib/url.c | 95 ++++++++++++++++--------------------------- tests/unit/unit1620.c | 8 +++- 2 files changed, 42 insertions(+), 61 deletions(-) diff --git a/lib/url.c b/lib/url.c index d7e58abc3e..59f796f991 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2568,14 +2568,15 @@ out: * * Parameters: * - * login [in] - The login string. - * len [in] - The length of the login string. - * userp [in/out] - The address where a pointer to newly allocated memory + * login [in] - login string. + * len [in] - length of the login string. + * userp [in/out] - address where a pointer to newly allocated memory * 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. - * optionsp [in/out] - The address where a pointer to newly allocated memory - * holding the options will be stored upon completion. + * optionsp [in/out] - OPTIONAL address where a pointer to newly allocated + * memory holding the options will be stored upon + * completion. * * Returns CURLE_OK on success. */ @@ -2583,19 +2584,19 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len, char **userp, char **passwdp, char **optionsp) { - CURLcode result = CURLE_OK; char *ubuf = NULL; char *pbuf = NULL; - char *obuf = NULL; const char *psep = NULL; const char *osep = NULL; size_t ulen; size_t plen; size_t olen; + DEBUGASSERT(userp); + DEBUGASSERT(passwdp); + /* Attempt to find the password separator */ - if(passwdp) - psep = memchr(login, ':', len); + psep = memchr(login, ':', len); /* Attempt to find the options separator */ if(optionsp) @@ -2607,64 +2608,40 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len, (osep ? (size_t)(osep - login) : len)); plen = (psep ? (osep && osep > psep ? (size_t)(osep - psep) : - (size_t)(login + len - psep)) - 1 : 0); + (size_t)(login + len - psep)) - 1 : 0); olen = (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 */ - if(userp) { - ubuf = malloc(ulen + 1); - if(!ubuf) - result = CURLE_OUT_OF_MEMORY; - } + /* Clone the user portion buffer, which can be zero length */ + ubuf = Curl_memdup0(login, ulen); + if(!ubuf) + goto error; - /* Allocate the password portion buffer */ - if(!result && passwdp && psep) { - pbuf = malloc(plen + 1); - if(!pbuf) { - free(ubuf); - result = CURLE_OUT_OF_MEMORY; - } + /* Clone the password portion buffer */ + if(psep) { + pbuf = Curl_memdup0(&psep[1], plen); + if(!pbuf) + goto error; } /* Allocate the options portion buffer */ - if(!result && optionsp && olen) { - obuf = malloc(olen + 1); - if(!obuf) { - free(pbuf); - free(ubuf); - result = CURLE_OUT_OF_MEMORY; + if(optionsp) { + char *obuf = NULL; + if(olen) { + obuf = Curl_memdup0(&osep[1], olen); + if(!obuf) + goto error; } + *optionsp = obuf; } - - 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; - } - } - - return result; + *userp = ubuf; + *passwdp = pbuf; + return CURLE_OK; +error: + free(ubuf); + free(pbuf); + return CURLE_OUT_OF_MEMORY; } /************************************************************* diff --git a/tests/unit/unit1620.c b/tests/unit/unit1620.c index dc3b3455af..fecb92321b 100644 --- a/tests/unit/unit1620.c +++ b/tests/unit/unit1620.c @@ -46,6 +46,8 @@ UNITTEST_START struct Curl_easy *empty; const char *hostname = "hostname"; enum dupstring i; + char *userstr = NULL; + char *passwdstr = NULL; bool async = FALSE; bool protocol_connect = FALSE; @@ -73,10 +75,12 @@ UNITTEST_START rc = Curl_init_do(empty, empty->conn); fail_unless(rc == CURLE_OK, "Curl_init_do() failed"); - rc = Curl_parse_login_details( - hostname, strlen(hostname), NULL, NULL, NULL); + rc = Curl_parse_login_details(hostname, strlen(hostname), + &userstr, &passwdstr, NULL); fail_unless(rc == CURLE_OK, "Curl_parse_login_details() failed"); + free(userstr); + free(passwdstr); Curl_freeset(empty); for(i = (enum dupstring)0; i < STRING_LAST; i++) {