char **ppath, char **pquery, char **pfrag)
{
const char *p, *tmp;
+ const char *authority_end;
const char *scheme, *scheme_end;
const char *user, *user_end;
const char *host, *host_end;
/* parse optional "userinfo@" */
user = user_end = host = p;
- host = strchr(p, '@');
+ authority_end = strpbrk(p, "/?#");
+ if (authority_end == NULL)
+ authority_end = p + strlen(p);
+ host = memchr(p, '@', authority_end - p);
if (host != NULL)
user_end = host++;
else
return res;
}
+static int test_http_url_host_ok(const char *url, const char *exp_host)
+{
+ char *host;
+ int res;
+
+ res = TEST_true(OSSL_HTTP_parse_url(url, NULL, NULL, &host, NULL, NULL,
+ NULL, NULL, NULL))
+ && TEST_str_eq(host, exp_host);
+ OPENSSL_free(host);
+ return res;
+}
+
static int test_http_url_dns(void)
{
return test_http_url_ok("host:65535/path", 0, "host", "65535", "/path");
return test_http_url_ok("user:pass@host/p?q#fr", 0, "host", "80", "/p");
}
+static int test_http_url_at_sign_outside_authority(void)
+{
+ return test_http_url_host_ok("http://host/p@attacker.test", "host")
+ && test_http_url_host_ok("http://host/p?q=@attacker.test", "host")
+ && test_http_url_host_ok("http://host/p?q#fr@attacker.test", "host");
+}
+
static int test_http_url_ipv4(void)
{
return test_http_url_ok("https://1.2.3.4/p/q", 1, "1.2.3.4", "443", "/p/q");
ADD_TEST(test_http_url_timestamp);
ADD_TEST(test_http_url_path_query);
ADD_TEST(test_http_url_userinfo_query_fragment);
+ ADD_TEST(test_http_url_at_sign_outside_authority);
ADD_TEST(test_http_url_ipv4);
ADD_TEST(test_http_url_ipv6);
ADD_TEST(test_http_url_invalid_prefix);