diff options
author | Omar Polo <op@omarpolo.com> | 2024-05-29 08:52:25 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2024-05-29 08:52:25 +0000 |
commit | b00f71ba97cf4448446fc5ccf715ca0dfda3a93b (patch) | |
tree | 9e9fdb9892c4079ebcbad7305c11df61e912003a | |
parent | 6ff8de1f8a389dd6b0de7e442ba95ccfe2734484 (diff) |
iri: add support for raw IPv6 addresses
-rw-r--r-- | iri.c | 48 | ||||
-rw-r--r-- | regress/iri_test.c | 8 |
2 files changed, 43 insertions, 13 deletions
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Omar Polo <op@omarpolo.com> + * Copyright (c) 2020, 2022, 2024 Omar Polo <op@omarpolo.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -177,25 +177,47 @@ parse_port(struct parser *p) return 1; } -/* TODO: add support for ip-literal and ipv4addr ? */ /* *( unreserved / sub-delims / pct-encoded ) */ static int parse_authority(struct parser *p) { - p->parsed->host = p->iri; + struct addrinfo hints, *ai; + char *end; + int err; - while (unreserved(*p->iri) - || sub_delimiters(*p->iri) - || parse_pct_encoded(p) - || valid_multibyte_utf8(p)) { - /* normalize the host name. */ - if (*p->iri < 0x7F) - *p->iri = tolower(*p->iri); + if (*p->iri == '[') { p->iri++; - } + p->parsed->host = p->iri; + if ((end = strchr(p->iri, ']')) == NULL) { + p->err = "invalid IPv6 address"; + return 0; + } + *end++ = '\0'; + p->iri = end; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_NUMERICHOST; + err = getaddrinfo(p->parsed->host, NULL, &hints, &ai); + if (err != 0) { + p->err = "invalid IPv6 address"; + return 0; + } + freeaddrinfo(ai); + } else { + p->parsed->host = p->iri; + while (unreserved(*p->iri) + || sub_delimiters(*p->iri) + || parse_pct_encoded(p) + || valid_multibyte_utf8(p)) { + /* normalize the host name. */ + if (*p->iri < 0x7F) + *p->iri = tolower(*p->iri); + p->iri++; + } - if (p->err != NULL) - return 0; + if (p->err != NULL) + return 0; + } if (*p->iri == ':') { *p->iri = '\0'; diff --git a/regress/iri_test.c b/regress/iri_test.c index 32d40a8..fa6d578 100644 --- a/regress/iri_test.c +++ b/regress/iri_test.c @@ -162,6 +162,14 @@ main(void) PASS, IRI("gemini", "naïve.omarpolo.com", "", "", "", ""), "Can percent decode hostnames"); + TEST("gemini://100.64.3.27/", + PASS, + IRI("gemini", "100.64.3.27", "", "", "", ""), + "Accepts IPv4 addresses"); + TEST("gemini://[::1]/", + PASS, + IRI("gemini", "::1", "", "", "", ""), + "Accepts IPv6 addresses"); /* path */ TEST("gemini://omarpolo.com/foo/bar/baz", |