mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-23 04:26:50 +03:00
Fix handling of bad mailto: urls.
svn path=/trunk/netsurf/; revision=13113
This commit is contained in:
parent
30ff09bd83
commit
04f6957141
@ -119,6 +119,17 @@ static bool nsurl__is_no_escape(unsigned char c)
|
|||||||
return no_escape[c];
|
return no_escape[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** nsurl scheme type */
|
||||||
|
enum scheme_type {
|
||||||
|
NSURL_SCHEME_OTHER,
|
||||||
|
NSURL_SCHEME_HTTP,
|
||||||
|
NSURL_SCHEME_HTTPS,
|
||||||
|
NSURL_SCHEME_FTP,
|
||||||
|
NSURL_SCHEME_MAILTO
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** nsurl components */
|
/** nsurl components */
|
||||||
struct nsurl_components {
|
struct nsurl_components {
|
||||||
lwc_string *scheme;
|
lwc_string *scheme;
|
||||||
@ -129,8 +140,11 @@ struct nsurl_components {
|
|||||||
lwc_string *path;
|
lwc_string *path;
|
||||||
lwc_string *query;
|
lwc_string *query;
|
||||||
lwc_string *fragment;
|
lwc_string *fragment;
|
||||||
|
|
||||||
|
enum scheme_type scheme_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NetSurf URL object
|
* NetSurf URL object
|
||||||
*
|
*
|
||||||
@ -161,6 +175,8 @@ struct url_markers {
|
|||||||
size_t fragment;
|
size_t fragment;
|
||||||
|
|
||||||
size_t end; /** end of URL */
|
size_t end; /** end of URL */
|
||||||
|
|
||||||
|
enum scheme_type scheme_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -233,7 +249,8 @@ static void nsurl__get_string_markers(const char const *url_s,
|
|||||||
bool trailing_whitespace = false;
|
bool trailing_whitespace = false;
|
||||||
|
|
||||||
/* Initialise marker set */
|
/* Initialise marker set */
|
||||||
struct url_markers marker = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
struct url_markers marker = { 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, NSURL_SCHEME_OTHER };
|
||||||
|
|
||||||
/* Skip any leading whitespace in url_s */
|
/* Skip any leading whitespace in url_s */
|
||||||
while (isspace(*pos))
|
while (isspace(*pos))
|
||||||
@ -267,7 +284,8 @@ static void nsurl__get_string_markers(const char const *url_s,
|
|||||||
|
|
||||||
off = marker.scheme_end - marker.start;
|
off = marker.scheme_end - marker.start;
|
||||||
|
|
||||||
/* Detect http(s) for scheme specifc normalisation */
|
/* Detect http(s) and mailto for scheme specifc
|
||||||
|
* normalisation */
|
||||||
if (off == SLEN("http") &&
|
if (off == SLEN("http") &&
|
||||||
(((*(pos - off + 0) == 'h') ||
|
(((*(pos - off + 0) == 'h') ||
|
||||||
(*(pos - off + 0) == 'H')) &&
|
(*(pos - off + 0) == 'H')) &&
|
||||||
@ -277,6 +295,7 @@ static void nsurl__get_string_markers(const char const *url_s,
|
|||||||
(*(pos - off + 2) == 'T')) &&
|
(*(pos - off + 2) == 'T')) &&
|
||||||
((*(pos - off + 3) == 'p') ||
|
((*(pos - off + 3) == 'p') ||
|
||||||
(*(pos - off + 3) == 'P')))) {
|
(*(pos - off + 3) == 'P')))) {
|
||||||
|
marker.scheme_type = NSURL_SCHEME_HTTP;
|
||||||
is_http = true;
|
is_http = true;
|
||||||
} else if (off == SLEN("https") &&
|
} else if (off == SLEN("https") &&
|
||||||
(((*(pos - off + 0) == 'h') ||
|
(((*(pos - off + 0) == 'h') ||
|
||||||
@ -287,9 +306,32 @@ static void nsurl__get_string_markers(const char const *url_s,
|
|||||||
(*(pos - off + 2) == 'T')) &&
|
(*(pos - off + 2) == 'T')) &&
|
||||||
((*(pos - off + 3) == 'p') ||
|
((*(pos - off + 3) == 'p') ||
|
||||||
(*(pos - off + 3) == 'P')) &&
|
(*(pos - off + 3) == 'P')) &&
|
||||||
((*(pos - off + 3) == 's') ||
|
((*(pos - off + 4) == 's') ||
|
||||||
(*(pos - off + 3) == 'S')))) {
|
(*(pos - off + 4) == 'S')))) {
|
||||||
|
marker.scheme_type = NSURL_SCHEME_HTTPS;
|
||||||
is_http = true;
|
is_http = true;
|
||||||
|
} else if (off == SLEN("https") &&
|
||||||
|
(((*(pos - off + 0) == 'f') ||
|
||||||
|
(*(pos - off + 0) == 'F')) &&
|
||||||
|
((*(pos - off + 1) == 't') ||
|
||||||
|
(*(pos - off + 1) == 'T')) &&
|
||||||
|
((*(pos - off + 2) == 'p') ||
|
||||||
|
(*(pos - off + 2) == 'P')))) {
|
||||||
|
marker.scheme_type = NSURL_SCHEME_FTP;
|
||||||
|
} else if (off == SLEN("mailto") &&
|
||||||
|
(((*(pos - off + 0) == 'm') ||
|
||||||
|
(*(pos - off + 0) == 'M')) &&
|
||||||
|
((*(pos - off + 1) == 'a') ||
|
||||||
|
(*(pos - off + 1) == 'A')) &&
|
||||||
|
((*(pos - off + 2) == 'i') ||
|
||||||
|
(*(pos - off + 2) == 'I')) &&
|
||||||
|
((*(pos - off + 3) == 'l') ||
|
||||||
|
(*(pos - off + 3) == 'L')) &&
|
||||||
|
((*(pos - off + 4) == 't') ||
|
||||||
|
(*(pos - off + 4) == 'T')) &&
|
||||||
|
((*(pos - off + 5) == 'o') ||
|
||||||
|
(*(pos - off + 5) == 'O')))) {
|
||||||
|
marker.scheme_type = NSURL_SCHEME_MAILTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip over colon */
|
/* Skip over colon */
|
||||||
@ -304,6 +346,7 @@ static void nsurl__get_string_markers(const char const *url_s,
|
|||||||
/* Not found a scheme */
|
/* Not found a scheme */
|
||||||
if (joining == false) {
|
if (joining == false) {
|
||||||
/* Assuming no scheme == http */
|
/* Assuming no scheme == http */
|
||||||
|
marker.scheme_type = NSURL_SCHEME_HTTP;
|
||||||
is_http = true;
|
is_http = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -316,11 +359,13 @@ static void nsurl__get_string_markers(const char const *url_s,
|
|||||||
* We are more relaxed in the case of http:
|
* We are more relaxed in the case of http:
|
||||||
* a. when joining, one or more slashes indicates start of authority
|
* a. when joining, one or more slashes indicates start of authority
|
||||||
* b. when not joining, we assume authority if no scheme was present
|
* b. when not joining, we assume authority if no scheme was present
|
||||||
|
* and in the case of mailto: when we assume there is an authority.
|
||||||
*/
|
*/
|
||||||
if ((*pos == '/' && *(pos + 1) == '/') ||
|
if ((*pos == '/' && *(pos + 1) == '/') ||
|
||||||
(is_http && ((joining && *pos == '/') ||
|
(is_http && ((joining && *pos == '/') ||
|
||||||
(joining == false &&
|
(joining == false &&
|
||||||
marker.scheme_end != marker.start)))) {
|
marker.scheme_end != marker.start))) ||
|
||||||
|
marker.scheme_type == NSURL_SCHEME_MAILTO) {
|
||||||
|
|
||||||
/* Skip over leading slashes */
|
/* Skip over leading slashes */
|
||||||
if (*pos == '/') {
|
if (*pos == '/') {
|
||||||
@ -853,13 +898,13 @@ static nserror nsurl__create_from_section(const char const *url_s,
|
|||||||
1 : 0;
|
1 : 0;
|
||||||
sec_start = norm_start + colon - pegs->at +
|
sec_start = norm_start + colon - pegs->at +
|
||||||
skip;
|
skip;
|
||||||
if (url->scheme != NULL && length -
|
if (url->scheme != NULL &&
|
||||||
|
url->scheme_type ==
|
||||||
|
NSURL_SCHEME_HTTP &&
|
||||||
|
length -
|
||||||
(colon - pegs->at + skip) == 2 &&
|
(colon - pegs->at + skip) == 2 &&
|
||||||
*sec_start == '8' &&
|
*sec_start == '8' &&
|
||||||
*(sec_start + 1) == '0' &&
|
*(sec_start + 1) == '0') {
|
||||||
strncmp(lwc_string_data(
|
|
||||||
url->scheme), "http",
|
|
||||||
SLEN("http")) == 0) {
|
|
||||||
/* Scheme is http, and port is default
|
/* Scheme is http, and port is default
|
||||||
* (80) */
|
* (80) */
|
||||||
flags |= NSURL_F_NO_PORT;
|
flags |= NSURL_F_NO_PORT;
|
||||||
@ -902,7 +947,8 @@ static nserror nsurl__create_from_section(const char const *url_s,
|
|||||||
&url->path) != lwc_error_ok) {
|
&url->path) != lwc_error_ok) {
|
||||||
return NSERROR_NOMEM;
|
return NSERROR_NOMEM;
|
||||||
}
|
}
|
||||||
} else if (url->host != NULL) {
|
} else if (url->host != NULL &&
|
||||||
|
url->scheme_type != NSURL_SCHEME_MAILTO) {
|
||||||
/* Set empty path to "/", if there's a host */
|
/* Set empty path to "/", if there's a host */
|
||||||
if (lwc_intern_string("/", SLEN("/"),
|
if (lwc_intern_string("/", SLEN("/"),
|
||||||
&url->path) != lwc_error_ok) {
|
&url->path) != lwc_error_ok) {
|
||||||
@ -1189,6 +1235,9 @@ nserror nsurl_create(const char const *url_s, nsurl **url)
|
|||||||
if (buff == NULL)
|
if (buff == NULL)
|
||||||
return NSERROR_NOMEM;
|
return NSERROR_NOMEM;
|
||||||
|
|
||||||
|
/* Set scheme type */
|
||||||
|
c.scheme_type = m.scheme_type;
|
||||||
|
|
||||||
/* Build NetSurf URL object from sections */
|
/* Build NetSurf URL object from sections */
|
||||||
e |= nsurl__create_from_section(url_s, URL_SCHEME, &m, buff, &c);
|
e |= nsurl__create_from_section(url_s, URL_SCHEME, &m, buff, &c);
|
||||||
e |= nsurl__create_from_section(url_s, URL_CREDENTIALS, &m, buff, &c);
|
e |= nsurl__create_from_section(url_s, URL_CREDENTIALS, &m, buff, &c);
|
||||||
@ -1598,11 +1647,16 @@ nserror nsurl_join(const nsurl *base, const char *rel, nsurl **joined)
|
|||||||
|
|
||||||
/* Form joined URL from base or rel components, as appropriate */
|
/* Form joined URL from base or rel components, as appropriate */
|
||||||
|
|
||||||
if (joined_parts & NSURL_F_BASE_SCHEME)
|
if (joined_parts & NSURL_F_BASE_SCHEME) {
|
||||||
|
c.scheme_type = base->components.scheme_type;
|
||||||
|
|
||||||
c.scheme = nsurl__component_copy(base->components.scheme);
|
c.scheme = nsurl__component_copy(base->components.scheme);
|
||||||
else
|
} else {
|
||||||
|
c.scheme_type = m.scheme_type;
|
||||||
|
|
||||||
error |= nsurl__create_from_section(rel, URL_SCHEME, &m,
|
error |= nsurl__create_from_section(rel, URL_SCHEME, &m,
|
||||||
buff, &c);
|
buff, &c);
|
||||||
|
}
|
||||||
|
|
||||||
if (joined_parts & NSURL_F_BASE_AUTHORITY) {
|
if (joined_parts & NSURL_F_BASE_AUTHORITY) {
|
||||||
c.username = nsurl__component_copy(base->components.username);
|
c.username = nsurl__component_copy(base->components.username);
|
||||||
@ -1756,6 +1810,8 @@ nserror nsurl_defragment(const nsurl *url, nsurl **no_frag)
|
|||||||
nsurl__component_copy(url->components.query);
|
nsurl__component_copy(url->components.query);
|
||||||
(*no_frag)->components.fragment = NULL;
|
(*no_frag)->components.fragment = NULL;
|
||||||
|
|
||||||
|
(*no_frag)->components.scheme_type = url->components.scheme_type;
|
||||||
|
|
||||||
(*no_frag)->length = length;
|
(*no_frag)->length = length;
|
||||||
|
|
||||||
/* Fill out the url string */
|
/* Fill out the url string */
|
||||||
@ -1827,6 +1883,8 @@ nserror nsurl_refragment(const nsurl *url, lwc_string *frag, nsurl **new_url)
|
|||||||
(*new_url)->components.fragment =
|
(*new_url)->components.fragment =
|
||||||
lwc_string_ref(frag);
|
lwc_string_ref(frag);
|
||||||
|
|
||||||
|
(*new_url)->components.scheme_type = url->components.scheme_type;
|
||||||
|
|
||||||
/* Give the URL a reference */
|
/* Give the URL a reference */
|
||||||
(*new_url)->count = 1;
|
(*new_url)->count = 1;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user