hare

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

commit cb2d3b21a75864d7cebc4d85b54741ba9512e24a
parent 0367c5c9a256d999d24bd4bda46ca1901c1ff119
Author: Alexey Yerin <yyp@disroot.org>
Date:   Thu, 11 Jul 2024 15:27:42 +0300

net::uri: Clean up memory handling after failure

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

Diffstat:
Mnet/uri/parse.ha | 36++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/net/uri/parse.ha b/net/uri/parse.ha @@ -12,13 +12,6 @@ use strings; // The URI provided to [[parse]] is invalid. export type invalid = !void; -fn free_non_empty(in: (str | ip::addr6)) void = { - match (in) { - case let s: str => if (len(s) > 0) free(s); - case => void; - }; -}; - // Parses a URI string into [[uri]] structure. The return value must be freed // using [[finish]]. export fn parse(in: str) (uri | invalid) = { @@ -32,9 +25,11 @@ export fn parse(in: str) (uri | invalid) = { let path = ""; let authority: ((str | ip::addr6), u16, str) = ("", 0u16, ""); defer if (!success) { - free_non_empty(authority.0); - free_non_empty(authority.2); + free(path); + free_host(authority.0); + free(authority.2); }; + match (strings::next(&in)) { case let r: rune => switch (r) { @@ -82,6 +77,7 @@ export fn parse(in: str) (uri | invalid) = { }; let query = ""; + defer if (!success) free(query); match (strings::next(&in)) { case let r: rune => if (r == '?') { @@ -162,7 +158,10 @@ fn parse_authority( let port = 0u16; let userinfo = ""; let has_userinfo = false; - let want_port = false; + defer if (!success) { + free_host(host); + free(userinfo); + }; for (let r => strings::next(in)) { if (r == '[') { @@ -200,7 +199,6 @@ fn parse_authority( }; // This was userinfo+host[+port] userinfo = percent_decode(memio::string(&buf)!)?; - defer if (!success) free(userinfo); memio::reset(&buf); has_userinfo = true; case '/' => @@ -211,7 +209,7 @@ fn parse_authority( case ':' => // This was host+port host = percent_decode(memio::string(&buf)!)?; - want_port = true; + port = parse_port(in)?; break; case => return invalid; @@ -221,12 +219,6 @@ fn parse_authority( }; }; - defer if (!success) free_non_empty(host); - - if (want_port) { - port = parse_port(in)?; - }; - match (host) { case let s: str => // In end of string case @@ -401,6 +393,14 @@ fn wantrune(iter: *strings::iterator) (rune | invalid) = { }; }; +fn free_host(in: (str | ip::addr6)) void = { + match (in) { + case let s: str => + free(s); + case => void; + }; +}; + fn is_userinfo(r: rune) bool = // unreserved + sub-delim + ":" ascii::isalnum(r) || strings::contains("-._~!$&'()*+,;=:", r)