← Commit list

831a151484

Daniel Stenberg
Daniel Stenberg
2026-05-15
SUCCESS Duration: 473s

Subject

urlapi: consume trailing dots after IPv4 numerical addresses

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/urlapi.c+20 -8
@@ -496,6 +496,9 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname,
* Output the "normalized" version of that input string in plain quad decimal
* integers.
*
+ * A single dot following the numerical address is accepted and "swallowed" as
+ * if it was never there.
+ *
* Returns the host type.
*
* @unittest 1675
@@ -527,17 +530,26 @@ UNITTEST int ipv4_normalize(struct dynbuf *host)
else
rc = curlx_str_number(&c, &l, UINT_MAX);
- if(rc)
- return HOST_NAME;
-
- parts[n] = (unsigned int)l;
+ if(rc) {
+ if(!n || (rc != STRE_NO_NUM) || *c)
+ return HOST_NAME;
+ n--;
+ }
+ else
+ parts[n] = (unsigned int)l;
switch(*c) {
case '.':
- if(n == 3)
- return HOST_NAME;
- n++;
- c++;
+ if(n == 3) {
+ if(c[1])
+ /* something follows this dot */
+ return HOST_NAME;
+ done = TRUE;
+ }
+ else {
+ n++;
+ c++;
+ }
break;
case '\0':
tests/data/test1560+1 -1
@@ -37,7 +37,7 @@ lib%TESTNUMBER
success
</stdout>
<limits>
-Allocations: 3100
+Allocations: 3200
</limits>
</verify>
</testcase>
tests/libtest/lib1560.c+19 -2
@@ -625,6 +625,23 @@ static const struct testcase get_parts_list[] = {
};
static const struct urltestcase get_url_list[] = {
+ {"https://127.1.", "https://127.0.0.1/", 0, 0, CURLUE_OK},
+ {"https://127.1.:443", "https://127.0.0.1:443/", 0, 0, CURLUE_OK},
+ {"https://127.1.?moo", "https://127.0.0.1/?moo", 0, 0, CURLUE_OK},
+ {"https://127.1.#moo", "https://127.0.0.1/#moo", 0, 0, CURLUE_OK},
+ {"https://127.1.a", "https://127.1.a/", 0, 0, CURLUE_OK},
+ {"https://127.1..", "", 0, 0, CURLUE_BAD_HOSTNAME},
+ {"https://127.1..:443", "", 0, 0, CURLUE_BAD_HOSTNAME},
+ {"https://127.1..?moo", "", 0, 0, CURLUE_BAD_HOSTNAME},
+ {"https://127.1..#moo", "", 0, 0, CURLUE_BAD_HOSTNAME},
+ {"https://127.1.1.", "https://127.1.0.1/", 0, 0, CURLUE_OK},
+ {"https://127.1.1./foo", "https://127.1.0.1/foo", 0, 0, CURLUE_OK},
+ {"https://127.1.1.1.", "https://127.1.1.1/", 0, 0, CURLUE_OK},
+ {"https://127.1", "https://127.0.0.1/", 0, 0, CURLUE_OK},
+ {"https://127.0.0.1.", "https://127.0.0.1/", 0, 0, CURLUE_OK},
+ {"https://127.0.0.0xff.", "https://127.0.0.255/", 0, 0, CURLUE_OK},
+ {"https://127.0.0.1..", "", 0, 0, CURLUE_BAD_HOSTNAME},
+ {"https://127.0.0.256..", "", 0, 0, CURLUE_BAD_HOSTNAME},
{"http://hej./", "http://hej./", 0, 0, CURLUE_OK},
{"http://hej../", "", 0, 0, CURLUE_BAD_HOSTNAME},
{"http://hej.../", "", 0, 0, CURLUE_BAD_HOSTNAME},
@@ -743,9 +760,9 @@ static const struct urltestcase get_url_list[] = {
{"https://16843009", "https://1.1.1.1/", 0, 0, CURLUE_OK},
{"https://0177.1", "https://127.0.0.1/", 0, 0, CURLUE_OK},
{"https://0111.02.0x3", "https://73.2.0.3/", 0, 0, CURLUE_OK},
- {"https://0111.02.0x3.", "https://0111.02.0x3./", 0, 0, CURLUE_OK},
+ {"https://0111.02.0x3.", "https://73.2.0.3/", 0, 0, CURLUE_OK},
{"https://0111.02.030", "https://73.2.0.24/", 0, 0, CURLUE_OK},
- {"https://0111.02.030.", "https://0111.02.030./", 0, 0, CURLUE_OK},
+ {"https://0111.02.030.", "https://73.2.0.24/", 0, 0, CURLUE_OK},
{"https://0xff.0xff.0377.255", "https://255.255.255.255/", 0, 0, CURLUE_OK},
{"https://1.0xffffff", "https://1.255.255.255/", 0, 0, CURLUE_OK},
/* IPv4 numerical overflows or syntax errors will not normalize */