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:
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)