summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAli Fardan <raiz@stellarbound.space>2020-11-23 09:56:37 +0300
committerAli Fardan <raiz@stellarbound.space>2020-11-23 09:56:37 +0300
commitfaabb55313f176c52897cf63623ecb5b158ec46d (patch)
treefedc77d0be9f47c2e9459b4c83b08c661d8e4bcb
parent5a66aa1bbace4775025cd99a8ab0a8a18487dfe9 (diff)
downloadlibyuri-faabb55313f176c52897cf63623ecb5b158ec46d.tar.gz
decode: fix percent encoded first character parser bug
-rw-r--r--decode.c21
-rw-r--r--types.h13
2 files changed, 24 insertions, 10 deletions
diff --git a/decode.c b/decode.c
index 805ad3f..39f6f09 100644
--- a/decode.c
+++ b/decode.c
@@ -146,11 +146,12 @@ uri_decode(const char *text)
 
 		/* scan for userinfo */
 		cpy = ptr;
-		while (*ptr != '\0' && (_is_unreserved(*ptr) || _is_sub_delim(*ptr) || *ptr == ':')) {
-			ptr++;
+		while (*ptr != '\0' && _is_userinfo(*ptr)) {
 			/* skip pct-encoded */
 			if (*ptr == '%')
 				ptr += 2;
+			else
+				ptr++;
 		}
 		if (*ptr == '@') {
 			ret->authority.user = strndup(cpy, ptr-cpy);
@@ -235,11 +236,12 @@ uri_decode(const char *text)
 
 		/* not found? try name */
 		if (ret->authority.type == 0) {
-			while (*ptr != '\0' && (_is_unreserved(*ptr) || _is_sub_delim(*ptr))) {
-				ptr++;
+			while (*ptr != '\0' && (_is_unreserved(*ptr) || _is_sub_delim(*ptr) || *ptr == '%')) {
 				/* skip pct-encoded */
 				if (*ptr == '%')
 					ptr += 2;
+				else
+					ptr++;
 			}
 			if (*ptr != '\0' && *ptr != ':' && *ptr != '/' && *ptr != '?' && *ptr != '#') {
 				uri_free(ret);
@@ -273,11 +275,12 @@ uri_decode(const char *text)
 			if (*ptr == '/')
 				ptr++;
 			cpy = ptr;
-			while (*ptr != '\0' && (ret->scheme ? _is_segment(*ptr) : _is_segment_nc(*ptr))) {
-				ptr++;
+			while (*ptr != '\0' && ((ret->npath == 0 && ret->scheme == NULL) ? _is_segment_nc(*ptr) : _is_segment(*ptr))) {
 				/* skip pct-encoded */
 				if (*ptr == '%')
 					ptr += 2;
+				else
+					ptr++;
 			}
 			if (_uri_append_path(ret, cpy, ptr-cpy) == -1) {
 				uri_free(ret);
@@ -291,10 +294,11 @@ uri_decode(const char *text)
 		ptr++;
 		cpy = ptr;
 		while (*ptr != '\0' && (_is_pchar(*ptr) || *ptr == '/' || *ptr == '?')) {
-			ptr++;
 			/* skip pct-encoded */
 			if (*ptr == '%')
 				ptr += 2;
+			else
+				ptr++;
 		}
 		ret->query = strndup(cpy, ptr-cpy);
 		if (ret->query == NULL) {
@@ -308,10 +312,11 @@ uri_decode(const char *text)
 		ptr++;
 		cpy = ptr;
 		while (*ptr != '\0' && (_is_pchar(*ptr) || *ptr == '/' || *ptr == '?')) {
-			ptr++;
 			/* skip pct-encoded */
 			if (*ptr == '%')
 				ptr += 2;
+			else
+				ptr++;
 		}
 		ret->fragment = strndup(cpy, ptr-cpy);
 		if (ret->fragment == NULL) {
diff --git a/types.h b/types.h
index 03208d4..4bfc84b 100644
--- a/types.h
+++ b/types.h
@@ -102,7 +102,14 @@
 	(_is_unreserved(c) ||\
 	 _is_sub_delim(c)  ||\
 	 (c == ':')        ||\
-	 (c == '@'))
+	 (c == '@')        ||\
+	 (c == '%'))
+
+#define _is_userinfo(c)\
+	(_is_unreserved(c) ||\
+	 _is_sub_delim(c)  ||\
+	 (c == ':')        ||\
+	 (c == '%'))
 
 #define _is_segment(c)\
 	_is_pchar(c)
@@ -110,4 +117,6 @@
 #define _is_segment_nc(c)\
 	(_is_unreserved(c) ||\
 	 _is_sub_delim(c)  ||\
-	 (c == '@'))
+	 (c == '@')        ||\
+	 (c == '%'))
+