From faabb55313f176c52897cf63623ecb5b158ec46d Mon Sep 17 00:00:00 2001 From: Ali Fardan Date: Mon, 23 Nov 2020 09:56:37 +0300 Subject: decode: fix percent encoded first character parser bug --- decode.c | 21 +++++++++++++-------- types.h | 13 +++++++++++-- 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 == '%')) + -- cgit 1.4.1-2-gfad0