|
| 1 | +From ed0c7c7e0e8f7298352646b2fd6e06a11e242ace Mon Sep 17 00:00:00 2001 |
| 2 | +From: =?UTF-8?q?Tim=20R=C3=BChsen?= <tim.ruehsen@gmx.de> |
| 3 | +Date: Sun, 2 Jun 2024 12:40:16 +0200 |
| 4 | +Subject: [PATCH] Properly re-implement userinfo parsing (rfc2396) |
| 5 | + |
| 6 | +* src/url.c (url_skip_credentials): Properly re-implement userinfo parsing (rfc2396) |
| 7 | + |
| 8 | +The reason why the implementation is based on RFC 2396, an outdated standard, |
| 9 | +is that the whole file is based on that RFC, and mixing standard here might be |
| 10 | +dangerous. |
| 11 | +--- |
| 12 | + src/url.c | 40 ++++++++++++++++++++++++++++++++++------ |
| 13 | + 1 file changed, 34 insertions(+), 6 deletions(-) |
| 14 | + |
| 15 | +diff --git a/src/url.c b/src/url.c |
| 16 | +index 69e948b00..07c3bc876 100644 |
| 17 | +--- a/src/url.c |
| 18 | ++++ b/src/url.c |
| 19 | +@@ -41,6 +41,7 @@ as that of the covered work. */ |
| 20 | + #include "url.h" |
| 21 | + #include "host.h" /* for is_valid_ipv6_address */ |
| 22 | + #include "c-strcase.h" |
| 23 | ++#include "c-ctype.h" |
| 24 | + |
| 25 | + #ifdef HAVE_ICONV |
| 26 | + # include <iconv.h> |
| 27 | +@@ -526,12 +527,39 @@ scheme_leading_string (enum url_scheme scheme) |
| 28 | + static const char * |
| 29 | + url_skip_credentials (const char *url) |
| 30 | + { |
| 31 | +- /* Look for '@' that comes before terminators, such as '/', '?', |
| 32 | +- '#', or ';'. */ |
| 33 | +- const char *p = (const char *)strpbrk (url, "@/?#;"); |
| 34 | +- if (!p || *p != '@') |
| 35 | +- return url; |
| 36 | +- return p + 1; |
| 37 | ++ /* |
| 38 | ++ * This whole file implements https://www.rfc-editor.org/rfc/rfc2396 . |
| 39 | ++ * RFC 2396 is outdated since 2005 and needs a rewrite or a thorough re-visit. |
| 40 | ++ * |
| 41 | ++ * The RFC says |
| 42 | ++ * server = [ [ userinfo "@" ] hostport ] |
| 43 | ++ * userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" | "+" | "$" | "," ) |
| 44 | ++ * unreserved = alphanum | mark |
| 45 | ++ * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" |
| 46 | ++ */ |
| 47 | ++ static const char *allowed = "-_.!~*'();:&=+$,"; |
| 48 | ++ |
| 49 | ++ for (const char *p = url; *p; p++) |
| 50 | ++ { |
| 51 | ++ if (c_isalnum(*p)) |
| 52 | ++ continue; |
| 53 | ++ |
| 54 | ++ if (strchr(allowed, *p)) |
| 55 | ++ continue; |
| 56 | ++ |
| 57 | ++ if (*p == '%' && c_isxdigit(p[1]) && c_isxdigit(p[2])) |
| 58 | ++ { |
| 59 | ++ p += 2; |
| 60 | ++ continue; |
| 61 | ++ } |
| 62 | ++ |
| 63 | ++ if (*p == '@') |
| 64 | ++ return p + 1; |
| 65 | ++ |
| 66 | ++ break; |
| 67 | ++ } |
| 68 | ++ |
| 69 | ++ return url; |
| 70 | + } |
| 71 | + |
| 72 | + /* Parse credentials contained in [BEG, END). The region is expected |
0 commit comments