summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2018-09-26 17:14:25 +0100
committerVincent Sanders <vince@kyllikki.org>2018-09-26 17:21:48 +0100
commit5c96acd6f119b71fc75e5d48465afca9fd13e87f (patch)
treeebe6b2b07b6767f1c892a35ba99295b4cd17ec59
parent9100fcb4095cf8858d4cd2c613bff69ceb4f71ec (diff)
downloadnetsurf-5c96acd6f119b71fc75e5d48465afca9fd13e87f.tar.gz
netsurf-5c96acd6f119b71fc75e5d48465afca9fd13e87f.tar.bz2
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.
-rw-r--r--content/fetch.h18
-rw-r--r--content/handlers/html/box_textarea.c17
-rw-r--r--content/handlers/html/form.c224
-rw-r--r--content/handlers/html/form_internal.h35
-rw-r--r--content/handlers/html/html_interaction.c41
5 files changed, 177 insertions, 158 deletions
diff --git a/content/fetch.h b/content/fetch.h
index 5521778ea..0b4b52a2f 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 c19afbb77..f0ba9f9de 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 4a9d7102d..f779f07bd 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 a77e823b3..f76f126b4 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 648d27467..04d14aa81 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);
+ }
+
}