summary refs log tree commit diff stats
path: root/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'decode.c')
-rw-r--r--decode.c21
1 files changed, 13 insertions, 8 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) {