mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-22 14:31:20 +03:00
improve nsurl query handling.
Alter the handling of query values within nsurl to be like fragments. This ensures callers never have to care about the query punctuation, e.g. the question mark This also means the strings generated will no longer have trailing question marks which now conforms to behaviour in whatwg url spec on url serializing in section 4.5
This commit is contained in:
parent
83512a6ff5
commit
9100fcb409
26
test/nsurl.c
26
test/nsurl.c
@ -428,9 +428,9 @@ static const struct test_pairs join_tests[] = {
|
||||
{ " ", "http://a/b/c/d;p?q" },
|
||||
{ "/", "http://a/" },
|
||||
{ " / ", "http://a/" },
|
||||
{ " ? ", "http://a/b/c/d;p?" },
|
||||
{ " ? ", "http://a/b/c/d;p" },
|
||||
{ " h ", "http://a/b/c/h" },
|
||||
{ "//foo?", "http://foo/?" },
|
||||
{ "//foo?", "http://foo/" },
|
||||
{ "//foo#bar", "http://foo/#bar" },
|
||||
{ "//foo/", "http://foo/" },
|
||||
{ "http://<!--#echo var=", "http://<!--/#echo%20var="},
|
||||
@ -531,21 +531,25 @@ END_TEST
|
||||
*/
|
||||
static const struct test_triplets replace_query_tests[] = {
|
||||
{ "http://netsurf-browser.org/?magical=true",
|
||||
"?magical=true&result=win",
|
||||
"magical=true&result=win",
|
||||
"http://netsurf-browser.org/?magical=true&result=win"},
|
||||
|
||||
{ "http://netsurf-browser.org/?magical=true#fragment",
|
||||
"?magical=true&result=win",
|
||||
"magical=true&result=win",
|
||||
"http://netsurf-browser.org/?magical=true&result=win#fragment"},
|
||||
|
||||
{ "http://netsurf-browser.org/#fragment",
|
||||
"?magical=true&result=win",
|
||||
"magical=true&result=win",
|
||||
"http://netsurf-browser.org/?magical=true&result=win#fragment"},
|
||||
|
||||
{ "http://netsurf-browser.org/path",
|
||||
"?magical=true",
|
||||
"magical=true",
|
||||
"http://netsurf-browser.org/path?magical=true"},
|
||||
|
||||
{ "http://netsurf-browser.org/path?magical=true",
|
||||
"",
|
||||
"http://netsurf-browser.org/path"},
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -655,7 +659,7 @@ static const struct test_compare component_tests[] = {
|
||||
{ "http://u:p@a:66/b/c/d;p?q#f", "a", NSURL_HOST, true },
|
||||
{ "http://u:p@a:66/b/c/d;p?q#f", "66", NSURL_PORT, true },
|
||||
{ "http://u:p@a:66/b/c/d;p?q#f", "/b/c/d;p", NSURL_PATH, true },
|
||||
{ "http://u:p@a:66/b/c/d;p?q#f", "?q", NSURL_QUERY, true },
|
||||
{ "http://u:p@a:66/b/c/d;p?q#f", "q", NSURL_QUERY, true },
|
||||
{ "http://u:p@a:66/b/c/d;p?q#f", "f", NSURL_FRAGMENT, true },
|
||||
|
||||
{ "file:", "file", NSURL_SCHEME, true },
|
||||
@ -667,6 +671,11 @@ static const struct test_compare component_tests[] = {
|
||||
{ "file:", NULL, NSURL_QUERY, false },
|
||||
{ "file:", NULL, NSURL_FRAGMENT, false },
|
||||
|
||||
{ "http://u:p@a:66/b/c/d;p?q=v#f", "q=v", NSURL_QUERY, true },
|
||||
{ "http://u:p@a:66/b/c/d;p?q=v", "q=v", NSURL_QUERY, true },
|
||||
{ "http://u:p@a:66/b/c/d;p?q=v&q1=v1#f", "q=v&q1=v1", NSURL_QUERY, true },
|
||||
{ "http://u:p@a:66/b/c/d;p?q=v&q1=v1", "q=v&q1=v1", NSURL_QUERY, true },
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1167,12 +1176,11 @@ START_TEST(nsurl_api_assert_replace_query3_test)
|
||||
nsurl *url;
|
||||
nsurl *res;
|
||||
nserror err;
|
||||
const char *rel = "moo";
|
||||
|
||||
err = nsurl_create(base_str, &url);
|
||||
ck_assert(err == NSERROR_OK);
|
||||
|
||||
err = nsurl_replace_query(url, rel, &res);
|
||||
err = nsurl_replace_query(url, NULL, &res);
|
||||
ck_assert(err != NSERROR_OK);
|
||||
|
||||
nsurl_unref(url);
|
||||
|
@ -313,6 +313,9 @@ nserror nsurl_refragment(const nsurl *url, lwc_string *frag, nsurl **new_url);
|
||||
* the created object.
|
||||
*
|
||||
* Any query component in url is replaced with query in new_url.
|
||||
*
|
||||
* Passing the empty string as a replacement will result in the query
|
||||
* component being removed.
|
||||
*/
|
||||
nserror nsurl_replace_query(const nsurl *url, const char *query,
|
||||
nsurl **new_url);
|
||||
|
@ -574,57 +574,67 @@ nserror nsurl_refragment(const nsurl *url, lwc_string *frag, nsurl **new_url)
|
||||
nserror nsurl_replace_query(const nsurl *url, const char *query,
|
||||
nsurl **new_url)
|
||||
{
|
||||
int query_len; /* Length of new query string, including '?' */
|
||||
int frag_len = 0; /* Length of fragment, including '#' */
|
||||
int query_len; /* Length of new query string excluding '?' */
|
||||
int frag_len = 0; /* Length of fragment, excluding '#' */
|
||||
int base_len; /* Length of URL up to start of query */
|
||||
char *pos;
|
||||
size_t len;
|
||||
lwc_string *lwc_query;
|
||||
char *pos; /* current position in output string */
|
||||
size_t length; /* new url string length */
|
||||
lwc_string *lwc_query = NULL;
|
||||
|
||||
assert(url != NULL);
|
||||
assert(query != NULL);
|
||||
assert(query[0] == '?');
|
||||
|
||||
/* Get the length of the new query */
|
||||
query_len = strlen(query);
|
||||
length = query_len = strlen(query);
|
||||
if (query_len > 0) {
|
||||
length++; /* allow for '?' */
|
||||
|
||||
/* intern string */
|
||||
if (lwc_intern_string(query,
|
||||
query_len,
|
||||
&lwc_query) != lwc_error_ok) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the change in length from url to new_url */
|
||||
base_len = url->length;
|
||||
if (url->components.query != NULL) {
|
||||
base_len -= lwc_string_length(url->components.query);
|
||||
base_len -= (1 + lwc_string_length(url->components.query));
|
||||
}
|
||||
if (url->components.fragment != NULL) {
|
||||
frag_len = 1 + lwc_string_length(url->components.fragment);
|
||||
base_len -= frag_len;
|
||||
frag_len = lwc_string_length(url->components.fragment);
|
||||
base_len -= (1 + frag_len);
|
||||
length += frag_len + 1; /* allow for '#' */
|
||||
}
|
||||
|
||||
/* Set new_url's length */
|
||||
len = base_len + query_len + frag_len;
|
||||
/* compute new url string length */
|
||||
length += base_len;
|
||||
|
||||
/* Create NetSurf URL object */
|
||||
*new_url = malloc(sizeof(nsurl) + len + 1); /* Add 1 for \0 */
|
||||
*new_url = malloc(sizeof(nsurl) + length + 1); /* Add 1 for \0 */
|
||||
if (*new_url == NULL) {
|
||||
if (query_len > 0) {
|
||||
lwc_string_unref(lwc_query);
|
||||
}
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
if (lwc_intern_string(query, query_len, &lwc_query) != lwc_error_ok) {
|
||||
free(*new_url);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
(*new_url)->length = len;
|
||||
(*new_url)->length = length;
|
||||
|
||||
/* Set string */
|
||||
pos = (*new_url)->string;
|
||||
memcpy(pos, url->string, base_len);
|
||||
pos += base_len;
|
||||
memcpy(pos, query, query_len);
|
||||
if (query_len > 0) {
|
||||
*pos = '?';
|
||||
memcpy(++pos, query, query_len);
|
||||
pos += query_len;
|
||||
}
|
||||
if (url->components.fragment != NULL) {
|
||||
const char *frag = lwc_string_data(url->components.fragment);
|
||||
*pos = '#';
|
||||
memcpy(++pos, frag, frag_len - 1);
|
||||
pos += frag_len - 1;
|
||||
memcpy(++pos, frag, frag_len);
|
||||
pos += frag_len;
|
||||
}
|
||||
*pos = '\0';
|
||||
|
||||
@ -945,4 +955,3 @@ nserror nsurl_parent(const nsurl *url, nsurl **new_url)
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -671,7 +671,9 @@ static nserror nsurl__create_from_section(const char * const url_s,
|
||||
break;
|
||||
|
||||
case URL_QUERY:
|
||||
start = pegs->query;
|
||||
start = (*(url_s + pegs->query) != '?') ?
|
||||
pegs->query :
|
||||
pegs->query + 1;
|
||||
end = pegs->fragment;
|
||||
break;
|
||||
|
||||
@ -1085,6 +1087,15 @@ static void nsurl__get_string_data(const struct nsurl_components *url,
|
||||
*url_l += SLEN("@");
|
||||
}
|
||||
|
||||
/* spanned query question mark */
|
||||
if ((flags & ~(NSURL_F_QUERY | NSURL_F_FRAGMENT)) &&
|
||||
(flags & NSURL_F_QUERY)) {
|
||||
flags |= NSURL_F_QUERY_PUNCTUATION;
|
||||
|
||||
*url_l += SLEN("?");
|
||||
}
|
||||
|
||||
/* spanned fragment hash mark */
|
||||
if ((flags & ~NSURL_F_FRAGMENT) && (flags & NSURL_F_FRAGMENT)) {
|
||||
flags |= NSURL_F_FRAGMENT_PUNCTUATION;
|
||||
|
||||
@ -1158,6 +1169,8 @@ static void nsurl__get_string(const struct nsurl_components *url, char *url_s,
|
||||
}
|
||||
|
||||
if (flags & NSURL_F_QUERY) {
|
||||
if (flags & NSURL_F_QUERY_PUNCTUATION)
|
||||
*(pos++) = '?';
|
||||
memcpy(pos, lwc_string_data(url->query), l->query);
|
||||
pos += l->query;
|
||||
}
|
||||
@ -1557,4 +1570,3 @@ nserror nsurl_join(const nsurl *base, const char *rel, nsurl **joined)
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -105,9 +105,10 @@ enum nsurl_string_flags {
|
||||
NSURL_F_HOST |
|
||||
NSURL_F_PORT),
|
||||
NSURL_F_PATH = (1 << 8),
|
||||
NSURL_F_QUERY = (1 << 9),
|
||||
NSURL_F_FRAGMENT_PUNCTUATION = (1 << 10),
|
||||
NSURL_F_FRAGMENT = (1 << 11)
|
||||
NSURL_F_QUERY_PUNCTUATION = (1 << 9),
|
||||
NSURL_F_QUERY = (1 << 10),
|
||||
NSURL_F_FRAGMENT_PUNCTUATION = (1 << 11),
|
||||
NSURL_F_FRAGMENT = (1 << 12)
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user