Merge pull request #15337 from cgundogan/pr/uri_parser_interfaces

uri_parser: extend for parsing interfaces in IPv6 addresses
This commit is contained in:
Martine Lenders 2020-11-12 11:16:52 +01:00 committed by GitHub
commit 37dd848c37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 153 additions and 18 deletions

View File

@ -39,18 +39,45 @@ extern "C" {
* @brief container that holds all results * @brief container that holds all results
*/ */
typedef struct { typedef struct {
char *scheme; /**< scheme */ char *scheme; /**< scheme */
char *userinfo; /**< userinfo */ char *userinfo; /**< userinfo */
char *host; /**< host */
char *port; /**< port */ /**
char *path; /**< path */ * @brief host part
char *query; /**< query */ *
uint16_t scheme_len; /**< length of @p scheme */ * @note for IPv6 addresses, @ref host also includes the brackets
uint16_t userinfo_len; /**< length of @p userinfo */ * '[' and ']' as well as the zoneid (with leading '%'), if
uint16_t host_len; /**< length of @p host */ * present.
uint16_t port_len; /**< length of @p port */ */
uint16_t path_len; /**< length of @p path */ char *host;
uint16_t query_len; /**< length of @p query */
/**
* @brief Pointer to the start of the address, if @ref host is an
* IPv6 address and NULL otherwise
*
* @note @ref ipv6addr does not include the brackets '[' and ']'
* and the zoneid part.
*/
char *ipv6addr;
/**
* @brief zoneid if @ref host is IPv6 address, NULL otherwise
*
* @see https://tools.ietf.org/html/rfc6874
*/
char *zoneid;
char *port; /**< port */
char *path; /**< path */
char *query; /**< query */
uint16_t scheme_len; /**< length of @ref scheme */
uint16_t userinfo_len; /**< length of @ref userinfo */
uint16_t host_len; /**< length of @ref host */
uint16_t ipv6addr_len; /**< length of @ref ipv6addr */
uint16_t zoneid_len; /**< length of @ref zoneid */
uint16_t port_len; /**< length of @ref port */
uint16_t path_len; /**< length of @ref path */
uint16_t query_len; /**< length of @ref query */
} uri_parser_result_t; } uri_parser_result_t;
/** /**

View File

@ -133,6 +133,25 @@ static char *_consume_authority(uri_parser_result_t *result, char *uri,
if (ipv6_end >= authority_end) { if (ipv6_end >= authority_end) {
return NULL; return NULL;
} }
char *zoneid_start = _strchrb(result->host, ipv6_end, '%');
if (zoneid_start) {
/* skip % */
result->zoneid = zoneid_start + 1;
result->zoneid_len = ipv6_end - result->zoneid;
/* zoneid cannot be empty */
if (result->zoneid_len == 0) {
return NULL;
}
}
/* remove '[', ']', and '%' zoneid from ipv6addr */
result->ipv6addr = result->host + 1;
result->ipv6addr_len = ipv6_end - result->ipv6addr;
if (result->zoneid) {
result->ipv6addr_len -= result->zoneid_len + 1;
}
} }
/* consume port, if available */ /* consume port, if available */
@ -145,6 +164,7 @@ static char *_consume_authority(uri_parser_result_t *result, char *uri,
(result->userinfo || result->port)) { (result->userinfo || result->port)) {
return NULL; return NULL;
} }
/* this includes the '/' */ /* this includes the '/' */
return authority_end; return authority_end;
} }

View File

@ -18,6 +18,9 @@ BOARD_INSUFFICIENT_MEMORY := \
bluepill \ bluepill \
bluepill-128kib \ bluepill-128kib \
calliope-mini \ calliope-mini \
cc1312-launchpad \
cc1352-launchpad \
cc1352p-launchpad \
cc2650-launchpad \ cc2650-launchpad \
cc2650stk \ cc2650stk \
derfmega128 \ derfmega128 \

View File

@ -21,9 +21,10 @@
#include "unittests-constants.h" #include "unittests-constants.h"
#include "tests-uri_parser.h" #include "tests-uri_parser.h"
#define VEC(u, f, s, us, h, po, pa, q, e) \ #define VEC(u, f, s, us, h, v6a, z, po, pa, q, e) \
{ .uri = u, .full_uri = f, .scheme = s, .userinfo = us, .host = h, \ { .uri = u, .full_uri = f, .scheme = s, .userinfo = us, .host = h, \
.port = po, .path = pa, .query = q, .expected = e} .ipv6addr = v6a, .zoneid = z, .port = po, .path = pa, \
.query = q, .expected = e}
#define VEC_CHECK(comp, i, vec_msg) \ #define VEC_CHECK(comp, i, vec_msg) \
do { \ do { \
@ -55,7 +56,9 @@ typedef struct {
bool full_uri; bool full_uri;
char scheme[8]; char scheme[8];
char userinfo[16]; char userinfo[16];
char host[16]; char host[24];
char ipv6addr[16];
char zoneid[8];
char port[32]; char port[32];
char path[48]; char path[48];
char query[32]; char query[32];
@ -67,9 +70,9 @@ typedef struct {
scheme, userinfo, host, port, scheme, userinfo, host, port,
path, query, expected return value) path, query, expected return value)
*/ */
static const validate_t validate_uris[27] = { static const validate_t validate_uris[] = {
/* uri to parse */ /* uri to parse */
VEC("coap://RIOT:test@[2001:db8::1]:5683/.well-known/core?v=1", VEC("coap://RIOT:test@[fe80:db8::1%tap0]:5683/.well-known/core?v=1",
/* is URI */ /* is URI */
true, true,
/* parsed scheme */ /* parsed scheme */
@ -77,7 +80,11 @@ static const validate_t validate_uris[27] = {
/* parsed userinfo */ /* parsed userinfo */
"RIOT:test", "RIOT:test",
/* parsed host */ /* parsed host */
"[2001:db8::1]", "[fe80:db8::1%tap0]",
/* parsed host without zoneid */
"fe80:db8::1",
/* parsed zoneid */
"tap0",
/* parsed port */ /* parsed port */
"5683", "5683",
/* parsed path */ /* parsed path */
@ -86,12 +93,36 @@ static const validate_t validate_uris[27] = {
"v=1", "v=1",
/* expected return value */ /* expected return value */
0), 0),
VEC("coap://RIOT:test@[fe80:db8::1%]:5683/.well-known/core?v=1",
true,
"coap",
"RIOT:test",
"[fe80:db8::1%]",
"fe80:db8::1",
"",
"5683",
"/.well-known/core",
"v=1",
-1),
VEC("coap://[fe80::1]/foo%20bar",
true,
"coap",
"",
"[fe80::1]",
"fe80::1",
"",
"",
"/foo%20bar",
"",
0),
VEC("/.well-known/core?v=1", VEC("/.well-known/core?v=1",
false, false,
"", "",
"", "",
"", "",
"", "",
"",
"",
"/.well-known/core", "/.well-known/core",
"v=1", "v=1",
0), 0),
@ -100,6 +131,8 @@ static const validate_t validate_uris[27] = {
"coap", "coap",
"R", "R",
"[2001:db8::1]", "[2001:db8::1]",
"2001:db8::1",
"",
"5own", "5own",
"/v=1", "/v=1",
"", "",
@ -109,6 +142,8 @@ static const validate_t validate_uris[27] = {
"coap", "coap",
"R", "R",
"[2001:db8::1]", "[2001:db8::1]",
"2001:db8::1",
"",
"5own", "5own",
"/:v=1", "/:v=1",
"", "",
@ -118,6 +153,8 @@ static const validate_t validate_uris[27] = {
"cap", "cap",
"R", "R",
"[2001:db8::1]", "[2001:db8::1]",
"2001:db8::1",
"",
"5own", "5own",
"/", "/",
"v=1", "v=1",
@ -127,6 +164,8 @@ static const validate_t validate_uris[27] = {
"oap", "oap",
"", "",
"Y2001:db8::1]", "Y2001:db8::1]",
"",
"",
"5own", "5own",
"/av=1", "/av=1",
"", "",
@ -137,6 +176,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"//Rb[ʰ00J:d/5v=0", "//Rb[ʰ00J:d/5v=0",
"", "",
0), 0),
@ -148,6 +189,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
-1), -1),
VEC("coap:///R@[2008::1]:5own//R@[2008::1]:5own/?v=1", VEC("coap:///R@[2008::1]:5own//R@[2008::1]:5own/?v=1",
true, true,
@ -155,6 +198,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"/R@[2008::1]:5own//R@[2008::1]:5own/", "/R@[2008::1]:5own//R@[2008::1]:5own/",
"v=1", "v=1",
0), 0),
@ -164,6 +209,8 @@ static const validate_t validate_uris[27] = {
"", "",
"R", "R",
"", "",
"",
"",
"/RZ[2001[8:01[8::1]:5o:1]:5oTMv=1", "/RZ[2001[8:01[8::1]:5o:1]:5oTMv=1",
"", "",
0), 0),
@ -175,6 +222,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
-1), -1),
VEC("coa[:////[2001:db5ow:5own/Ov=1", VEC("coa[:////[2001:db5ow:5own/Ov=1",
false, false,
@ -182,6 +231,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"coa[:////[2001:db5ow:5own/Ov=1", "coa[:////[2001:db5ow:5own/Ov=1",
"", "",
0), 0),
@ -191,6 +242,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"+1-816-555-1212", "+1-816-555-1212",
"", "",
0), 0),
@ -200,6 +253,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"+15105550101,+15105550102", "+15105550101,+15105550102",
"body=hello%20there", "body=hello%20there",
0), 0),
@ -209,6 +264,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"a", "a",
"", "",
0), 0),
@ -218,6 +275,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"test@example.com", "test@example.com",
"", "",
0), 0),
@ -227,6 +286,8 @@ static const validate_t validate_uris[27] = {
"", "",
"ftp.is.co.za", "ftp.is.co.za",
"", "",
"",
"",
"/rfc/rfc1808.txt", "/rfc/rfc1808.txt",
"", "",
0), 0),
@ -236,6 +297,8 @@ static const validate_t validate_uris[27] = {
"", "",
"www.ietf.org", "www.ietf.org",
"", "",
"",
"",
"/rfc/rfc2396.txt", "/rfc/rfc2396.txt",
"", "",
0), 0),
@ -244,6 +307,8 @@ static const validate_t validate_uris[27] = {
"ldap", "ldap",
"", "",
"[2001:db8::7]", "[2001:db8::7]",
"2001:db8::7",
"",
"", "",
"/c=GB", "/c=GB",
"objectClass?one", "objectClass?one",
@ -254,6 +319,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"John.Doe@example.com", "John.Doe@example.com",
"", "",
0), 0),
@ -263,6 +330,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"comp.infosystems.www.servers.unix", "comp.infosystems.www.servers.unix",
"", "",
0), 0),
@ -272,6 +341,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"+1-816-555-1212", "+1-816-555-1212",
"", "",
0), 0),
@ -280,6 +351,8 @@ static const validate_t validate_uris[27] = {
"telnet", "telnet",
"", "",
"192.0.2.16", "192.0.2.16",
"",
"",
"80", "80",
"/", "/",
"", "",
@ -290,6 +363,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"oasis:names:specification:docbook:dtd:xml:4.1.2", "oasis:names:specification:docbook:dtd:xml:4.1.2",
"", "",
0), 0),
@ -301,6 +376,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
-1), -1),
VEC("/", VEC("/",
false, false,
@ -308,6 +385,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"/", "/",
"", "",
0), 0),
@ -317,6 +396,8 @@ static const validate_t validate_uris[27] = {
"", "",
"", "",
"", "",
"",
"",
"./this:that", "./this:that",
"", "",
0), 0),
@ -336,6 +417,8 @@ static void test_uri_parser__validate(void)
VEC_CHECK(scheme, i, _failure_msg); VEC_CHECK(scheme, i, _failure_msg);
VEC_CHECK(userinfo, i, _failure_msg); VEC_CHECK(userinfo, i, _failure_msg);
VEC_CHECK(host, i, _failure_msg); VEC_CHECK(host, i, _failure_msg);
VEC_CHECK(ipv6addr, i, _failure_msg);
VEC_CHECK(zoneid, i, _failure_msg);
VEC_CHECK(port, i, _failure_msg); VEC_CHECK(port, i, _failure_msg);
VEC_CHECK(path, i, _failure_msg); VEC_CHECK(path, i, _failure_msg);
VEC_CHECK(query, i, _failure_msg); VEC_CHECK(query, i, _failure_msg);
@ -358,6 +441,8 @@ static void test_uri_parser__unterminated_string(void)
VEC_CHECK(scheme, 0, _failure_msg); VEC_CHECK(scheme, 0, _failure_msg);
VEC_CHECK(userinfo, 0, _failure_msg); VEC_CHECK(userinfo, 0, _failure_msg);
VEC_CHECK(host, 0, _failure_msg); VEC_CHECK(host, 0, _failure_msg);
VEC_CHECK(ipv6addr, 0, _failure_msg);
VEC_CHECK(zoneid, 0, _failure_msg);
VEC_CHECK(port, 0, _failure_msg); VEC_CHECK(port, 0, _failure_msg);
VEC_CHECK(path, 0, _failure_msg); VEC_CHECK(path, 0, _failure_msg);
VEC_CHECK(query, 0, _failure_msg); VEC_CHECK(query, 0, _failure_msg);