Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/5c96acd6f119b71fc75e5...
...commit
http://git.netsurf-browser.org/netsurf.git/commit/5c96acd6f119b71fc75e5d4...
...tree
http://git.netsurf-browser.org/netsurf.git/tree/5c96acd6f119b71fc75e5d484...
The branch, master has been updated
via 5c96acd6f119b71fc75e5d48465afca9fd13e87f (commit)
via 9100fcb4095cf8858d4cd2c613bff69ceb4f71ec (commit)
via 83512a6ff529c7c5cb6315167cba1cf132e6a67a (commit)
from 1a8fdb1462f8a506b2043877ab73cb86a9179ca6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=5c96acd6f119b71fc75...
commit 5c96acd6f119b71fc75e5d48465afca9fd13e87f
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
fix url encoding to be compatible with nsurl API changes.
As part of this fix the form submission error handling and
reporting has been improved.
diff --git a/content/fetch.h b/content/fetch.h
index 5521778..0b4b52a 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -74,16 +74,22 @@ typedef struct fetch_msg {
} data;
} fetch_msg;
-/** Fetch POST multipart data */
+/**
+ * Fetch POST multipart data
+ */
struct fetch_multipart_data {
- bool file; /**< Item is a file */
- char *name; /**< Name of item */
- char *value; /**< Item value */
- char *rawfile; /**< Raw filename if file is true */
+ struct fetch_multipart_data *next; /**< Next in linked list */
+
+ char *name; /**< Name of item */
+ char *value; /**< Item value */
- struct fetch_multipart_data *next; /**< Next in linked list */
+ char *rawfile; /**< Raw filename if file is true */
+ bool file; /**< Item is a file */
};
+/**
+ * ssl certificate information for certificate error message
+ */
struct ssl_cert_info {
long version; /**< Certificate version */
char not_before[32]; /**< Valid from date */
diff --git a/content/handlers/html/box_textarea.c b/content/handlers/html/box_textarea.c
index c19afbb..f0ba9f9 100644
--- a/content/handlers/html/box_textarea.c
+++ b/content/handlers/html/box_textarea.c
@@ -25,8 +25,11 @@
#include "utils/config.h"
#include "utils/log.h"
+#include "utils/messages.h"
#include "netsurf/keypress.h"
+#include "netsurf/misc.h"
#include "desktop/textarea.h"
+#include "desktop/gui_internal.h"
#include "html/html_internal.h"
#include "html/box.h"
@@ -41,6 +44,7 @@ bool box_textarea_keypress(html_content *html, struct box *box, uint32_t
key)
struct textarea *ta = gadget->data.text.ta;
struct form* form = box->gadget->form;
struct content *c = (struct content *) html;
+ nserror res;
assert(ta != NULL);
@@ -48,9 +52,16 @@ bool box_textarea_keypress(html_content *html, struct box *box,
uint32_t key)
switch (key) {
case NS_KEY_NL:
case NS_KEY_CR:
- if (form)
- form_submit(content_get_url(c), html->bw,
- form, 0);
+ if (form) {
+ res = form_submit(content_get_url(c),
+ html->bw,
+ form,
+ NULL);
+ if (res != NSERROR_OK) {
+ guit->misc->warning(messages_get_errorcode(res), NULL);
+ }
+
+ }
return true;
case NS_KEY_TAB:
diff --git a/content/handlers/html/form.c b/content/handlers/html/form.c
index 4a9d710..f779f07 100644
--- a/content/handlers/html/form.c
+++ b/content/handlers/html/form.c
@@ -327,10 +327,28 @@ bool form_add_option(struct form_control *control, char *value, char
*text,
}
-/* exported interface documented in html/form_internal.h */
-bool form_successful_controls_dom(struct form *_form,
- struct form_control *_submit_button,
- struct fetch_multipart_data **successful_controls)
+/**
+ * Identify 'successful' controls via the DOM.
+ *
+ * All text strings in the successful controls list will be in the charset most
+ * appropriate for submission. Therefore, no utf8_to_* processing should be
+ * performed upon them.
+ *
+ * \todo The chosen charset needs to be made available such that it can be
+ * included in the submission request (e.g. in the fetch's Content-Type header)
+ *
+ * See HTML 4.01 section 17.13.2.
+ *
+ * \param[in] form form to search for successful controls
+ * \param[in] submit_button control used to submit the form, if any
+ * \param[out] successful_controls updated to point to linked list of
+ * fetch_multipart_data, NULL if no controls
+ * \return NSERROR_OK on success or appropriate error code
+ */
+static nserror
+form_successful_controls_dom(struct form *_form,
+ struct form_control *_submit_button,
+ struct fetch_multipart_data **successful_controls)
{
dom_html_form_element *form = _form->node;
dom_html_element *submit_button = (_submit_button != NULL) ? _submit_button->node :
NULL;
@@ -352,7 +370,7 @@ bool form_successful_controls_dom(struct form *_form,
charset = form_acceptable_charset(_form);
if (charset == NULL) {
NSLOG(netsurf, INFO, "failed to find charset");
- return false;
+ return NSERROR_NOMEM;
}
#define ENCODE_ITEM(i) (((i) == NULL) ? ( \
@@ -685,6 +703,11 @@ bool form_successful_controls_dom(struct form *_form,
}
basename = ENCODE_ITEM(inputname);
+ if (basename == NULL) {
+ NSLOG(netsurf, INFO,
+ "Could not encode basename");
+ goto dom_no_memory;
+ }
success_new = calloc(1, sizeof(*success_new));
if (success_new == NULL) {
@@ -704,6 +727,8 @@ bool form_successful_controls_dom(struct form *_form,
"Could not allocate name for image.x");
goto dom_no_memory;
}
+ sprintf(success_new->name, "%s.x", basename);
+
success_new->value = malloc(20);
if (success_new->value == NULL) {
free(basename);
@@ -711,7 +736,6 @@ bool form_successful_controls_dom(struct form *_form,
"Could not allocate value for image.x");
goto dom_no_memory;
}
- sprintf(success_new->name, "%s.x", basename);
sprintf(success_new->value, "%d", coords->x);
success_new = calloc(1, sizeof(*success_new));
@@ -890,7 +914,7 @@ bool form_successful_controls_dom(struct form *_form,
*successful_controls = sentinel.next;
- return true;
+ return NSERROR_OK;
dom_no_memory:
free(charset);
@@ -915,73 +939,61 @@ dom_no_memory:
if (rawfile_temp != NULL)
free(rawfile_temp);
- return false;
+ return NSERROR_NOMEM;
}
#undef ENCODE_ITEM
/**
* Encode controls using application/x-www-form-urlencoded.
*
- * \param form form to which successful controls relate
- * \param control linked list of fetch_multipart_data
- * \param query_string iff true add '?' to the start of returned data
- * \return URL-encoded form, or 0 on memory exhaustion
+ * \param[in] form form to which successful controls relate
+ * \param[in] control linked list of fetch_multipart_data
+ * \param[out] encoded_out URL-encoded form data
+ * \return NSERROR_OK on success and \a encoded_out updated else appropriate error code
*/
-
-static char *form_url_encode(struct form *form,
+static nserror
+form_url_encode(struct form *form,
struct fetch_multipart_data *control,
- bool query_string)
+ char **encoded_out)
{
char *name, *value;
char *s, *s2;
unsigned int len, len1, len_init;
- nserror url_err;
+ nserror res;
- if (query_string)
- s = malloc(2);
- else
- s = malloc(1);
+ s = malloc(1);
- if (s == NULL)
- return NULL;
-
- if (query_string) {
- s[0] = '?';
- s[1] = '\0';
- len_init = len = 1;
- } else {
- s[0] = '\0';
- len_init = len = 0;
+ if (s == NULL) {
+ return NSERROR_NOMEM;
}
+ s[0] = '\0';
+ len_init = len = 0;
+
for (; control; control = control->next) {
- url_err = url_escape(control->name, true, NULL, &name);
- if (url_err == NSERROR_NOMEM) {
+ res = url_escape(control->name, true, NULL, &name);
+ if (res != NSERROR_OK) {
free(s);
- return NULL;
+ return res;
}
- assert(url_err == NSERROR_OK);
-
- url_err = url_escape(control->value, true, NULL, &value);
- if (url_err == NSERROR_NOMEM) {
+ res = url_escape(control->value, true, NULL, &value);
+ if (res != NSERROR_OK) {
free(name);
free(s);
- return NULL;
+ return res;
}
- assert(url_err == NSERROR_OK);
-
/* resize string to allow for new key/value pair,
* equals, amphersand and terminator
*/
len1 = len + strlen(name) + strlen(value) + 2;
s2 = realloc(s, len1 + 1);
- if (!s2) {
+ if (s2 == NULL) {
free(value);
free(name);
free(s);
- return NULL;
+ return NSERROR_NOMEM;
}
s = s2;
@@ -995,7 +1007,10 @@ static char *form_url_encode(struct form *form,
/* Replace trailing '&' */
s[len - 1] = '\0';
}
- return s;
+
+ *encoded_out = s;
+
+ return NSERROR_OK;
}
/**
@@ -1008,17 +1023,15 @@ char *form_acceptable_charset(struct form *form)
{
char *temp, *c;
- if (!form)
- return NULL;
-
if (!form->accept_charsets) {
/* no accept-charsets attribute for this form */
- if (form->document_charset)
+ if (form->document_charset) {
/* document charset present, so use it */
return strdup(form->document_charset);
- else
+ } else {
/* no document charset, so default to 8859-1 */
return strdup("ISO-8859-1");
+ }
}
/* make temporary copy of accept-charsets attribute */
@@ -1768,98 +1781,85 @@ void form_radio_set(struct form_control *radio)
}
-/**
- * Collect controls and submit a form.
- */
-
-void form_submit(nsurl *page_url, struct browser_window *target,
- struct form *form, struct form_control *submit_button)
+/* private interface described in html/form_internal.h */
+nserror
+form_submit(nsurl *page_url,
+ struct browser_window *target,
+ struct form *form,
+ struct form_control *submit_button)
{
- char *data = NULL;
- struct fetch_multipart_data *success;
+ nserror res;
+ char *data = NULL; /* encoded form data */
+ struct fetch_multipart_data *success = NULL; /* gcc is incapable of correctly reasoning
about use and generates "maybe used uninitialised" warnings */
nsurl *action_url;
- nsurl *action_query;
- nserror error;
+ nsurl *query_url;
assert(form != NULL);
- if (form_successful_controls_dom(form, submit_button, &success) == false) {
- guit->misc->warning("NoMemory", 0);
- return;
+ /* obtain list of controls from DOM */
+ res = form_successful_controls_dom(form, submit_button, &success);
+ if (res != NSERROR_OK) {
+ return res;
}
/* Decompose action */
- if (nsurl_create(form->action, &action_url) != NSERROR_OK) {
- free(data);
+ res = nsurl_create(form->action, &action_url);
+ if (res != NSERROR_OK) {
fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- return;
+ return res;
}
switch (form->method) {
case method_GET:
- data = form_url_encode(form, success, true);
- if (data == NULL) {
- fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- return;
- }
-
- /* Replace query segment */
- error = nsurl_replace_query(action_url, data, &action_query);
- if (error != NSERROR_OK) {
- nsurl_unref(action_query);
+ res = form_url_encode(form, success, &data);
+ if (res == NSERROR_OK) {
+ /* Replace query segment */
+ res = nsurl_replace_query(action_url, data, &query_url);
+ if (res == NSERROR_OK) {
+ res = browser_window_navigate(target,
+ query_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+
+ nsurl_unref(query_url);
+ }
free(data);
- fetch_multipart_data_destroy(success);
- guit->misc->warning(messages_get_errorcode(error), 0);
- return;
}
-
- /* Construct submit url */
- browser_window_navigate(target,
- action_query,
- page_url,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
-
- nsurl_unref(action_query);
break;
case method_POST_URLENC:
- data = form_url_encode(form, success, false);
- if (data == NULL) {
- fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- nsurl_unref(action_url);
- return;
+ res = form_url_encode(form, success, &data);
+ if (res == NSERROR_OK) {
+ res = browser_window_navigate(target,
+ action_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ data,
+ NULL,
+ NULL);
+ free(data);
}
-
- browser_window_navigate(target,
- action_url,
- page_url,
- BW_NAVIGATE_HISTORY,
- data,
- NULL,
- NULL);
break;
case method_POST_MULTIPART:
- browser_window_navigate(target,
- action_url,
- page_url,
- BW_NAVIGATE_HISTORY,
- NULL,
- success,
- NULL);
+ res = browser_window_navigate(target,
+ action_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ success,
+ NULL);
break;
}
nsurl_unref(action_url);
fetch_multipart_data_destroy(success);
- free(data);
+
+ return res;
}
void form_gadget_update_value(struct form_control *control, char *value)
diff --git a/content/handlers/html/form_internal.h
b/content/handlers/html/form_internal.h
index a77e823..f76f126 100644
--- a/content/handlers/html/form_internal.h
+++ b/content/handlers/html/form_internal.h
@@ -195,29 +195,6 @@ bool form_successful_controls(struct form *form,
struct fetch_multipart_data **successful_controls);
/**
- * Identify 'successful' controls via the DOM.
- *
- * All text strings in the successful controls list will be in the charset most
- * appropriate for submission. Therefore, no utf8_to_* processing should be
- * performed upon them.
- *
- * \todo The chosen charset needs to be made available such that it can be
- * included in the submission request (e.g. in the fetch's Content-Type header)
- *
- * See HTML 4.01 section 17.13.2.
- *
- * \param[in] form form to search for successful controls
- * \param[in] submit_button control used to submit the form, if any
- * \param[out] successful_controls updated to point to linked list of
- * fetch_multipart_data, 0 if no controls
- * \return true on success, false on memory exhaustion
- */
-bool form_successful_controls_dom(struct form *form,
- struct form_control *submit_button,
- struct fetch_multipart_data **successful_controls);
-
-
-/**
* Open a select menu for a select form control, creating it if necessary.
*
* \param client_data data passed to the redraw callback
@@ -268,8 +245,18 @@ void form_select_mouse_drag_end(struct form_control *control,
enum browser_mouse_state mouse, int x, int y);
void form_select_get_dimensions(struct form_control *control,
int *width, int *height);
-void form_submit(struct nsurl *page_url, struct browser_window *target,
+
+/**
+ * navigate browser window based on form submission.
+ *
+ * \param page_url content url
+ * \param target The browsing context in which the navigation will occour.
+ * \param form The form to submit.
+ * \param submit_button The control used to submit the form.
+ */
+nserror form_submit(struct nsurl *page_url, struct browser_window *target,
struct form *form, struct form_control *submit_button);
+
void form_radio_set(struct form_control *radio);
void form_gadget_update_value(struct form_control *control, char *value);
diff --git a/content/handlers/html/html_interaction.c
b/content/handlers/html/html_interaction.c
index 648d274..04d14aa 100644
--- a/content/handlers/html/html_interaction.c
+++ b/content/handlers/html/html_interaction.c
@@ -389,6 +389,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2 |
BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2);
+ nserror res;
+
if (drag_type != DRAGGING_NONE && !mouse &&
html->visible_select_menu != NULL) {
/* drag end: select menu */
@@ -875,9 +877,12 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
}
} else if (url) {
if (nsoption_bool(display_decoded_idn) == true) {
- if (nsurl_get_utf8(url, &url_s, &url_l) != NSERROR_OK) {
- /* Unable to obtain a decoded IDN. This is not a fatal error.
- * Ensure the string pointer is NULL so we use the encoded version. */
+ res = nsurl_get_utf8(url, &url_s, &url_l);
+ if (res != NSERROR_OK) {
+ /* Unable to obtain a decoded IDN. This is not
+ * a fatal error. Ensure the string pointer
+ * is NULL so we use the encoded version.
+ */
url_s = NULL;
}
}
@@ -1072,22 +1077,32 @@ void html_mouse_action(struct content *c, struct browser_window
*bw,
*/
switch (action) {
case ACTION_SUBMIT:
- form_submit(content_get_url(c),
- browser_window_find_target(bw, target, mouse),
- gadget->form, gadget);
+ res = form_submit(content_get_url(c),
+ browser_window_find_target(bw, target, mouse),
+ gadget->form,
+ gadget);
break;
+
case ACTION_GO:
- browser_window_navigate(browser_window_find_target(bw, target, mouse),
- url,
- content_get_url(c),
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
+ res = browser_window_navigate(
+ browser_window_find_target(bw, target, mouse),
+ url,
+ content_get_url(c),
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
break;
+
case ACTION_NONE:
+ res = NSERROR_OK;
break;
}
+
+ if (res != NSERROR_OK) {
+ guit->misc->warning(messages_get_errorcode(res), NULL);
+ }
+
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=9100fcb4095cf8858d4...
commit 9100fcb4095cf8858d4cd2c613bff69ceb4f71ec
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
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
diff --git a/test/nsurl.c b/test/nsurl.c
index ba02429..631e7ae 100644
--- a/test/nsurl.c
+++ b/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);
diff --git a/utils/nsurl.h b/utils/nsurl.h
index bc6e910..c6590bd 100644
--- a/utils/nsurl.h
+++ b/utils/nsurl.h
@@ -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);
diff --git a/utils/nsurl/nsurl.c b/utils/nsurl/nsurl.c
index 4dbbe96..38c0e53 100644
--- a/utils/nsurl/nsurl.c
+++ b/utils/nsurl/nsurl.c
@@ -54,7 +54,7 @@
* Does nothing if the components are the same, so ensure match is
* preset to true.
*/
-#define nsurl__component_compare(c1, c2, match) \
+#define nsurl__component_compare(c1, c2, match) \
if (c1 && c2 && lwc_error_ok == \
lwc_string_isequal(c1, c2, match)) { \
/* do nothing */ \
@@ -364,7 +364,7 @@ nserror nsurl_get_utf8(const nsurl *url, char **url_s, size_t *url_l)
}
*url_l = scheme_len + idna_host_len + path_len + 1; /* +1 for \0 */
- *url_s = malloc(*url_l);
+ *url_s = malloc(*url_l);
if (*url_s == NULL) {
err = NSERROR_NOMEM;
@@ -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 base_len; /* Length of URL up to start of query */
- char *pos;
- size_t len;
- lwc_string *lwc_query;
+ 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; /* 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);
- pos += 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;
}
-
diff --git a/utils/nsurl/parse.c b/utils/nsurl/parse.c
index 3e3c521..3b8816d 100644
--- a/utils/nsurl/parse.c
+++ b/utils/nsurl/parse.c
@@ -344,7 +344,7 @@ static void nsurl__get_string_markers(const char * const url_s,
* and in the case of mailto: when we assume there is an authority.
*/
if ((*pos == '/' && *(pos + 1) == '/') ||
- (is_http && ((joining && *pos == '/') ||
+ (is_http && ((joining && *pos == '/') ||
(joining == false &&
marker.scheme_end != marker.start))) ||
marker.scheme_type == NSURL_SCHEME_MAILTO) {
@@ -577,7 +577,7 @@ static size_t nsurl__remove_dot_segments(char *path, char *output)
/* Copy up to but not including next '/' */
while ((*path_pos != '/') && (*path_pos != '\0'))
- *output_pos++ = *path_pos++;
+ *output_pos++ = *path_pos++;
}
return output_pos - output;
@@ -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;
}
-
diff --git a/utils/nsurl/private.h b/utils/nsurl/private.h
index 4366ff6..06f143f 100644
--- a/utils/nsurl/private.h
+++ b/utils/nsurl/private.h
@@ -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)
};
/**
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=83512a6ff529c7c5cb6...
commit 83512a6ff529c7c5cb6315167cba1cf132e6a67a
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
squash clang warning about increased alignment requirements.
diff --git a/frontends/gtk/gdk.c b/frontends/gtk/gdk.c
index fd82af5..2912862 100644
--- a/frontends/gtk/gdk.c
+++ b/frontends/gtk/gdk.c
@@ -33,7 +33,8 @@ convert_alpha(guchar *dest_data,
int x, y;
for (y = 0; y < height; y++) {
- guint32 *src = (guint32 *) src_data;
+ /* this cast is safe, the buffer is appropriately aligned */
+ guint32 *src = (void *) src_data;
for (x = 0; x < width; x++) {
guint alpha = src[x] >> 24;
-----------------------------------------------------------------------
Summary of changes:
content/fetch.h | 18 ++-
content/handlers/html/box_textarea.c | 17 ++-
content/handlers/html/form.c | 224 +++++++++++++++---------------
content/handlers/html/form_internal.h | 35 ++---
content/handlers/html/html_interaction.c | 41 ++++--
frontends/gtk/gdk.c | 3 +-
test/nsurl.c | 26 ++--
utils/nsurl.h | 3 +
utils/nsurl/nsurl.c | 65 +++++----
utils/nsurl/parse.c | 20 ++-
utils/nsurl/private.h | 7 +-
11 files changed, 256 insertions(+), 203 deletions(-)
diff --git a/content/fetch.h b/content/fetch.h
index 5521778..0b4b52a 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -74,16 +74,22 @@ typedef struct fetch_msg {
} data;
} fetch_msg;
-/** Fetch POST multipart data */
+/**
+ * Fetch POST multipart data
+ */
struct fetch_multipart_data {
- bool file; /**< Item is a file */
- char *name; /**< Name of item */
- char *value; /**< Item value */
- char *rawfile; /**< Raw filename if file is true */
+ struct fetch_multipart_data *next; /**< Next in linked list */
+
+ char *name; /**< Name of item */
+ char *value; /**< Item value */
- struct fetch_multipart_data *next; /**< Next in linked list */
+ char *rawfile; /**< Raw filename if file is true */
+ bool file; /**< Item is a file */
};
+/**
+ * ssl certificate information for certificate error message
+ */
struct ssl_cert_info {
long version; /**< Certificate version */
char not_before[32]; /**< Valid from date */
diff --git a/content/handlers/html/box_textarea.c b/content/handlers/html/box_textarea.c
index c19afbb..f0ba9f9 100644
--- a/content/handlers/html/box_textarea.c
+++ b/content/handlers/html/box_textarea.c
@@ -25,8 +25,11 @@
#include "utils/config.h"
#include "utils/log.h"
+#include "utils/messages.h"
#include "netsurf/keypress.h"
+#include "netsurf/misc.h"
#include "desktop/textarea.h"
+#include "desktop/gui_internal.h"
#include "html/html_internal.h"
#include "html/box.h"
@@ -41,6 +44,7 @@ bool box_textarea_keypress(html_content *html, struct box *box, uint32_t
key)
struct textarea *ta = gadget->data.text.ta;
struct form* form = box->gadget->form;
struct content *c = (struct content *) html;
+ nserror res;
assert(ta != NULL);
@@ -48,9 +52,16 @@ bool box_textarea_keypress(html_content *html, struct box *box,
uint32_t key)
switch (key) {
case NS_KEY_NL:
case NS_KEY_CR:
- if (form)
- form_submit(content_get_url(c), html->bw,
- form, 0);
+ if (form) {
+ res = form_submit(content_get_url(c),
+ html->bw,
+ form,
+ NULL);
+ if (res != NSERROR_OK) {
+ guit->misc->warning(messages_get_errorcode(res), NULL);
+ }
+
+ }
return true;
case NS_KEY_TAB:
diff --git a/content/handlers/html/form.c b/content/handlers/html/form.c
index 4a9d710..f779f07 100644
--- a/content/handlers/html/form.c
+++ b/content/handlers/html/form.c
@@ -327,10 +327,28 @@ bool form_add_option(struct form_control *control, char *value, char
*text,
}
-/* exported interface documented in html/form_internal.h */
-bool form_successful_controls_dom(struct form *_form,
- struct form_control *_submit_button,
- struct fetch_multipart_data **successful_controls)
+/**
+ * Identify 'successful' controls via the DOM.
+ *
+ * All text strings in the successful controls list will be in the charset most
+ * appropriate for submission. Therefore, no utf8_to_* processing should be
+ * performed upon them.
+ *
+ * \todo The chosen charset needs to be made available such that it can be
+ * included in the submission request (e.g. in the fetch's Content-Type header)
+ *
+ * See HTML 4.01 section 17.13.2.
+ *
+ * \param[in] form form to search for successful controls
+ * \param[in] submit_button control used to submit the form, if any
+ * \param[out] successful_controls updated to point to linked list of
+ * fetch_multipart_data, NULL if no controls
+ * \return NSERROR_OK on success or appropriate error code
+ */
+static nserror
+form_successful_controls_dom(struct form *_form,
+ struct form_control *_submit_button,
+ struct fetch_multipart_data **successful_controls)
{
dom_html_form_element *form = _form->node;
dom_html_element *submit_button = (_submit_button != NULL) ? _submit_button->node :
NULL;
@@ -352,7 +370,7 @@ bool form_successful_controls_dom(struct form *_form,
charset = form_acceptable_charset(_form);
if (charset == NULL) {
NSLOG(netsurf, INFO, "failed to find charset");
- return false;
+ return NSERROR_NOMEM;
}
#define ENCODE_ITEM(i) (((i) == NULL) ? ( \
@@ -685,6 +703,11 @@ bool form_successful_controls_dom(struct form *_form,
}
basename = ENCODE_ITEM(inputname);
+ if (basename == NULL) {
+ NSLOG(netsurf, INFO,
+ "Could not encode basename");
+ goto dom_no_memory;
+ }
success_new = calloc(1, sizeof(*success_new));
if (success_new == NULL) {
@@ -704,6 +727,8 @@ bool form_successful_controls_dom(struct form *_form,
"Could not allocate name for image.x");
goto dom_no_memory;
}
+ sprintf(success_new->name, "%s.x", basename);
+
success_new->value = malloc(20);
if (success_new->value == NULL) {
free(basename);
@@ -711,7 +736,6 @@ bool form_successful_controls_dom(struct form *_form,
"Could not allocate value for image.x");
goto dom_no_memory;
}
- sprintf(success_new->name, "%s.x", basename);
sprintf(success_new->value, "%d", coords->x);
success_new = calloc(1, sizeof(*success_new));
@@ -890,7 +914,7 @@ bool form_successful_controls_dom(struct form *_form,
*successful_controls = sentinel.next;
- return true;
+ return NSERROR_OK;
dom_no_memory:
free(charset);
@@ -915,73 +939,61 @@ dom_no_memory:
if (rawfile_temp != NULL)
free(rawfile_temp);
- return false;
+ return NSERROR_NOMEM;
}
#undef ENCODE_ITEM
/**
* Encode controls using application/x-www-form-urlencoded.
*
- * \param form form to which successful controls relate
- * \param control linked list of fetch_multipart_data
- * \param query_string iff true add '?' to the start of returned data
- * \return URL-encoded form, or 0 on memory exhaustion
+ * \param[in] form form to which successful controls relate
+ * \param[in] control linked list of fetch_multipart_data
+ * \param[out] encoded_out URL-encoded form data
+ * \return NSERROR_OK on success and \a encoded_out updated else appropriate error code
*/
-
-static char *form_url_encode(struct form *form,
+static nserror
+form_url_encode(struct form *form,
struct fetch_multipart_data *control,
- bool query_string)
+ char **encoded_out)
{
char *name, *value;
char *s, *s2;
unsigned int len, len1, len_init;
- nserror url_err;
+ nserror res;
- if (query_string)
- s = malloc(2);
- else
- s = malloc(1);
+ s = malloc(1);
- if (s == NULL)
- return NULL;
-
- if (query_string) {
- s[0] = '?';
- s[1] = '\0';
- len_init = len = 1;
- } else {
- s[0] = '\0';
- len_init = len = 0;
+ if (s == NULL) {
+ return NSERROR_NOMEM;
}
+ s[0] = '\0';
+ len_init = len = 0;
+
for (; control; control = control->next) {
- url_err = url_escape(control->name, true, NULL, &name);
- if (url_err == NSERROR_NOMEM) {
+ res = url_escape(control->name, true, NULL, &name);
+ if (res != NSERROR_OK) {
free(s);
- return NULL;
+ return res;
}
- assert(url_err == NSERROR_OK);
-
- url_err = url_escape(control->value, true, NULL, &value);
- if (url_err == NSERROR_NOMEM) {
+ res = url_escape(control->value, true, NULL, &value);
+ if (res != NSERROR_OK) {
free(name);
free(s);
- return NULL;
+ return res;
}
- assert(url_err == NSERROR_OK);
-
/* resize string to allow for new key/value pair,
* equals, amphersand and terminator
*/
len1 = len + strlen(name) + strlen(value) + 2;
s2 = realloc(s, len1 + 1);
- if (!s2) {
+ if (s2 == NULL) {
free(value);
free(name);
free(s);
- return NULL;
+ return NSERROR_NOMEM;
}
s = s2;
@@ -995,7 +1007,10 @@ static char *form_url_encode(struct form *form,
/* Replace trailing '&' */
s[len - 1] = '\0';
}
- return s;
+
+ *encoded_out = s;
+
+ return NSERROR_OK;
}
/**
@@ -1008,17 +1023,15 @@ char *form_acceptable_charset(struct form *form)
{
char *temp, *c;
- if (!form)
- return NULL;
-
if (!form->accept_charsets) {
/* no accept-charsets attribute for this form */
- if (form->document_charset)
+ if (form->document_charset) {
/* document charset present, so use it */
return strdup(form->document_charset);
- else
+ } else {
/* no document charset, so default to 8859-1 */
return strdup("ISO-8859-1");
+ }
}
/* make temporary copy of accept-charsets attribute */
@@ -1768,98 +1781,85 @@ void form_radio_set(struct form_control *radio)
}
-/**
- * Collect controls and submit a form.
- */
-
-void form_submit(nsurl *page_url, struct browser_window *target,
- struct form *form, struct form_control *submit_button)
+/* private interface described in html/form_internal.h */
+nserror
+form_submit(nsurl *page_url,
+ struct browser_window *target,
+ struct form *form,
+ struct form_control *submit_button)
{
- char *data = NULL;
- struct fetch_multipart_data *success;
+ nserror res;
+ char *data = NULL; /* encoded form data */
+ struct fetch_multipart_data *success = NULL; /* gcc is incapable of correctly reasoning
about use and generates "maybe used uninitialised" warnings */
nsurl *action_url;
- nsurl *action_query;
- nserror error;
+ nsurl *query_url;
assert(form != NULL);
- if (form_successful_controls_dom(form, submit_button, &success) == false) {
- guit->misc->warning("NoMemory", 0);
- return;
+ /* obtain list of controls from DOM */
+ res = form_successful_controls_dom(form, submit_button, &success);
+ if (res != NSERROR_OK) {
+ return res;
}
/* Decompose action */
- if (nsurl_create(form->action, &action_url) != NSERROR_OK) {
- free(data);
+ res = nsurl_create(form->action, &action_url);
+ if (res != NSERROR_OK) {
fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- return;
+ return res;
}
switch (form->method) {
case method_GET:
- data = form_url_encode(form, success, true);
- if (data == NULL) {
- fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- return;
- }
-
- /* Replace query segment */
- error = nsurl_replace_query(action_url, data, &action_query);
- if (error != NSERROR_OK) {
- nsurl_unref(action_query);
+ res = form_url_encode(form, success, &data);
+ if (res == NSERROR_OK) {
+ /* Replace query segment */
+ res = nsurl_replace_query(action_url, data, &query_url);
+ if (res == NSERROR_OK) {
+ res = browser_window_navigate(target,
+ query_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+
+ nsurl_unref(query_url);
+ }
free(data);
- fetch_multipart_data_destroy(success);
- guit->misc->warning(messages_get_errorcode(error), 0);
- return;
}
-
- /* Construct submit url */
- browser_window_navigate(target,
- action_query,
- page_url,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
-
- nsurl_unref(action_query);
break;
case method_POST_URLENC:
- data = form_url_encode(form, success, false);
- if (data == NULL) {
- fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- nsurl_unref(action_url);
- return;
+ res = form_url_encode(form, success, &data);
+ if (res == NSERROR_OK) {
+ res = browser_window_navigate(target,
+ action_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ data,
+ NULL,
+ NULL);
+ free(data);
}
-
- browser_window_navigate(target,
- action_url,
- page_url,
- BW_NAVIGATE_HISTORY,
- data,
- NULL,
- NULL);
break;
case method_POST_MULTIPART:
- browser_window_navigate(target,
- action_url,
- page_url,
- BW_NAVIGATE_HISTORY,
- NULL,
- success,
- NULL);
+ res = browser_window_navigate(target,
+ action_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ success,
+ NULL);
break;
}
nsurl_unref(action_url);
fetch_multipart_data_destroy(success);
- free(data);
+
+ return res;
}
void form_gadget_update_value(struct form_control *control, char *value)
diff --git a/content/handlers/html/form_internal.h
b/content/handlers/html/form_internal.h
index a77e823..f76f126 100644
--- a/content/handlers/html/form_internal.h
+++ b/content/handlers/html/form_internal.h
@@ -195,29 +195,6 @@ bool form_successful_controls(struct form *form,
struct fetch_multipart_data **successful_controls);
/**
- * Identify 'successful' controls via the DOM.
- *
- * All text strings in the successful controls list will be in the charset most
- * appropriate for submission. Therefore, no utf8_to_* processing should be
- * performed upon them.
- *
- * \todo The chosen charset needs to be made available such that it can be
- * included in the submission request (e.g. in the fetch's Content-Type header)
- *
- * See HTML 4.01 section 17.13.2.
- *
- * \param[in] form form to search for successful controls
- * \param[in] submit_button control used to submit the form, if any
- * \param[out] successful_controls updated to point to linked list of
- * fetch_multipart_data, 0 if no controls
- * \return true on success, false on memory exhaustion
- */
-bool form_successful_controls_dom(struct form *form,
- struct form_control *submit_button,
- struct fetch_multipart_data **successful_controls);
-
-
-/**
* Open a select menu for a select form control, creating it if necessary.
*
* \param client_data data passed to the redraw callback
@@ -268,8 +245,18 @@ void form_select_mouse_drag_end(struct form_control *control,
enum browser_mouse_state mouse, int x, int y);
void form_select_get_dimensions(struct form_control *control,
int *width, int *height);
-void form_submit(struct nsurl *page_url, struct browser_window *target,
+
+/**
+ * navigate browser window based on form submission.
+ *
+ * \param page_url content url
+ * \param target The browsing context in which the navigation will occour.
+ * \param form The form to submit.
+ * \param submit_button The control used to submit the form.
+ */
+nserror form_submit(struct nsurl *page_url, struct browser_window *target,
struct form *form, struct form_control *submit_button);
+
void form_radio_set(struct form_control *radio);
void form_gadget_update_value(struct form_control *control, char *value);
diff --git a/content/handlers/html/html_interaction.c
b/content/handlers/html/html_interaction.c
index 648d274..04d14aa 100644
--- a/content/handlers/html/html_interaction.c
+++ b/content/handlers/html/html_interaction.c
@@ -389,6 +389,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2 |
BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2);
+ nserror res;
+
if (drag_type != DRAGGING_NONE && !mouse &&
html->visible_select_menu != NULL) {
/* drag end: select menu */
@@ -875,9 +877,12 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
}
} else if (url) {
if (nsoption_bool(display_decoded_idn) == true) {
- if (nsurl_get_utf8(url, &url_s, &url_l) != NSERROR_OK) {
- /* Unable to obtain a decoded IDN. This is not a fatal error.
- * Ensure the string pointer is NULL so we use the encoded version. */
+ res = nsurl_get_utf8(url, &url_s, &url_l);
+ if (res != NSERROR_OK) {
+ /* Unable to obtain a decoded IDN. This is not
+ * a fatal error. Ensure the string pointer
+ * is NULL so we use the encoded version.
+ */
url_s = NULL;
}
}
@@ -1072,22 +1077,32 @@ void html_mouse_action(struct content *c, struct browser_window
*bw,
*/
switch (action) {
case ACTION_SUBMIT:
- form_submit(content_get_url(c),
- browser_window_find_target(bw, target, mouse),
- gadget->form, gadget);
+ res = form_submit(content_get_url(c),
+ browser_window_find_target(bw, target, mouse),
+ gadget->form,
+ gadget);
break;
+
case ACTION_GO:
- browser_window_navigate(browser_window_find_target(bw, target, mouse),
- url,
- content_get_url(c),
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
+ res = browser_window_navigate(
+ browser_window_find_target(bw, target, mouse),
+ url,
+ content_get_url(c),
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
break;
+
case ACTION_NONE:
+ res = NSERROR_OK;
break;
}
+
+ if (res != NSERROR_OK) {
+ guit->misc->warning(messages_get_errorcode(res), NULL);
+ }
+
}
diff --git a/frontends/gtk/gdk.c b/frontends/gtk/gdk.c
index fd82af5..2912862 100644
--- a/frontends/gtk/gdk.c
+++ b/frontends/gtk/gdk.c
@@ -33,7 +33,8 @@ convert_alpha(guchar *dest_data,
int x, y;
for (y = 0; y < height; y++) {
- guint32 *src = (guint32 *) src_data;
+ /* this cast is safe, the buffer is appropriately aligned */
+ guint32 *src = (void *) src_data;
for (x = 0; x < width; x++) {
guint alpha = src[x] >> 24;
diff --git a/test/nsurl.c b/test/nsurl.c
index ba02429..631e7ae 100644
--- a/test/nsurl.c
+++ b/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);
diff --git a/utils/nsurl.h b/utils/nsurl.h
index bc6e910..c6590bd 100644
--- a/utils/nsurl.h
+++ b/utils/nsurl.h
@@ -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);
diff --git a/utils/nsurl/nsurl.c b/utils/nsurl/nsurl.c
index 4dbbe96..38c0e53 100644
--- a/utils/nsurl/nsurl.c
+++ b/utils/nsurl/nsurl.c
@@ -54,7 +54,7 @@
* Does nothing if the components are the same, so ensure match is
* preset to true.
*/
-#define nsurl__component_compare(c1, c2, match) \
+#define nsurl__component_compare(c1, c2, match) \
if (c1 && c2 && lwc_error_ok == \
lwc_string_isequal(c1, c2, match)) { \
/* do nothing */ \
@@ -364,7 +364,7 @@ nserror nsurl_get_utf8(const nsurl *url, char **url_s, size_t *url_l)
}
*url_l = scheme_len + idna_host_len + path_len + 1; /* +1 for \0 */
- *url_s = malloc(*url_l);
+ *url_s = malloc(*url_l);
if (*url_s == NULL) {
err = NSERROR_NOMEM;
@@ -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 base_len; /* Length of URL up to start of query */
- char *pos;
- size_t len;
- lwc_string *lwc_query;
+ 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; /* 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);
- pos += 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;
}
-
diff --git a/utils/nsurl/parse.c b/utils/nsurl/parse.c
index 3e3c521..3b8816d 100644
--- a/utils/nsurl/parse.c
+++ b/utils/nsurl/parse.c
@@ -344,7 +344,7 @@ static void nsurl__get_string_markers(const char * const url_s,
* and in the case of mailto: when we assume there is an authority.
*/
if ((*pos == '/' && *(pos + 1) == '/') ||
- (is_http && ((joining && *pos == '/') ||
+ (is_http && ((joining && *pos == '/') ||
(joining == false &&
marker.scheme_end != marker.start))) ||
marker.scheme_type == NSURL_SCHEME_MAILTO) {
@@ -577,7 +577,7 @@ static size_t nsurl__remove_dot_segments(char *path, char *output)
/* Copy up to but not including next '/' */
while ((*path_pos != '/') && (*path_pos != '\0'))
- *output_pos++ = *path_pos++;
+ *output_pos++ = *path_pos++;
}
return output_pos - output;
@@ -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;
}
-
diff --git a/utils/nsurl/private.h b/utils/nsurl/private.h
index 4366ff6..06f143f 100644
--- a/utils/nsurl/private.h
+++ b/utils/nsurl/private.h
@@ -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)
};
/**
--
NetSurf Browser