← Commit list

26c6a4d898

Stefan Eissing
Stefan Eissing
2026-06-25
SUCCESS Duration: 187s

Subject

urlapi: do not keep an internal port string

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-int.h+2 -2
@@ -34,11 +34,11 @@ struct Curl_URL {
char *options; /* IMAP only? */
char *host;
char *zoneid; /* for numerical IPv6 addresses */
- char *port;
char *path;
char *query;
char *fragment;
- unsigned short portnum; /* the numerical version (if 'port' is set) */
+ uint16_t portnum; /* the numerical port if present */
+ BIT(port_present); /* to support missing port */
BIT(query_present); /* to support blank */
BIT(fragment_present); /* to support blank */
BIT(guessed_scheme); /* when a URL without scheme is parsed */
lib/urlapi.c+47 -43
@@ -73,7 +73,6 @@ static void free_urlhandle(struct Curl_URL *u)
curlx_free(u->options);
curlx_free(u->host);
curlx_free(u->zoneid);
- curlx_free(u->port);
curlx_free(u->path);
curlx_free(u->query);
curlx_free(u->fragment);
@@ -358,6 +357,8 @@ UNITTEST CURLUcode parse_port(struct Curl_URL *u, struct dynbuf *host,
/*
* Find the end of an IPv6 address on the ']' ending bracket.
*/
+ u->portnum = 0;
+ u->port_present = FALSE;
if(hostname[0] == '[') {
portptr = strchr(hostname, ']');
if(!portptr)
@@ -393,12 +394,8 @@ UNITTEST CURLUcode parse_port(struct Curl_URL *u, struct dynbuf *host,
if(curlx_str_number(&portptr, &port, 0xffff) || *portptr)
return CURLUE_BAD_PORT_NUMBER;
- u->portnum = (unsigned short)port;
- /* generate a new port number string to get rid of leading zeroes etc */
- curlx_free(u->port);
- u->port = curl_maprintf("%" CURL_FORMAT_CURL_OFF_T, port);
- if(!u->port)
- return CURLUE_OUT_OF_MEMORY;
+ u->portnum = (uint16_t)port;
+ u->port_present = TRUE;
}
return CURLUE_OK;
@@ -1344,12 +1341,12 @@ CURLU *curl_url_dup(const CURLU *in)
DUP(u, in, password);
DUP(u, in, options);
DUP(u, in, host);
- DUP(u, in, port);
DUP(u, in, path);
DUP(u, in, query);
DUP(u, in, fragment);
DUP(u, in, zoneid);
u->portnum = in->portnum;
+ u->port_present = in->port_present;
u->fragment_present = in->fragment_present;
u->query_present = in->query_present;
}
@@ -1484,7 +1481,7 @@ static CURLUcode urlget_url(const CURLU *u, char **part, unsigned int flags)
else {
const char *scheme;
char *options = u->options;
- char *port = u->port;
+ char *port = NULL;
const struct Curl_scheme *h = NULL;
char schemebuf[MAX_SCHEME_LEN + 5];
if(u->scheme)
@@ -1494,19 +1491,26 @@ static CURLUcode urlget_url(const CURLU *u, char **part, unsigned int flags)
else
return CURLUE_NO_SCHEME;
+ if(u->port_present) {
+ curl_msnprintf(portbuf, sizeof(portbuf), "%u", u->portnum);
+ port = portbuf;
+ }
+
h = Curl_get_scheme(scheme);
if(h) {
- if(!port && (flags & CURLU_DEFAULT_PORT)) {
+ if(!u->port_present && (flags & CURLU_DEFAULT_PORT)) {
/* there is no stored port number, but asked to deliver a default one
for the scheme */
curl_msnprintf(portbuf, sizeof(portbuf), "%u", h->defport);
port = portbuf;
}
- else if(port && (h->defport == u->portnum) &&
- (flags & CURLU_NO_DEFAULT_PORT))
+ else if(u->port_present && (h->defport == u->portnum) &&
+ (flags & CURLU_NO_DEFAULT_PORT)) {
/* there is a stored port number, but asked to inhibit if it matches
the default port for the scheme */
port = NULL;
+ }
+
if(!(h->flags & PROTOPT_URLOPTIONS))
options = NULL;
}
@@ -1614,10 +1618,24 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
ifmissing = CURLUE_NO_ZONEID;
break;
case CURLUPART_PORT:
- ptr = u->port;
+ ptr = NULL;
ifmissing = CURLUE_NO_PORT;
flags &= ~U_CURLU_URLDECODE; /* never for port */
- if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) {
+ if(u->port_present) {
+ const struct Curl_scheme *h = u->scheme ?
+ Curl_get_scheme(u->scheme) : NULL;
+ /* there is a stored port number, but ask to inhibit if
+ it matches the default one for the scheme */
+ if(h && (h->defport == u->portnum) &&
+ (flags & CURLU_NO_DEFAULT_PORT)) {
+ ptr = NULL;
+ }
+ else {
+ curl_msnprintf(portbuf, sizeof(portbuf), "%u", u->portnum);
+ ptr = portbuf;
+ }
+ }
+ else if((flags & CURLU_DEFAULT_PORT) && u->scheme) {
/* there is no stored port number, but asked to deliver
a default one for the scheme */
const struct Curl_scheme *h = Curl_get_scheme(u->scheme);
@@ -1626,14 +1644,6 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
ptr = portbuf;
}
}
- else if(ptr && u->scheme) {
- /* there is a stored port number, but ask to inhibit if
- it matches the default one for the scheme */
- const struct Curl_scheme *h = Curl_get_scheme(u->scheme);
- if(h && (h->defport == u->portnum) &&
- (flags & CURLU_NO_DEFAULT_PORT))
- ptr = NULL;
- }
break;
case CURLUPART_PATH:
ptr = u->path;
@@ -1700,7 +1710,6 @@ static CURLUcode set_url_scheme(CURLU *u, const char *scheme,
static CURLUcode set_url_port(CURLU *u, const char *provided_port)
{
- char *tmp;
curl_off_t port;
if(!ISDIGIT(provided_port[0]))
/* not a number */
@@ -1708,12 +1717,8 @@ static CURLUcode set_url_port(CURLU *u, const char *provided_port)
if(curlx_str_number(&provided_port, &port, 0xffff) || *provided_port)
/* weirdly provided number, not good! */
return CURLUE_BAD_PORT_NUMBER;
- tmp = curl_maprintf("%" CURL_FORMAT_CURL_OFF_T, port);
- if(!tmp)
- return CURLUE_OUT_OF_MEMORY;
- curlx_free(u->port);
- u->port = tmp;
- u->portnum = (unsigned short)port;
+ u->portnum = (uint16_t)port;
+ u->port_present = TRUE;
return CURLUE_OK;
}
@@ -1796,7 +1801,7 @@ static CURLUcode urlset_clear(CURLU *u, CURLUPart what)
break;
case CURLUPART_PORT:
u->portnum = 0;
- curlx_safefree(u->port);
+ u->port_present = FALSE;
break;
case CURLUPART_PATH:
curlx_safefree(u->path);
@@ -2077,26 +2082,25 @@ bool Curl_url_same_origin(CURLU *base, CURLU *href)
if(href->host) {
if(!curl_strequal(base->host, href->host))
return FALSE;
- if(!curl_strequal(base->zoneid ? base->zoneid : "",
- href->zoneid ? href->zoneid : ""))
- return FALSE;
- if(!curl_strequal(base->port, href->port)) {
- /* This may still match if only one has an explicit port
- * and it is the default for the scheme. */
- if(base->port && href->port)
- return FALSE;
+ if(base->port_present != href->port_present) {
+ /* one is present, one is not */
s = Curl_get_scheme(base->scheme);
if(!s) /* Cannot match default port for unknown scheme */
return FALSE;
-
- /* The port which is set must be the default one */
- if((base->port && (base->portnum != s->defport)) ||
- (href->port && (href->portnum != s->defport)))
+ /* to match, the present one must be the default port */
+ if((base->port_present && (base->portnum != s->defport)) ||
+ (href->port_present && (href->portnum != s->defport)))
return FALSE;
}
+ else if(base->portnum != href->portnum) /* both present or missing */
+ return FALSE;
+
+ if(!curl_strequal(base->zoneid ? base->zoneid : "",
+ href->zoneid ? href->zoneid : ""))
+ return FALSE;
}
- else if(href->port) /* no host in href, then there must be no port */
+ else if(href->port_present) /* no host in href, then there must be no port */
return FALSE;
return TRUE;
}