From f02261b71dc27edc6cf9bd241262dbd0923a1a3e Mon Sep 17 00:00:00 2001 From: anmartan Date: Thu, 4 Jul 2024 09:30:02 +0200 Subject: [PATCH] core: Improved URN parsing according to RFC8141 - Improved URN parsing to allow consuming URNs that contain 3 or more colons. Previosly URI parser treated some of the colons as separator between host and port causing the URN parsing to fail. --- src/core/parser/parse_uri.c | 53 +++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/core/parser/parse_uri.c b/src/core/parser/parse_uri.c index 9ccb62ee51e2..026bb0c624d8 100644 --- a/src/core/parser/parse_uri.c +++ b/src/core/parser/parse_uri.c @@ -186,6 +186,7 @@ int parse_uri(char *buf, int len, struct sip_uri *uri) char *end; char *pass; int found_user; + int found_host; int error_headers; uint32_t scheme; uri_type backup_urit; @@ -237,28 +238,33 @@ int parse_uri(char *buf, int len, struct sip_uri *uri) } else \ goto error_bad_char -#define check_host_end \ - case ':': \ - /* found the host */ \ - uri->host.s = s; \ - uri->host.len = p - s; \ - state = URI_PORT; \ - s = p + 1; \ - break; \ - case ';': \ - uri->host.s = s; \ - uri->host.len = p - s; \ - state = URI_PARAM; \ - s = p + 1; \ - break; \ - case '?': \ - uri->host.s = s; \ - uri->host.len = p - s; \ - state = URI_HEADERS; \ - s = p + 1; \ - break; \ - case '&': \ - case '@': \ +#define check_host_end \ + case ':': \ + /* found the host */ \ + if(scheme != URN_SCH || found_host == 0) { \ + uri->host.s = s; \ + found_host = 1; \ + } \ + uri->host.len = p - uri->host.s; \ + if(scheme != URN_SCH) { \ + state = URI_PORT; \ + s = p + 1; \ + } \ + break; \ + case ';': \ + uri->host.s = s; \ + uri->host.len = p - s; \ + state = URI_PARAM; \ + s = p + 1; \ + break; \ + case '?': \ + uri->host.s = s; \ + uri->host.len = p - s; \ + state = URI_HEADERS; \ + s = p + 1; \ + break; \ + case '&': \ + case '@': \ goto error_bad_char @@ -445,6 +451,7 @@ int parse_uri(char *buf, int len, struct sip_uri *uri) end = buf + len; p = buf + 4; found_user = 0; + found_host = 0; error_headers = 0; b = v = 0; param = param_val = 0; @@ -493,7 +500,7 @@ int parse_uri(char *buf, int len, struct sip_uri *uri) case '@': /* error no user part, or * be forgiving and accept it ? */ default: - state = URI_USER; + state = (scheme == URN_SCH) ? URI_HOST : URI_USER; } break; case URI_USER: