summaryrefslogtreecommitdiff
path: root/content/handlers/html/form.c
diff options
context:
space:
mode:
Diffstat (limited to 'content/handlers/html/form.c')
-rw-r--r--content/handlers/html/form.c224
1 files changed, 112 insertions, 112 deletions
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)