Skip to content

Commit

Permalink
uri-util: Changed URI host/authority parsing API to not use a boolean.
Browse files Browse the repository at this point in the history
The boolean indicated whether the basic reg-name syntax or the more limited Internet host name syntax was to be expected.
This change creates separate functions for this.
  • Loading branch information
stephanbosch authored and GitLab committed May 16, 2016
1 parent 14383bf commit d3b0b5d
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 47 deletions.
4 changes: 2 additions & 2 deletions src/lib-http/http-url.c
Expand Up @@ -35,7 +35,7 @@ static bool http_url_parse_authority(struct http_url_parser *url_parser)
const char *user = NULL, *password = NULL;
int ret;

if ((ret = uri_parse_authority(parser, &auth, TRUE)) < 0)
if ((ret = uri_parse_host_authority(parser, &auth)) < 0)
return FALSE;
if (auth.host.name == NULL || *auth.host.name == '\0') {
/* RFC 7230, Section 2.7.1: http URI Scheme
Expand Down Expand Up @@ -367,7 +367,7 @@ int http_url_request_target_parse(const char *request_target,
parser = &url_parser.parser;
uri_parser_init(parser, pool, host_header);

if (uri_parse_authority(parser, &auth, TRUE) <= 0) {
if (uri_parse_host_authority(parser, &auth) <= 0) {
*error_r = t_strdup_printf("Invalid Host header: %s", parser->error);
return -1;
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib-imap/imap-url.c
Expand Up @@ -191,8 +191,8 @@ static int imap_url_parse_iserver(struct imap_url_parser *url_parser)
*/

/* "//" iserver */
if ((ret = uri_parse_slashslash_authority
(parser, &auth, TRUE)) <= 0)
if ((ret = uri_parse_slashslash_host_authority
(parser, &auth)) <= 0)
return ret;
if (auth.host.name == NULL || *auth.host.name == '\0') {
/* This situation is not documented anywhere, but it is not
Expand Down
84 changes: 68 additions & 16 deletions src/lib/uri-util.c
Expand Up @@ -393,7 +393,7 @@ uri_parse_ipv4address(struct uri_parser *parser, string_t *literal,
}

static int
uri_parse_reg_name(struct uri_parser *parser,
uri_do_parse_reg_name(struct uri_parser *parser,
string_t *reg_name) ATTR_NULL(2)
{
/* RFC 3986:
Expand Down Expand Up @@ -431,7 +431,24 @@ uri_parse_reg_name(struct uri_parser *parser,
return 0;
}

static int uri_do_parse_host_name_dns(struct uri_parser *parser,
int uri_parse_reg_name(struct uri_parser *parser,
const char **reg_name_r)
{
string_t *reg_name = NULL;
int ret;

if (reg_name_r != NULL)
reg_name = uri_parser_get_tmpbuf(parser, 256);

if ((ret=uri_do_parse_reg_name(parser, reg_name)) <= 0)
return ret;

if (reg_name_r != NULL)
*reg_name_r = str_c(reg_name);
return 1;
}

static int uri_do_parse_host_name(struct uri_parser *parser,
string_t *host_name) ATTR_NULL(2)
{
const unsigned char *first, *part;
Expand Down Expand Up @@ -547,7 +564,7 @@ static int uri_do_parse_host_name_dns(struct uri_parser *parser,
return 1;
}

int uri_parse_host_name_dns(struct uri_parser *parser,
int uri_parse_host_name(struct uri_parser *parser,
const char **host_name_r)
{
string_t *host_name = NULL;
Expand All @@ -556,7 +573,7 @@ int uri_parse_host_name_dns(struct uri_parser *parser,
if (host_name_r != NULL)
host_name = uri_parser_get_tmpbuf(parser, 256);

if ((ret=uri_do_parse_host_name_dns(parser, host_name)) <= 0)
if ((ret=uri_do_parse_host_name(parser, host_name)) <= 0)
return ret;

if (host_name_r != NULL)
Expand Down Expand Up @@ -615,8 +632,10 @@ uri_parse_ip_literal(struct uri_parser *parser, string_t *literal,
return 1;
}

int uri_parse_host(struct uri_parser *parser,
struct uri_host *host, bool dns_name)
static int
uri_do_parse_host(struct uri_parser *parser,
struct uri_host *host, bool host_name)
ATTR_NULL(2)
{
const unsigned char *preserve;
struct in_addr ip4;
Expand Down Expand Up @@ -664,16 +683,22 @@ int uri_parse_host(struct uri_parser *parser,
str_truncate(literal, 0);

/* reg-name */
if (dns_name) {
if (uri_do_parse_host_name_dns(parser, literal) < 0)
if (host_name) {
if (uri_do_parse_host_name(parser, literal) < 0)
return -1;
} else if (uri_parse_reg_name(parser, literal) < 0)
} else if (uri_do_parse_reg_name(parser, literal) < 0)
return -1;
if (host != NULL)
host->name = p_strdup(parser->pool, str_c(literal));
return 0;
}

int uri_parse_host(struct uri_parser *parser,
struct uri_host *host)
{
return uri_do_parse_host(parser, host, TRUE);
}

static int
uri_parse_port(struct uri_parser *parser,
struct uri_authority *auth) ATTR_NULL(2)
Expand Down Expand Up @@ -702,8 +727,9 @@ uri_parse_port(struct uri_parser *parser,
return 1;
}

int uri_parse_authority(struct uri_parser *parser,
struct uri_authority *auth, bool dns_name)
static int
uri_do_parse_authority(struct uri_parser *parser,
struct uri_authority *auth, bool host_name) ATTR_NULL(2)
{
const unsigned char *p;
int ret;
Expand Down Expand Up @@ -734,8 +760,8 @@ int uri_parse_authority(struct uri_parser *parser,
}

/* host */
if (uri_parse_host(parser,
(auth == NULL ? NULL : &auth->host), dns_name) < 0)
if (uri_do_parse_host(parser,
(auth == NULL ? NULL : &auth->host), host_name) < 0)
return -1;
if (parser->cur == parser->end)
return 1;
Expand Down Expand Up @@ -767,8 +793,10 @@ int uri_parse_authority(struct uri_parser *parser,
return 1;
}

int uri_parse_slashslash_authority(struct uri_parser *parser,
struct uri_authority *auth, bool dns_name)
static int
uri_do_parse_slashslash_authority(struct uri_parser *parser,
struct uri_authority *auth, bool host_name)
ATTR_NULL(2)
{
/* "//" authority */

Expand All @@ -777,7 +805,31 @@ int uri_parse_slashslash_authority(struct uri_parser *parser,
return 0;

parser->cur += 2;
return uri_parse_authority(parser, auth, dns_name);
return uri_do_parse_authority(parser, auth, host_name);
}

int uri_parse_authority(struct uri_parser *parser,
struct uri_authority *auth)
{
return uri_do_parse_authority(parser, auth, FALSE);
}

int uri_parse_slashslash_authority(struct uri_parser *parser,
struct uri_authority *auth)
{
return uri_do_parse_slashslash_authority(parser, auth, FALSE);
}

int uri_parse_host_authority(struct uri_parser *parser,
struct uri_authority *auth)
{
return uri_do_parse_authority(parser, auth, TRUE);
}

int uri_parse_slashslash_host_authority(struct uri_parser *parser,
struct uri_authority *auth)
{
return uri_do_parse_slashslash_authority(parser, auth, TRUE);
}

int uri_parse_path_segment(struct uri_parser *parser, const char **segment_r)
Expand Down
71 changes: 44 additions & 27 deletions src/lib/uri-util.h
Expand Up @@ -66,46 +66,63 @@ int uri_cut_scheme(const char **uri_p, const char **scheme_r)
int uri_parse_scheme(struct uri_parser *parser, const char **scheme_r)
ATTR_NULL(2);

/* parse a DNS host name. A host name is a sequence of domain name labels
separated by '.', as defined in Section 3.5 of RFC 1034 and Section
2.1 of RFC 1123. Returns 1 if successful, 0 if the first character is
not valid for a host name, and -1 in case of error. The result parameter
host_name_r can be NULL to use this function for merely checking the
presence of a valid host name. The result is allocated from the data
stack.
*/
int uri_parse_host_name_dns(struct uri_parser *parser,
/* parse the URI 'reg-name' syntax. Returns 1 if successful, 0 if the first
character is not valid for a host name, and -1 in case of error. The
result parameter reg_name_r can be NULL to use this function for merely
checking the presence of a valid host name. The result is allocated from
the data stack.
*/
int uri_parse_reg_name(struct uri_parser *parser,
const char **reg_name_r) ATTR_NULL(2);
/* parse the URI 'reg-name' part as an Internet host name, which is a
sequence of domain name labels separated by '.', as defined in
Section 3.5 of RFC 1034 and Section 2.1 of RFC 1123. Returns 1 if
successful, 0 if the first character is not valid for a host name,
and -1 in case of error. The result parameter host_name_r can be NULL
to use this function for merely checking the presence of a valid host
name. The result is allocated from the data stack.
*/
int uri_parse_host_name(struct uri_parser *parser,
const char **host_name_r) ATTR_NULL(2);
/* parse the URI 'host' syntax, which is either an IP address literal or
a registered (host) name. If dns_name is TRUE, this function expects
a host name, as defined in Section 3.5 of RFC 1034 and Section
2.1 of RFC 1123. Otherwise, a generic registered name syntax is allowed.
An IP address literal is always allowed. Returns 1 if successful, 0 if
the first character is not valid for a host name, and -1 in case of
error. The provided host struct is filled in with the parsed data, all
allocated from the parser pool. The host parameter can be NULL to use
this function for merely checking for valid 'host' syntax.
a an Internet host name, as defined in Section 3.5 of RFC 1034 and
Section 2.1 of RFC 1123. An IP address literal is always allowed.
Returns 1 if successful, 0 if the first character is not valid for a
host name, and -1 in case of error. The provided host struct is filled
in with the parsed data, all allocated from the parser pool. The host
parameter can be NULL to use this function for merely checking for
valid 'host' syntax.
*/
int uri_parse_host(struct uri_parser *parser,
struct uri_host *host, bool dns_name) ATTR_NULL(2);

/* parse the URI 'authority' syntax. If dns_name is TRUE, this function
expects a host name for the 'host' part, as defined in Section 3.5 of
RFC 1034 and Section 2.1 of RFC 1123. Otherwise, a generic registered
name syntax is allowed. Returns 1 if successful, 0 if the first
character is not valid for the 'authority' syntax and -1 in case of
error. The provided uri_authority struct is filled in with the parsed
struct uri_host *host) ATTR_NULL(2);

/* parse the URI 'authority' syntax. Returns 1 if successful, 0 if the
first character is not valid for the 'authority' syntax and -1 in case
of error. The provided uri_authority struct is filled in with the parsed
data, all allocated from the parser pool. The auth parameter can be
NULL to use this function for merely checking for valid 'authority'
syntax.
*/
int uri_parse_authority(struct uri_parser *parser,
struct uri_authority *auth, bool dns_name) ATTR_NULL(2);
struct uri_authority *auth) ATTR_NULL(2);
/* identical to uri_parse_authority(), except that this function parses
'"//" authority', rather than 'authority'.
*/
int uri_parse_slashslash_authority(struct uri_parser *parser,
struct uri_authority *auth, bool dns_name) ATTR_NULL(2);
struct uri_authority *auth) ATTR_NULL(2);
/* identical to uri_parse_authority(), except that this function parses
the registered name ('reg-name' syntax) as an Internet host name, as
defined in Section 3.5 of RFC 1034 and Section 2.1 of RFC 1123.
*/
int uri_parse_host_authority(struct uri_parser *parser,
struct uri_authority *auth) ATTR_NULL(2);
/* identical to uri_parse_slashslash_authority(), except that this
function parses the registered name ('reg-name' syntax) as an Internet
host name, as defined in Section 3.5 of RFC 1034 and Section 2.1 of
RFC 1123.
*/
int uri_parse_slashslash_host_authority(struct uri_parser *parser,
struct uri_authority *auth) ATTR_NULL(2);

/* parse the URI 'segment' syntax. Returns 1 if successful, 0 if the first
character is not valid for the 'segment' syntax and -1 in case of
Expand Down

0 comments on commit d3b0b5d

Please sign in to comment.