aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--src/dillo.cc4
-rw-r--r--src/html.cc221
3 files changed, 147 insertions, 80 deletions
diff --git a/ChangeLog b/ChangeLog
index a8c336d7..8c546670 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -81,7 +81,7 @@ dillo-fltk2
- Fixed a memory leak in cookies.c
- Added "standard_widget_colors" preference. It allows a more stylish look.
- Fixed the return value of Cache_parse_multiple_field.
- - Added multipart/form-data encoding for form submission.
+ - Added the multipart/form-data encoding method to form submission.
Patches: place
+- Fixed a problem with locally-installed dpis.
- Added code for optional image loading (nice interface) very advanced!
diff --git a/src/dillo.cc b/src/dillo.cc
index cfefa053..af45adfc 100644
--- a/src/dillo.cc
+++ b/src/dillo.cc
@@ -20,6 +20,8 @@
#include <stdio.h>
#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
#include <fltk/Window.h>
#include <fltk/run.h>
@@ -78,6 +80,8 @@ static DilloUrl *Dillo_make_start_url(char *str)
*/
int main(int argc, char **argv)
{
+ srand((uint_t)(time(0) ^ getpid()));
+
// Initialize internal modules
a_Dir_init();
a_Prefs_init();
diff --git a/src/html.cc b/src/html.cc
index af474307..b8473a7d 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -3520,6 +3520,7 @@ static void Html_tag_open_form(DilloHtml *html, const char *tag, int tagsize)
if (!dStrcasecmp(attrbuf, "multipart/form-data"))
enc = DILLO_HTML_ENC_MULTIPART;
}
+ // todo: handle accept-charset attr
html->formNew(method, action, enc);
a_Url_free(action);
}
@@ -3813,23 +3814,16 @@ static void Html_urlencode_append(Dstr *str, const char *val)
* Append a name-value pair to an existing url.
*/
static void
- Html_append_input(DilloHtmlEnc encoding, Dstr *url, const char *name,
- const char *value)
+ Html_append_input(DilloHtmlEnc encoding, const char *boundary, Dstr *url,
+ const char *name, const char *value)
{
- /*
- * RFC2046: boundary := 0*69<bchars> bcharsnospace
- * bchars := bcharsnospace / " "
- * bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
- * "+" / "_" / "," / "-" / "." / "/" / ":" / "=" / "?"
- */
- const char *const boundary = "o_JOU,-LJU:ylnyp'Lyf0RUoh4P(8THlfd98?575p0";
-
if (name != NULL) {
if (encoding == DILLO_HTML_ENC_MULTIPART) {
if (url->len == 0) {
dStr_append(url, "--");
dStr_append(url, boundary);
}
+ // todo: encode name (RFC 2231) [coming soon]
dStr_sprintfa(url,
"\n"
"Content-Disposition: form-data; name=\"%s\"\n"
@@ -3862,6 +3856,75 @@ static void
//}
/*
+ * Get the values for a "successful control".
+ */
+static void Html_get_input_values(const DilloHtmlInput *input,
+ bool active_submit, Dlist *values)
+{
+ switch (input->type) {
+ case DILLO_HTML_INPUT_TEXT:
+ case DILLO_HTML_INPUT_PASSWORD:
+ EntryResource *entryres;
+ entryres = (EntryResource*)((Embed*)input->widget)->getResource();
+ dList_append(values, dStr_new(entryres->getText()));
+ break;
+ case DILLO_HTML_INPUT_TEXTAREA:
+ MultiLineTextResource *textres;
+ textres = (MultiLineTextResource*)((Embed*)input->widget)->getResource();
+ dList_append(values, dStr_new(textres->getText()));
+ break;
+ case DILLO_HTML_INPUT_CHECKBOX:
+ case DILLO_HTML_INPUT_RADIO:
+ ToggleButtonResource *cb_r;
+ cb_r = (ToggleButtonResource*)((Embed*)input->widget)->getResource();
+ if (input->name && input->init_str && cb_r->isActivated()) {
+ dList_append(values, dStr_new(input->init_str));
+ }
+ break;
+ case DILLO_HTML_INPUT_SUBMIT:
+ case DILLO_HTML_INPUT_BUTTON_SUBMIT:
+ if (active_submit)
+ dList_append(values, dStr_new(input->init_str));
+ break;
+ case DILLO_HTML_INPUT_HIDDEN:
+ dList_append(values, dStr_new(input->init_str));
+ break;
+ case DILLO_HTML_INPUT_SELECT:
+ case DILLO_HTML_INPUT_SEL_LIST:
+ { // brackets for compiler happiness.
+ SelectionResource *sel_res =
+ (SelectionResource*)((Embed*)input->widget)->getResource();
+ int size = input->select->options->size ();
+ for (int i = 0; i < size; i++) {
+ if (sel_res->isSelected(i)) {
+ DilloHtmlOption *option = input->select->options->get(i);
+ char *val = option->value ? option->value : option->content;
+ dList_append(values, dStr_new(val));
+ }
+ }
+ break;
+ }
+// case DILLO_HTML_INPUT_INDEX:
+// success = Html_urlencode_append(DataStr,
+// gtk_entry_get_text(GTK_ENTRY(input->widget)));
+// break;
+// case DILLO_HTML_INPUT_IMAGE:
+// if (input->widget == submit) {
+// dList_append(dStr_new(input->init_str));
+// will have to be modified to handle enctype="multipart/form-data"
+// Html_append_clickpos(DataStr, input->name, click_x, click_y);
+// }
+// break;
+ case DILLO_HTML_INPUT_FILE:
+ MSG("Data from file input not submitted\n");
+ // If multiple files are submitted, use multipart/mixed.
+ break;
+ default:
+ break;
+ }
+}
+
+/*
* Submit the form containing the submit input by making a new query URL
* and sending it with a_Nav_push.
* (Called by GTK+)
@@ -3879,80 +3942,77 @@ static void Html_submit_form2(DilloHtml *html, DilloHtmlForm *form,
if ((form->method == DILLO_HTML_METHOD_GET) ||
(form->method == DILLO_HTML_METHOD_POST)) {
Dstr *DataStr = dStr_sized_new(4096);
+ Dstr *boundary;
+ int i;
+ bool success = true;
_MSG("Html_submit_form2: form->action=%s\n",URL_STR_(form->action));
-
- for (input_idx = 0; input_idx < form->inputs->size(); input_idx++) {
- input = form->inputs->getRef (input_idx);
- switch (input->type) {
- case DILLO_HTML_INPUT_TEXT:
- case DILLO_HTML_INPUT_PASSWORD:
- EntryResource *entryres;
- entryres = (EntryResource*)((Embed*)input->widget)->getResource();
- Html_append_input(form->enc, DataStr, input->name,
- entryres->getText());
- break;
- case DILLO_HTML_INPUT_TEXTAREA:
- MultiLineTextResource *textres;
- textres = (MultiLineTextResource*)((Embed*)input->widget)
- ->getResource();
- Html_append_input(form->enc, DataStr, input->name,
- textres->getText());
- break;
- case DILLO_HTML_INPUT_CHECKBOX:
- case DILLO_HTML_INPUT_RADIO:
- ToggleButtonResource *cb_r;
- cb_r=(ToggleButtonResource*)((Embed*)input->widget)->getResource();
- if (input->name && input->init_str && cb_r->isActivated()) {
- Html_append_input(form->enc, DataStr, input->name,
- input->init_str);
+
+ if (form->enc == DILLO_HTML_ENC_MULTIPART) {
+ /* choose a boundary string */
+ const int max_tries = 10;
+ Dlist *values = dList_new(5);
+ success = false;
+
+ /* fill DataStr with names and values */
+ for (input_idx = 0; input_idx < form->inputs->size(); input_idx++) {
+ bool active_submit;
+ input = form->inputs->getRef (input_idx);
+ active_submit = (e_input_idx == input_idx) &&
+ (form->num_submit_buttons > 0) &&
+ ((input->type == DILLO_HTML_INPUT_SUBMIT) ||
+ (input->type == DILLO_HTML_INPUT_BUTTON_SUBMIT));
+ Html_get_input_values(input, active_submit, values);
+
+ if (input->name)
+ dStr_append(DataStr, input->name);
+ for (i = 0; i < dList_length(values); i++) {
+ Dstr *val = (Dstr *) dList_nth_data(values, 0);
+ dList_remove(values, val);
+ dStr_append(DataStr, val->str);
+ dStr_free(val, 1);
}
- break;
- case DILLO_HTML_INPUT_HIDDEN:
- Html_append_input(form->enc, DataStr, input->name,
- input->init_str);
- break;
- case DILLO_HTML_INPUT_SELECT:
- case DILLO_HTML_INPUT_SEL_LIST:
- { // brackets for compiler happiness.
- SelectionResource *sel_res =
- (SelectionResource*)((Embed*)input->widget)->getResource();
- int size = input->select->options->size ();
- for (int i = 0; i < size; i++) {
- if (sel_res->isSelected(i)) {
- DilloHtmlOption *option =
- input->select->options->get (i);
- char *val = option->value ? option->value : option->content;
- Html_append_input(form->enc, DataStr, input->name, val);
- }
+ }
+
+ /* generate a boundary that is not contained within the data */
+ boundary = dStr_sized_new(80);
+ for (i = 0; i < max_tries && !success; i++) {
+ // Firefox-style boundary
+ dStr_sprintf(boundary, "---------------------------%d%d%d",
+ rand(), rand(), rand());
+ dStr_truncate(boundary, 70);
+ success = !strstr(DataStr->str, boundary->str);
+ }
+ dList_free(values);
+ dStr_truncate(DataStr, 0);
+ }
+
+ if (success) {
+ /* build query data string */
+ Dlist *values = dList_new(5);
+ for (input_idx = 0; input_idx < form->inputs->size(); input_idx++) {
+ bool active_submit;
+ input = form->inputs->getRef (input_idx);
+ active_submit = (e_input_idx == input_idx) &&
+ (form->num_submit_buttons > 0) &&
+ ((input->type == DILLO_HTML_INPUT_SUBMIT) ||
+ (input->type == DILLO_HTML_INPUT_BUTTON_SUBMIT));
+ Html_get_input_values(input, active_submit, values);
+
+ for (i = 0; i < dList_length(values); i++) {
+ Dstr *val = (Dstr *) dList_nth_data(values, 0);
+ dList_remove(values, val);
+ Html_append_input(form->enc, boundary->str, DataStr,
+ input->name, val->str);
+ dStr_free(val, 1);
}
- break;
}
-// case DILLO_HTML_INPUT_INDEX:
-// Html_urlencode_append(DataStr,
-// gtk_entry_get_text(GTK_ENTRY(input->widget)));
-// break;
-// case DILLO_HTML_INPUT_IMAGE:
-// if (input->widget == submit) {
-// will have to be modified for handle enctype="multipart/form-data"
-// Html_append_input(DataStr, input->name, input->init_str);
-// Html_append_clickpos(DataStr, input->name, click_x, click_y);
-// }
-// break;
- case DILLO_HTML_INPUT_FILE:
- MSG("Data from file input not submitted\n");
- // If multiple files are submitted, multipart/mixed should be used.
- break;
- case DILLO_HTML_INPUT_SUBMIT:
- case DILLO_HTML_INPUT_BUTTON_SUBMIT:
- if (input_idx == e_input_idx && form->num_submit_buttons > 0)
- Html_append_input(form->enc, DataStr, input->name,
- input->init_str);
- break;
- default:
- break;
- } /* switch */
- } /* for (inputs) */
+ dList_free(values);
+ } else {
+ // can only be a bug or a weakness that allows the boundary string
+ // to be predicted.
+ MSG_ERR("Html_submit_form2: cannot construct data string.\n");
+ }
if (DataStr->len > 0) {
if (form->enc == DILLO_HTML_ENC_URLENCODING) {
@@ -3962,6 +4022,9 @@ static void Html_submit_form2(DilloHtml *html, DilloHtmlForm *form,
dStr_append(DataStr, "--");
}
}
+
+ if (form->enc == DILLO_HTML_ENC_MULTIPART)
+ dStr_free(boundary, 1);
/* form->action was previously resolved against base URL */
action_str = dStrdup(URL_STR(form->action));