summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/form.cc792
1 files changed, 400 insertions, 392 deletions
diff --git a/src/form.cc b/src/form.cc
index 6a7f167f..a98a3fea 100644
--- a/src/form.cc
+++ b/src/form.cc
@@ -41,20 +41,6 @@ class DilloHtmlInput;
typedef struct _DilloHtmlSelect DilloHtmlSelect;
typedef struct _DilloHtmlOption DilloHtmlOption;
-static Dstr *Html_encode_text(iconv_t encoder, Dstr **input);
-static void Html_urlencode_append(Dstr *str, const char *val);
-static void Html_append_input_urlencode(Dstr *data, const char *name,
- const char *value);
-static void Html_append_input_multipart_files(Dstr* data, const char *boundary,
- const char *name, Dstr *file,
- const char *filename);
-static void Html_append_input_multipart(Dstr *data, const char *boundary,
- const char *name, const char *value);
-static void Html_append_clickpos_urlencode(Dstr *data,
- Dstr *name, int x,int y);
-static void Html_append_clickpos_multipart(Dstr *data, const char *boundary,
- Dstr *name, int x, int y);
-
static dw::core::ui::Embed *Html_input_image(DilloHtml *html,
const char *tag, int tagsize);
@@ -94,6 +80,25 @@ class DilloHtmlForm {
DilloHtml *html;
void eventHandler(dw::core::ui::Resource *resource,
int click_x, int click_y);
+ DilloUrl *buildQueryUrl(DilloHtmlInput *input, int click_x, int click_y);
+ Dstr *buildQueryData(DilloHtmlInput *active_submit, int x, int y);
+ char *makeMultipartBoundary(iconv_t encoder, DilloHtmlInput *active_submit);
+ Dstr *encodeText(iconv_t encoder, Dstr **input);
+ void urlencodeAppend(Dstr *str, const char *val);
+ void appendInputUrlencode(Dstr *data,
+ const char *name, const char *value);
+ void appendInputMultipartFiles(Dstr* data,
+ const char *boundary,
+ const char *name, Dstr *file,
+ const char *filename);
+ void appendInputMultipart(Dstr *data,
+ const char *boundary,
+ const char *name,
+ const char *value);
+ void appendClickposUrlencode(Dstr *data, Dstr *name, int x,int y);
+ void appendClickposMultipart(Dstr *data,
+ const char *boundary,
+ Dstr *name, int x, int y);
public: //BUG: for now everything is public
DilloHtmlMethod method;
@@ -123,9 +128,6 @@ public:
const char *init_str,
DilloHtmlSelect *select,
bool_t init_val);
- DilloUrl *buildQueryUrl(DilloHtmlInput *input, int click_x, int click_y);
- Dstr *buildQueryData(DilloHtmlInput *active_submit, int x, int y);
- char *makeMultipartBoundary(iconv_t encoder, DilloHtmlInput *active_submit);
};
class DilloHtmlReceiver:
@@ -944,55 +946,6 @@ DilloHtmlForm::~DilloHtmlForm ()
delete(form_receiver);
}
-/*
- * Get the current input.
- */
-DilloHtmlInput *DilloHtmlForm::getCurrentInput ()
-{
- return inputs->get (inputs->size() - 1);
-}
-
-/*
- * Reset all inputs containing reset to their initial values. In
- * general, reset is the reset button for the form.
- */
-void DilloHtmlForm::reset ()
-{
- int size = inputs->size();
- for (int i = 0; i < size; i++)
- inputs->get(i)->reset();
-}
-
-/*
- * Add a new input, setting the initial values.
- */
-void DilloHtmlForm::addInput(DilloHtmlInputType type,
- dw::core::ui::Embed *embed,
- const char *name,
- const char *init_str,
- DilloHtmlSelect *select,
- bool_t init_val)
-{
- _MSG("name=[%s] init_str=[%s] init_val=[%d]\n",
- name, init_str, init_val);
- DilloHtmlInput *input =
- new DilloHtmlInput (type,embed,name,init_str,select,init_val);
- input->connectTo (form_receiver);
- int ni = inputs->size ();
- inputs->increase ();
- inputs->set (ni,input);
-
- /* some stats */
- if (type == DILLO_HTML_INPUT_PASSWORD ||
- type == DILLO_HTML_INPUT_TEXT) {
- num_entry_fields++;
- } else if (type == DILLO_HTML_INPUT_SUBMIT ||
- type == DILLO_HTML_INPUT_BUTTON_SUBMIT ||
- type == DILLO_HTML_INPUT_IMAGE) {
- num_submit_buttons++;
- }
-}
-
void DilloHtmlForm::eventHandler(dw::core::ui::Resource *resource,
int click_x, int click_y)
{
@@ -1039,94 +992,63 @@ void DilloHtmlForm::eventHandler(dw::core::ui::Resource *resource,
}
/*
- * Return the input with a given resource.
- */
-DilloHtmlInput *DilloHtmlForm::getInput (dw::core::ui::Resource *resource)
-{
- for (int idx = 0; idx < inputs->size(); idx++) {
- DilloHtmlInput *input = inputs->get(idx);
- if (input->embed &&
- resource == input->embed->getResource())
- return input;
- }
- return NULL;
-}
-
-/*
- * Return a Radio input for the given name.
+ * Build a new query URL.
+ * (Called by eventHandler())
+ * click_x and click_y are used only by input images.
*/
-DilloHtmlInput *DilloHtmlForm::getRadioInput (const char *name)
+DilloUrl *DilloHtmlForm::buildQueryUrl(DilloHtmlInput *input,
+ int click_x, int click_y)
{
- for (int idx = 0; idx < inputs->size(); idx++) {
- DilloHtmlInput *input = inputs->get(idx);
- if (input->type == DILLO_HTML_INPUT_RADIO &&
- input->name && !dStrcasecmp(input->name, name))
- return input;
- }
- return NULL;
-}
+ DilloUrl *new_url = NULL;
-/*
- * Generate a boundary string for use in separating the parts of a
- * multipart/form-data submission.
- */
-char *DilloHtmlForm::makeMultipartBoundary(iconv_t encoder,
- DilloHtmlInput *active_submit)
-{
- const int max_tries = 10;
- Dlist *values = dList_new(5);
- Dstr *DataStr = dStr_new("");
- Dstr *boundary = dStr_new("");
- char *ret = NULL;
+ if ((method == DILLO_HTML_METHOD_GET) ||
+ (method == DILLO_HTML_METHOD_POST)) {
+ Dstr *DataStr;
+ DilloHtmlInput *active_submit = NULL;
- /* fill DataStr with names, filenames, and values */
- for (int input_idx = 0; input_idx < inputs->size(); input_idx++) {
- Dstr *dstr;
- DilloHtmlInput *input = inputs->get (input_idx);
- bool is_active_submit = (input == active_submit);
- input->getInputValues(is_active_submit, values);
+ _MSG("DilloHtmlForm::buildQueryUrl: action=%s\n",URL_STR_(action));
- if (input->name) {
- dstr = dStr_new(input->name);
- dstr = Html_encode_text(encoder, &dstr);
- dStr_append_l(DataStr, dstr->str, dstr->len);
- dStr_free(dstr, 1);
- }
- if (input->type == DILLO_HTML_INPUT_FILE) {
- dw::core::ui::LabelButtonResource *lbr =
- (dw::core::ui::LabelButtonResource*)input->embed->getResource();
- const char *filename = lbr->getLabel();
- if (filename[0] && strcmp(filename, input->init_str)) {
- dstr = dStr_new(filename);
- dstr = Html_encode_text(encoder, &dstr);
- dStr_append_l(DataStr, dstr->str, dstr->len);
- dStr_free(dstr, 1);
+ if (num_submit_buttons > 0) {
+ if ((input->type == DILLO_HTML_INPUT_SUBMIT) ||
+ (input->type == DILLO_HTML_INPUT_IMAGE) ||
+ (input->type == DILLO_HTML_INPUT_BUTTON_SUBMIT)) {
+ active_submit = input;
}
}
- int length = dList_length(values);
- for (int i = 0; i < length; i++) {
- dstr = (Dstr *) dList_nth_data(values, 0);
- dList_remove(values, dstr);
- if (input->type != DILLO_HTML_INPUT_FILE)
- dstr = Html_encode_text(encoder, &dstr);
- dStr_append_l(DataStr, dstr->str, dstr->len);
- dStr_free(dstr, 1);
+
+ DataStr = buildQueryData(active_submit, click_x, click_y);
+ if (DataStr) {
+ /* action was previously resolved against base URL */
+ char *action_str = dStrdup(URL_STR(action));
+
+ if (method == DILLO_HTML_METHOD_POST) {
+ new_url = a_Url_new(action_str, NULL, 0, 0, 0);
+ /* new_url keeps the dStr and sets DataStr to NULL */
+ a_Url_set_data(new_url, &DataStr);
+ a_Url_set_flags(new_url, URL_FLAGS(new_url) | URL_Post);
+ if (enc == DILLO_HTML_ENC_MULTIPART)
+ a_Url_set_flags(new_url, URL_FLAGS(new_url) | URL_MultipartEnc);
+ } else {
+ /* remove <fragment> and <query> sections if present */
+ char *url_str, *p;
+ if ((p = strchr(action_str, '#')))
+ *p = 0;
+ if ((p = strchr(action_str, '?')))
+ *p = 0;
+
+ url_str = dStrconcat(action_str, "?", DataStr->str, NULL);
+ new_url = a_Url_new(url_str, NULL, 0, 0, 0);
+ a_Url_set_flags(new_url, URL_FLAGS(new_url) | URL_Get);
+ dFree(url_str);
+ }
+ dStr_free(DataStr, 1);
+ dFree(action_str);
}
+ } else {
+ MSG("DilloHtmlForm::buildQueryUrl: Method unknown\n");
}
- /* generate a boundary that is not contained within the data */
- for (int i = 0; i < max_tries && !ret; i++) {
- // Firefox-style boundary
- dStr_sprintf(boundary, "---------------------------%d%d%d",
- rand(), rand(), rand());
- dStr_truncate(boundary, 70);
- if (dStr_memmem(DataStr, boundary) == NULL)
- ret = boundary->str;
- }
- dList_free(values);
- dStr_free(DataStr, 1);
- dStr_free(boundary, (ret == NULL));
- return ret;
+ return new_url;
}
/*
@@ -1163,14 +1085,14 @@ Dstr *DilloHtmlForm::buildQueryData(DilloHtmlInput *active_submit,
Dstr *name = dStr_new(input->name);
bool is_active_submit = (input == active_submit);
- name = Html_encode_text(encoder, &name);
+ name = encodeText(encoder, &name);
if (input->type == DILLO_HTML_INPUT_IMAGE) {
if (is_active_submit){
if (enc == DILLO_HTML_ENC_URLENCODING)
- Html_append_clickpos_urlencode(DataStr, name, x, y);
+ appendClickposUrlencode(DataStr, name, x, y);
else if (enc == DILLO_HTML_ENC_MULTIPART)
- Html_append_clickpos_multipart(DataStr, boundary, name, x,y);
+ appendClickposMultipart(DataStr, boundary, name, x,y);
}
} else {
input->getInputValues(is_active_submit, values);
@@ -1192,29 +1114,29 @@ Dstr *DilloHtmlForm::buildQueryData(DilloHtmlInput *active_submit,
if (p)
filename = p + 1; /* don't reveal path */
Dstr *dfilename = dStr_new(filename);
- dfilename = Html_encode_text(encoder, &dfilename);
- Html_append_input_multipart_files(DataStr, boundary,
- name->str, file, dfilename->str);
+ dfilename = encodeText(encoder, &dfilename);
+ appendInputMultipartFiles(DataStr, boundary, name->str,
+ file, dfilename->str);
dStr_free(dfilename, 1);
}
dStr_free(file, 1);
} else if (input->type == DILLO_HTML_INPUT_INDEX) {
Dstr *val = (Dstr *) dList_nth_data(values, 0);
dList_remove(values, val);
- val = Html_encode_text(encoder, &val);
- Html_urlencode_append(DataStr, val->str);
+ val = encodeText(encoder, &val);
+ urlencodeAppend(DataStr, val->str);
dStr_free(val, 1);
} else {
int length = dList_length(values), i;
for (i = 0; i < length; i++) {
Dstr *val = (Dstr *) dList_nth_data(values, 0);
dList_remove(values, val);
- val = Html_encode_text(encoder, &val);
+ val = encodeText(encoder, &val);
if (enc == DILLO_HTML_ENC_URLENCODING)
- Html_append_input_urlencode(DataStr, name->str, val->str);
+ appendInputUrlencode(DataStr, name->str, val->str);
else if (enc == DILLO_HTML_ENC_MULTIPART)
- Html_append_input_multipart(DataStr, boundary, name->str,
- val->str);
+ appendInputMultipart(DataStr, boundary,
+ name->str, val->str);
dStr_free(val, 1);
}
}
@@ -1238,63 +1160,340 @@ Dstr *DilloHtmlForm::buildQueryData(DilloHtmlInput *active_submit,
}
/*
- * Build a new query URL.
- * (Called by eventHandler())
- * click_x and click_y are used only by input images.
+ * Generate a boundary string for use in separating the parts of a
+ * multipart/form-data submission.
*/
-DilloUrl *DilloHtmlForm::buildQueryUrl(DilloHtmlInput *input,
- int click_x, int click_y)
+char *DilloHtmlForm::makeMultipartBoundary(iconv_t encoder,
+ DilloHtmlInput *active_submit)
{
- DilloUrl *new_url = NULL;
-
- if ((method == DILLO_HTML_METHOD_GET) ||
- (method == DILLO_HTML_METHOD_POST)) {
- Dstr *DataStr;
- DilloHtmlInput *active_submit = NULL;
+ const int max_tries = 10;
+ Dlist *values = dList_new(5);
+ Dstr *DataStr = dStr_new("");
+ Dstr *boundary = dStr_new("");
+ char *ret = NULL;
- _MSG("DilloHtmlForm::buildQueryUrl: action=%s\n",URL_STR_(action));
+ /* fill DataStr with names, filenames, and values */
+ for (int input_idx = 0; input_idx < inputs->size(); input_idx++) {
+ Dstr *dstr;
+ DilloHtmlInput *input = inputs->get (input_idx);
+ bool is_active_submit = (input == active_submit);
+ input->getInputValues(is_active_submit, values);
- if (num_submit_buttons > 0) {
- if ((input->type == DILLO_HTML_INPUT_SUBMIT) ||
- (input->type == DILLO_HTML_INPUT_IMAGE) ||
- (input->type == DILLO_HTML_INPUT_BUTTON_SUBMIT)) {
- active_submit = input;
+ if (input->name) {
+ dstr = dStr_new(input->name);
+ dstr = encodeText(encoder, &dstr);
+ dStr_append_l(DataStr, dstr->str, dstr->len);
+ dStr_free(dstr, 1);
+ }
+ if (input->type == DILLO_HTML_INPUT_FILE) {
+ dw::core::ui::LabelButtonResource *lbr =
+ (dw::core::ui::LabelButtonResource*)input->embed->getResource();
+ const char *filename = lbr->getLabel();
+ if (filename[0] && strcmp(filename, input->init_str)) {
+ dstr = dStr_new(filename);
+ dstr = encodeText(encoder, &dstr);
+ dStr_append_l(DataStr, dstr->str, dstr->len);
+ dStr_free(dstr, 1);
}
}
+ int length = dList_length(values);
+ for (int i = 0; i < length; i++) {
+ dstr = (Dstr *) dList_nth_data(values, 0);
+ dList_remove(values, dstr);
+ if (input->type != DILLO_HTML_INPUT_FILE)
+ dstr = encodeText(encoder, &dstr);
+ dStr_append_l(DataStr, dstr->str, dstr->len);
+ dStr_free(dstr, 1);
+ }
+ }
- DataStr = buildQueryData(active_submit, click_x, click_y);
- if (DataStr) {
- /* action was previously resolved against base URL */
- char *action_str = dStrdup(URL_STR(action));
+ /* generate a boundary that is not contained within the data */
+ for (int i = 0; i < max_tries && !ret; i++) {
+ // Firefox-style boundary
+ dStr_sprintf(boundary, "---------------------------%d%d%d",
+ rand(), rand(), rand());
+ dStr_truncate(boundary, 70);
+ if (dStr_memmem(DataStr, boundary) == NULL)
+ ret = boundary->str;
+ }
+ dList_free(values);
+ dStr_free(DataStr, 1);
+ dStr_free(boundary, (ret == NULL));
+ return ret;
+}
- if (method == DILLO_HTML_METHOD_POST) {
- new_url = a_Url_new(action_str, NULL, 0, 0, 0);
- /* new_url keeps the dStr and sets DataStr to NULL */
- a_Url_set_data(new_url, &DataStr);
- a_Url_set_flags(new_url, URL_FLAGS(new_url) | URL_Post);
- if (enc == DILLO_HTML_ENC_MULTIPART)
- a_Url_set_flags(new_url, URL_FLAGS(new_url) | URL_MultipartEnc);
- } else {
- /* remove <fragment> and <query> sections if present */
- char *url_str, *p;
- if ((p = strchr(action_str, '#')))
- *p = 0;
- if ((p = strchr(action_str, '?')))
- *p = 0;
+/*
+ * Pass input text through character set encoder.
+ * Return value: same input Dstr if no encoding is needed.
+ new Dstr when encoding (input Dstr is freed).
+ */
+Dstr *DilloHtmlForm::encodeText(iconv_t encoder, Dstr **input)
+{
+ int rc = 0;
+ Dstr *output;
+ const int bufsize = 128;
+ inbuf_t *inPtr;
+ char *buffer, *outPtr;
+ size_t inLeft, outRoom;
+ bool bad_chars = false;
- url_str = dStrconcat(action_str, "?", DataStr->str, NULL);
- new_url = a_Url_new(url_str, NULL, 0, 0, 0);
- a_Url_set_flags(new_url, URL_FLAGS(new_url) | URL_Get);
- dFree(url_str);
- }
- dStr_free(DataStr, 1);
- dFree(action_str);
+ if ((encoder == (iconv_t) -1) || *input == NULL || (*input)->len == 0)
+ return *input;
+
+ output = dStr_new("");
+ inPtr = (*input)->str;
+ inLeft = (*input)->len;
+ buffer = dNew(char, bufsize);
+
+ while ((rc != EINVAL) && (inLeft > 0)) {
+
+ outPtr = buffer;
+ outRoom = bufsize;
+
+ rc = iconv(encoder, &inPtr, &inLeft, &outPtr, &outRoom);
+
+ // iconv() on success, number of bytes converted
+ // -1, errno == EILSEQ illegal byte sequence found
+ // EINVAL partial character ends source buffer
+ // E2BIG destination buffer is full
+ //
+ // GNU iconv has the undocumented(!) behavior that EILSEQ is also
+ // returned when a character cannot be converted.
+
+ dStr_append_l(output, buffer, bufsize - outRoom);
+
+ if (rc == -1) {
+ rc = errno;
+ }
+ if (rc == EILSEQ){
+ /* count chars? (would be utf-8-specific) */
+ bad_chars = true;
+ inPtr++;
+ inLeft--;
+ dStr_append_c(output, '?');
+ } else if (rc == EINVAL) {
+ MSG_ERR("Html_decode_text: bad source string\n");
}
- } else {
- MSG("DilloHtmlForm::buildQueryUrl: Method unknown\n");
}
- return new_url;
+ if (bad_chars) {
+ /*
+ * It might be friendly to inform the caller, who would know whether
+ * it is safe to display the beginning of the string in a message
+ * (isn't, e.g., a password).
+ */
+ MSG_WARN("String cannot be converted cleanly.\n");
+ }
+
+ dFree(buffer);
+ dStr_free(*input, 1);
+
+ return output;
+}
+
+/*
+ * Urlencode 'val' and append it to 'str'
+ */
+void DilloHtmlForm::urlencodeAppend(Dstr *str, const char *val)
+{
+ char *enc_val = a_Url_encode_hex_str(val);
+ dStr_append(str, enc_val);
+ dFree(enc_val);
+}
+
+/*
+ * Append a name-value pair to url data using url encoding.
+ */
+void DilloHtmlForm::appendInputUrlencode(Dstr *data,
+ const char *name,
+ const char *value)
+{
+ if (name && name[0]) {
+ urlencodeAppend(data, name);
+ dStr_append_c(data, '=');
+ urlencodeAppend(data, value);
+ dStr_append_c(data, '&');
+ }
+}
+
+/*
+ * Append files to URL data using multipart encoding.
+ * Currently only accepts one file.
+ */
+void DilloHtmlForm::appendInputMultipartFiles(Dstr* data,
+ const char *boundary,
+ const char *name,
+ Dstr *file,
+ const char *filename)
+{
+ const char *ctype, *ext;
+
+ if (name && name[0]) {
+ (void)a_Misc_get_content_type_from_data(file->str, file->len, &ctype);
+ /* Heuristic: text/plain with ".htm[l]" extension -> text/html */
+ if ((ext = strrchr(filename, '.')) &&
+ !dStrcasecmp(ctype, "text/plain") &&
+ (!dStrcasecmp(ext, ".html") || !dStrcasecmp(ext, ".htm"))) {
+ ctype = "text/html";
+ }
+
+ if (data->len == 0) {
+ dStr_append(data, "--");
+ dStr_append(data, boundary);
+ }
+ // todo: encode name, filename
+ dStr_sprintfa(data,
+ "\r\n"
+ "Content-Disposition: form-data; name=\"%s\"; "
+ "filename=\"%s\"\r\n"
+ "Content-Type: %s\r\n"
+ "\r\n", name, filename, ctype);
+
+ dStr_append_l(data, file->str, file->len);
+
+ dStr_sprintfa(data,
+ "\r\n"
+ "--%s", boundary);
+ }
+}
+
+/*
+ * Append a name-value pair to url data using multipart encoding.
+ */
+void DilloHtmlForm::appendInputMultipart(Dstr *data,
+ const char *boundary,
+ const char *name,
+ const char *value)
+{
+ if (name && name[0]) {
+ if (data->len == 0) {
+ dStr_append(data, "--");
+ dStr_append(data, boundary);
+ }
+ // todo: encode name (RFC 2231) [coming soon]
+ dStr_sprintfa(data,
+ "\r\n"
+ "Content-Disposition: form-data; name=\"%s\"\r\n"
+ "\r\n"
+ "%s\r\n"
+ "--%s",
+ name, value, boundary);
+ }
+}
+
+/*
+ * Append an image button click position to url data using url encoding.
+ */
+void DilloHtmlForm::appendClickposUrlencode(Dstr *data,
+ Dstr *name, int x,int y)
+{
+ if (name->len) {
+ urlencodeAppend(data, name->str);
+ dStr_sprintfa(data, ".x=%d&", x);
+ urlencodeAppend(data, name->str);
+ dStr_sprintfa(data, ".y=%d&", y);
+ } else
+ dStr_sprintfa(data, "x=%d&y=%d&", x, y);
+}
+
+/*
+ * Append an image button click position to url data using multipart encoding.
+ */
+void DilloHtmlForm::appendClickposMultipart(Dstr *data,
+ const char *boundary,
+ Dstr *name, int x, int y)
+{
+ char posstr[16];
+ int orig_len = name->len;
+
+ if (orig_len)
+ dStr_append_c(name, '.');
+ dStr_append_c(name, 'x');
+
+ snprintf(posstr, 16, "%d", x);
+ appendInputMultipart(data, boundary, name->str, posstr);
+ dStr_truncate(name, name->len - 1);
+ dStr_append_c(name, 'y');
+ snprintf(posstr, 16, "%d", y);
+ appendInputMultipart(data, boundary, name->str, posstr);
+ dStr_truncate(name, orig_len);
+}
+
+/*
+ * Get the current input.
+ */
+DilloHtmlInput *DilloHtmlForm::getCurrentInput ()
+{
+ return inputs->get (inputs->size() - 1);
+}
+
+/*
+ * Reset all inputs containing reset to their initial values. In
+ * general, reset is the reset button for the form.
+ */
+void DilloHtmlForm::reset ()
+{
+ int size = inputs->size();
+ for (int i = 0; i < size; i++)
+ inputs->get(i)->reset();
+}
+
+/*
+ * Add a new input, setting the initial values.
+ */
+void DilloHtmlForm::addInput(DilloHtmlInputType type,
+ dw::core::ui::Embed *embed,
+ const char *name,
+ const char *init_str,
+ DilloHtmlSelect *select,
+ bool_t init_val)
+{
+ _MSG("name=[%s] init_str=[%s] init_val=[%d]\n",
+ name, init_str, init_val);
+ DilloHtmlInput *input =
+ new DilloHtmlInput (type,embed,name,init_str,select,init_val);
+ input->connectTo (form_receiver);
+ int ni = inputs->size ();
+ inputs->increase ();
+ inputs->set (ni,input);
+
+ /* some stats */
+ if (type == DILLO_HTML_INPUT_PASSWORD ||
+ type == DILLO_HTML_INPUT_TEXT) {
+ num_entry_fields++;
+ } else if (type == DILLO_HTML_INPUT_SUBMIT ||
+ type == DILLO_HTML_INPUT_BUTTON_SUBMIT ||
+ type == DILLO_HTML_INPUT_IMAGE) {
+ num_submit_buttons++;
+ }
+}
+
+/*
+ * Return the input with a given resource.
+ */
+DilloHtmlInput *DilloHtmlForm::getInput (dw::core::ui::Resource *resource)
+{
+ for (int idx = 0; idx < inputs->size(); idx++) {
+ DilloHtmlInput *input = inputs->get(idx);
+ if (input->embed &&
+ resource == input->embed->getResource())
+ return input;
+ }
+ return NULL;
+}
+
+/*
+ * Return a Radio input for the given name.
+ */
+DilloHtmlInput *DilloHtmlForm::getRadioInput (const char *name)
+{
+ for (int idx = 0; idx < inputs->size(); idx++) {
+ DilloHtmlInput *input = inputs->get(idx);
+ if (input->type == DILLO_HTML_INPUT_RADIO &&
+ input->name && !dStrcasecmp(input->name, name))
+ return input;
+ }
+ return NULL;
}
/*
@@ -1554,197 +1753,6 @@ void DilloHtmlInput::reset ()
*/
/*
- * Pass input text through character set encoder.
- * Return value: same input Dstr if no encoding is needed.
- new Dstr when encoding (input Dstr is freed).
- */
-static Dstr *Html_encode_text(iconv_t encoder, Dstr **input)
-{
- int rc = 0;
- Dstr *output;
- const int bufsize = 128;
- inbuf_t *inPtr;
- char *buffer, *outPtr;
- size_t inLeft, outRoom;
- bool bad_chars = false;
-
- if ((encoder == (iconv_t) -1) || *input == NULL || (*input)->len == 0)
- return *input;
-
- output = dStr_new("");
- inPtr = (*input)->str;
- inLeft = (*input)->len;
- buffer = dNew(char, bufsize);
-
- while ((rc != EINVAL) && (inLeft > 0)) {
-
- outPtr = buffer;
- outRoom = bufsize;
-
- rc = iconv(encoder, &inPtr, &inLeft, &outPtr, &outRoom);
-
- // iconv() on success, number of bytes converted
- // -1, errno == EILSEQ illegal byte sequence found
- // EINVAL partial character ends source buffer
- // E2BIG destination buffer is full
- //
- // GNU iconv has the undocumented(!) behavior that EILSEQ is also
- // returned when a character cannot be converted.
-
- dStr_append_l(output, buffer, bufsize - outRoom);
-
- if (rc == -1) {
- rc = errno;
- }
- if (rc == EILSEQ){
- /* count chars? (would be utf-8-specific) */
- bad_chars = true;
- inPtr++;
- inLeft--;
- dStr_append_c(output, '?');
- } else if (rc == EINVAL) {
- MSG_ERR("Html_decode_text: bad source string\n");
- }
- }
-
- if (bad_chars) {
- /*
- * It might be friendly to inform the caller, who would know whether
- * it is safe to display the beginning of the string in a message
- * (isn't, e.g., a password).
- */
- MSG_WARN("String cannot be converted cleanly.\n");
- }
-
- dFree(buffer);
- dStr_free(*input, 1);
-
- return output;
-}
-
-/*
- * Urlencode 'val' and append it to 'str'
- */
-static void Html_urlencode_append(Dstr *str, const char *val)
-{
- char *enc_val = a_Url_encode_hex_str(val);
- dStr_append(str, enc_val);
- dFree(enc_val);
-}
-
-/*
- * Append a name-value pair to url data using url encoding.
- */
-static void Html_append_input_urlencode(Dstr *data, const char *name,
- const char *value)
-{
- if (name && name[0]) {
- Html_urlencode_append(data, name);
- dStr_append_c(data, '=');
- Html_urlencode_append(data, value);
- dStr_append_c(data, '&');
- }
-}
-
-/*
- * Append files to URL data using multipart encoding.
- * Currently only accepts one file.
- */
-static void Html_append_input_multipart_files(Dstr* data, const char *boundary,
- const char *name, Dstr *file,
- const char *filename)
-{
- const char *ctype, *ext;
-
- if (name && name[0]) {
- (void)a_Misc_get_content_type_from_data(file->str, file->len, &ctype);
- /* Heuristic: text/plain with ".htm[l]" extension -> text/html */
- if ((ext = strrchr(filename, '.')) &&
- !dStrcasecmp(ctype, "text/plain") &&
- (!dStrcasecmp(ext, ".html") || !dStrcasecmp(ext, ".htm"))) {
- ctype = "text/html";
- }
-
- if (data->len == 0) {
- dStr_append(data, "--");
- dStr_append(data, boundary);
- }
- // todo: encode name, filename
- dStr_sprintfa(data,
- "\r\n"
- "Content-Disposition: form-data; name=\"%s\"; "
- "filename=\"%s\"\r\n"
- "Content-Type: %s\r\n"
- "\r\n", name, filename, ctype);
-
- dStr_append_l(data, file->str, file->len);
-
- dStr_sprintfa(data,
- "\r\n"
- "--%s", boundary);
- }
-}
-
-/*
- * Append a name-value pair to url data using multipart encoding.
- */
-static void Html_append_input_multipart(Dstr *data, const char *boundary,
- const char *name, const char *value)
-{
- if (name && name[0]) {
- if (data->len == 0) {
- dStr_append(data, "--");
- dStr_append(data, boundary);
- }
- // todo: encode name (RFC 2231) [coming soon]
- dStr_sprintfa(data,
- "\r\n"
- "Content-Disposition: form-data; name=\"%s\"\r\n"
- "\r\n"
- "%s\r\n"
- "--%s",
- name, value, boundary);
- }
-}
-
-/*
- * Append an image button click position to url data using url encoding.
- */
-static void Html_append_clickpos_urlencode(Dstr *data,
- Dstr *name, int x,int y)
-{
- if (name->len) {
- Html_urlencode_append(data, name->str);
- dStr_sprintfa(data, ".x=%d&", x);
- Html_urlencode_append(data, name->str);
- dStr_sprintfa(data, ".y=%d&", y);
- } else
- dStr_sprintfa(data, "x=%d&y=%d&", x, y);
-}
-
-/*
- * Append an image button click position to url data using multipart encoding.
- */
-static void Html_append_clickpos_multipart(Dstr *data, const char *boundary,
- Dstr *name, int x, int y)
-{
- char posstr[16];
- int orig_len = name->len;
-
- if (orig_len)
- dStr_append_c(name, '.');
- dStr_append_c(name, 'x');
-
- snprintf(posstr, 16, "%d", x);
- Html_append_input_multipart(data, boundary, name->str, posstr);
- dStr_truncate(name, name->len - 1);
- dStr_append_c(name, 'y');
- snprintf(posstr, 16, "%d", y);
- Html_append_input_multipart(data, boundary, name->str, posstr);
- dStr_truncate(name, orig_len);
-}
-
-/*
* Create input image for the form
*/
static dw::core::ui::Embed *Html_input_image(DilloHtml *html,