hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 95115695179fe1ad1f0c3d09c8cf400d77970d2d
parent be5e0d5a705ef7314dadc4795d3ec5f0be443c5f
Author: Alexey Yerin <yyp@disroot.org>
Date:   Wed, 22 Feb 2023 15:36:09 +0300

net::uri: disallow '@' after seeing userinfo

A boolean is used instead of len(userinfo)>0 to also catch a provided,
but empty userinfo part like this:

    https://@example

Adding another '@' here should be still invalid.

Signed-off-by: Alexey Yerin <yyp@disroot.org>

Diffstat:
Mnet/uri/+test.ha | 4++++
Mnet/uri/parse.ha | 8+++++---
2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/uri/+test.ha b/net/uri/+test.ha @@ -103,6 +103,10 @@ use net::ip; // Something other than IPv6 address inside [ ... ] assert(parse("https://[1.2.3.4]") is invalid); assert(parse("https://[example]") is invalid); + + // '@' in userinfo + assert(parse("https://a@b@example") is invalid); + assert(parse("https://@@example") is invalid); }; @test fn percent_encoding() void = { diff --git a/net/uri/parse.ha b/net/uri/parse.ha @@ -137,6 +137,7 @@ fn parse_authority( let host: (str | ip::addr6) = ""; let port = 0u16; let userinfo = ""; + let has_userinfo = false; for (true) { const r = match (strings::next(in)) { @@ -173,14 +174,15 @@ fn parse_authority( return invalid; }; } else if (r == ':' || !is_userinfo(r) && !is_host(r)) { - if (len(userinfo) > 0 && is_userinfo(r)) { - return invalid; - }; switch (r) { case '@' => + if (has_userinfo) { + return invalid; + }; // This was userinfo+host[+port] userinfo = percent_decode(strio::string(&buf))?; strio::reset(&buf); + has_userinfo = true; case '/' => // This was just host strings::prev(in);