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

@ -41,16 +41,43 @@ extern "C" {
typedef struct {
char *scheme; /**< scheme */
char *userinfo; /**< userinfo */
char *host; /**< host */
/**
* @brief host part
*
* @note for IPv6 addresses, @ref host also includes the brackets
* '[' and ']' as well as the zoneid (with leading '%'), if
* present.
*/
char *host;
/**
* @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 @p scheme */
uint16_t userinfo_len; /**< length of @p userinfo */
uint16_t host_len; /**< length of @p host */
uint16_t port_len; /**< length of @p port */
uint16_t path_len; /**< length of @p path */
uint16_t query_len; /**< length of @p 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;
/**

View File

@ -133,6 +133,25 @@ static char *_consume_authority(uri_parser_result_t *result, char *uri,
if (ipv6_end >= authority_end) {
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 */
@ -145,6 +164,7 @@ static char *_consume_authority(uri_parser_result_t *result, char *uri,
(result->userinfo || result->port)) {
return NULL;
}
/* this includes the '/' */
return authority_end;
}

View File

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

View File

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