]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
uri-util: Added the possibility of only checking the URI without parsing any of the...
authorStephan Bosch <stephan@rename-it.nl>
Sat, 25 Apr 2015 09:42:06 +0000 (11:42 +0200)
committerStephan Bosch <stephan@rename-it.nl>
Sat, 25 Apr 2015 09:42:06 +0000 (11:42 +0200)
src/lib/uri-util.c
src/lib/uri-util.h

index 351e55848522bf723f98dd63b302a2eedc20a38a..42ef7b3ef0ed0b4ebca19820e7ddd9b5fd469632 100644 (file)
@@ -234,7 +234,8 @@ int uri_cut_scheme(const char **uri_p, const char **scheme_r)
        if (*p != ':')
                return -1;
        
-       *scheme_r = t_strdup_until(*uri_p, p);
+       if (scheme_r != NULL)
+               *scheme_r = t_strdup_until(*uri_p, p);
        *uri_p = p + 1;
        return 0;
 }
@@ -256,7 +257,7 @@ int uri_parse_scheme(struct uri_parser *parser, const char **scheme_r)
 
 static int
 uri_parse_dec_octet(struct uri_parser *parser, string_t *literal,
-                   uint8_t *octet_r)
+                   uint8_t *octet_r) ATTR_NULL(2)
 {
        unsigned int octet = 0;
        int count = 0;
@@ -291,7 +292,7 @@ uri_parse_dec_octet(struct uri_parser *parser, string_t *literal,
 
 static int
 uri_parse_ipv4address(struct uri_parser *parser, string_t *literal,
-                     struct in_addr *ip4_r)
+                     struct in_addr *ip4_r) ATTR_NULL(2,3)
 {
        uint8_t octet;
        uint32_t ip = 0;
@@ -325,7 +326,9 @@ uri_parse_ipv4address(struct uri_parser *parser, string_t *literal,
        return 1;
 }
 
-static int uri_parse_reg_name(struct uri_parser *parser, string_t *reg_name)
+static int
+uri_parse_reg_name(struct uri_parser *parser,
+       string_t *reg_name) ATTR_NULL(2)
 {
        /* RFC 3986:
         *
@@ -362,10 +365,11 @@ static int uri_parse_reg_name(struct uri_parser *parser, string_t *reg_name)
 #ifdef HAVE_IPV6
 static int
 uri_parse_ip_literal(struct uri_parser *parser, string_t *literal,
-                    struct in6_addr *ip6_r)
+                    struct in6_addr *ip6_r) ATTR_NULL(2,3)
 {
        const unsigned char *p;
        const char *address;
+       struct in6_addr ip6;
        int ret;
 
        /* IP-literal    = "[" ( IPv6address / IPvFuture  ) "]"
@@ -400,16 +404,20 @@ uri_parse_ip_literal(struct uri_parser *parser, string_t *literal,
                        "Future IP host address '%s' not supported", address);
                return -1;
        }
-       if ((ret = inet_pton(AF_INET6, address, ip6_r)) <= 0) {
+       if ((ret = inet_pton(AF_INET6, address, &ip6)) <= 0) {
                parser->error = t_strdup_printf(
                        "Invalid IPv6 host address '%s'", address);
                return -1;
        }
+       if (ip6_r != NULL)
+               *ip6_r = ip6;
        return 1;
 }
 #endif
 
-static int uri_parse_host(struct uri_parser *parser, struct uri_authority *auth)
+static int 
+uri_parse_host(struct uri_parser *parser,
+       struct uri_authority *auth) ATTR_NULL(2)
 {
        const unsigned char *preserve;
        struct in_addr ip4;
@@ -470,7 +478,9 @@ static int uri_parse_host(struct uri_parser *parser, struct uri_authority *auth)
        return 0;
 }
 
-static int uri_parse_port(struct uri_parser *parser, struct uri_authority *auth)
+static int
+uri_parse_port(struct uri_parser *parser,
+       struct uri_authority *auth) ATTR_NULL(2)
 {
        unsigned long port = 0;
        int count = 0;
@@ -612,7 +622,11 @@ int uri_parse_path(struct uri_parser *parser,
        int relative = 1;
        int ret;
 
-       t_array_init(&segments, 16);
+       count = 0;
+       if (path_r != NULL)
+               t_array_init(&segments, 16);
+       else
+               memset(&segments, 0, sizeof(segments));
 
        /* check for a leading '/' and indicate absolute path
           when it is present
@@ -636,9 +650,12 @@ int uri_parse_path(struct uri_parser *parser,
                                                segment = NULL;
 
                                                /* ... pop last segment (if any) */
-                                               count = array_count(&segments);
                                                if (count > 0) {
-                                                       array_delete(&segments, count-1, 1);
+                                                       if (path_r != NULL) {
+                                                               i_assert(count == array_count(&segments));
+                                                               array_delete(&segments, count-1, 1);
+                                                       }
+                                                       count--;
                                                } else if ( relative > 0 ) {
                                                        relative++;
                                                }
@@ -652,8 +669,11 @@ int uri_parse_path(struct uri_parser *parser,
                        segment = "";
                }
 
-               if (segment != NULL)
-                       array_append(&segments, &segment, 1);
+               if (segment != NULL) {
+                       if (path_r != NULL)
+                               array_append(&segments, &segment, 1);
+                       count++;
+               }
 
                if (parser->cur >= parser->end || *parser->cur != '/')
                        break;
@@ -664,22 +684,25 @@ int uri_parse_path(struct uri_parser *parser,
                        return -1;
        }
 
-       *path_r = NULL;
-       *relative_r = relative;
+       if (relative_r != NULL)
+               *relative_r = relative;
+       if (path_r != NULL)
+               *path_r = NULL;
 
        if (parser->cur == pbegin) {
                /* path part of URI is empty */
                return 0;
        }
 
-       /* special treatment for a trailing '..' or '.' */
-       if (segment == NULL) {
-               segment = "";
-               array_append(&segments, &segment, 1);
+       if (path_r != NULL) {
+               /* special treatment for a trailing '..' or '.' */
+               if (segment == NULL) {
+                       segment = "";
+                       array_append(&segments, &segment, 1);
+               }
+               array_append_zero(&segments);
+               *path_r = array_get(&segments, &count);
        }
-       array_append_zero(&segments);
-       *path_r = array_get(&segments, &count);
-
        if (parser->cur < parser->end &&
                *parser->cur != '?' && *parser->cur != '#') {
                parser->error = "Path component contains invalid character";
index e64c8ebabe51c6e0a39c734655b249138ae2fec8..b4bafd0ecb2c5e0fa85373b7b78187df9bca4215 100644 (file)
@@ -33,22 +33,30 @@ int uri_parse_unreserved(struct uri_parser *parser, string_t *part);
 bool uri_data_decode(struct uri_parser *parser, const char *data,
                     const char *until, const char **decoded_r) ATTR_NULL(3);
 
-int uri_cut_scheme(const char **uri_p, const char **scheme_r);
-int uri_parse_scheme(struct uri_parser *parser, const char **scheme_r);
+int uri_cut_scheme(const char **uri_p, const char **scheme_r)
+       ATTR_NULL(2);
+int uri_parse_scheme(struct uri_parser *parser, const char **scheme_r)
+       ATTR_NULL(2);
 int uri_parse_authority(struct uri_parser *parser,
-       struct uri_authority *auth);
+       struct uri_authority *auth)      ATTR_NULL(2);
 int uri_parse_slashslash_authority(struct uri_parser *parser,
-       struct uri_authority *auth);
+       struct uri_authority *auth) ATTR_NULL(2);
 
-int uri_parse_path_segment(struct uri_parser *parser, const char **segment_r);
+int uri_parse_path_segment(struct uri_parser *parser,
+       const char **segment_r) ATTR_NULL(2);
 int uri_parse_path(struct uri_parser *parser, int *relative_r,
-                  const char *const **path_r);
+                  const char *const **path_r) ATTR_NULL(2,3);
 
-int uri_parse_query(struct uri_parser *parser, const char **query_r);
-int uri_parse_fragment(struct uri_parser *parser, const char **fragment_r);
+int uri_parse_query(struct uri_parser *parser,
+       const char **query_r) ATTR_NULL(2);
+int uri_parse_fragment(struct uri_parser *parser,
+       const char **fragment_r) ATTR_NULL(2);
+
+void uri_parser_init(struct uri_parser *parser, pool_t pool,
+       const char *data);
+string_t *uri_parser_get_tmpbuf(struct uri_parser *parser,
+       size_t size);
 
-void uri_parser_init(struct uri_parser *parser, pool_t pool, const char *data);
-string_t *uri_parser_get_tmpbuf(struct uri_parser *parser, size_t size);
 
 /*
  * Generic URI construction