Hello,

Currently ELinks reinterprets a literal newline within the value
attribute of a hidden input field as a space character.  This is
inconsistent with the HTML specification and the behaviour of other
browsers.  This patch fixes the problem.  Some changes are also
made to ensure that these fields are URL encoded using CR LF pairs
when submitted.

The same situation may also apply to other fields (e.g. values of
<option> tags) but I haven't checked this.

Thanks,

---
 src/document/html/parser/forms.c |    4 +++-
 src/document/html/parser/parse.c |    3 ++-
 src/document/html/parser/parse.h |    5 +++++
 src/viewer/text/form.c           |   27 +++++++++++++++++++++++++++
 src/viewer/text/form.h           |    1 +
 src/viewer/text/textarea.c       |   13 +------------
 6 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/src/document/html/parser/forms.c b/src/document/html/parser/forms.c
index 1a717a8..c5d9ae1 100644
--- a/src/document/html/parser/forms.c
+++ b/src/document/html/parser/forms.c
@@ -287,7 +287,9 @@ html_input(struct html_context *html_context, unsigned char 
*a,
                mem_free(al);
        }
 
-       if (fc->type != FC_FILE)
+       if (fc->type == FC_HIDDEN)
+               fc->default_value = get_lit_attr_val(a, "value", cp);
+       else if (fc->type != FC_FILE)
                fc->default_value = get_attr_val(a, "value", cp);
        if (!fc->default_value) {
                if (fc->type == FC_CHECKBOX)
diff --git a/src/document/html/parser/parse.c b/src/document/html/parser/parse.c
index 74707b1..cfa25e5 100644
--- a/src/document/html/parser/parse.c
+++ b/src/document/html/parser/parse.c
@@ -181,7 +181,8 @@ next_attr:
                        while (*(++e) != quote) {
                                if (*e == ASCII_CR) continue;
                                if (!*e) goto parse_error;
-                               if (*e != ASCII_TAB && *e != ASCII_LF)
+                               if (flags & HTML_ATTR_LITERAL_NL
+                                || (*e != ASCII_TAB && *e != ASCII_LF))
                                        add_chr(attr, attrlen, *e);
                                else if (!(flags & HTML_ATTR_EAT_NL))
                                        add_chr(attr, attrlen, ' ');
diff --git a/src/document/html/parser/parse.h b/src/document/html/parser/parse.h
index 4eaa154..6adfed3 100644
--- a/src/document/html/parser/parse.h
+++ b/src/document/html/parser/parse.h
@@ -25,6 +25,10 @@ enum html_attr_flags {
        /* If HTML_ATTR_NO_CONV is set, then convert_string() is not called
         * on value. Unused for now. */
        /* HTML_ATTR_NO_CONV = 4, */
+
+       /* If HTML_ATTR_LITERAL_NL is set, newline and tab characters are
+        * returned literally. */
+       HTML_ATTR_LITERAL_NL = 8,
 };
 
 /* Parses html element attributes.
@@ -37,6 +41,7 @@ unsigned char *get_attr_value(register unsigned char *e, 
unsigned char *name, in
 
 /* Wrappers for get_attr_value(). */
 #define get_attr_val(e, name, cp) get_attr_value(e, name, cp, HTML_ATTR_NONE)
+#define get_lit_attr_val(e, name, cp) get_attr_value(e, name, cp, 
HTML_ATTR_LITERAL_NL)
 #define get_url_val(e, name, cp) get_attr_value(e, name, cp, HTML_ATTR_EAT_NL)
 #define has_attr(e, name, cp) (!!get_attr_value(e, name, cp, HTML_ATTR_TEST))
 
diff --git a/src/viewer/text/form.c b/src/viewer/text/form.c
index f2b7b9d..841b8b2 100644
--- a/src/viewer/text/form.c
+++ b/src/viewer/text/form.c
@@ -807,6 +807,27 @@ get_successful_controls(struct document_view *doc_view,
        sort_submitted_values(list);
 }
 
+unsigned char *
+encode_crlf(struct submitted_value *sv)
+{
+       struct string newtext;
+       int i;
+
+       assert(sv && sv->value);
+       if_assert_failed return NULL;
+
+       if (!init_string(&newtext)) return NULL;
+
+       for (i = 0; sv->value[i]; i++) {
+               if (sv->value[i] != '\n')
+                       add_char_to_string(&newtext, sv->value[i]);
+               else
+                       add_crlf_to_string(&newtext);
+       }
+
+       return newtext.source;
+}
+
 static void
 encode_controls(LIST_OF(struct submitted_value) *l, struct string *data,
                int cp_from, int cp_to)
@@ -850,6 +871,8 @@ encode_controls(LIST_OF(struct submitted_value) *l, struct 
string *data,
 
                        p2 = convert_string(convert_table, sv->value,
                                            strlen(sv->value), -1, CSM_FORM, 
NULL, NULL, NULL);
+               } else if (sv->type == FC_HIDDEN) {
+                       p2 = encode_crlf(sv);
                } else {
                        p2 = stracpy(sv->value);
                }
@@ -1115,6 +1138,10 @@ encode_text_plain(LIST_OF(struct submitted_value) *l, 
struct string *data,
                add_to_string(data, sv->name);
                add_char_to_string(data, '=');
 
+               if (sv->type == FC_HIDDEN) {
+                       value = encode_crlf(sv);
+               }
+
                switch (sv->type) {
                case FC_TEXTAREA:
                        value = area51 = encode_textarea(sv);
diff --git a/src/viewer/text/form.h b/src/viewer/text/form.h
index 74a9991..79757ba 100644
--- a/src/viewer/text/form.h
+++ b/src/viewer/text/form.h
@@ -99,6 +99,7 @@ struct submitted_value {
 struct submitted_value *init_submitted_value(unsigned char *name, unsigned 
char *value, enum form_type type, struct form_control *fc, int position);
 void done_submitted_value(struct submitted_value *sv);
 void done_submitted_value_list(LIST_OF(struct submitted_value) *list);
+unsigned char *encode_crlf(struct submitted_value *sv);
 
 struct uri *get_form_uri(struct session *ses, struct document_view *doc_view, 
struct form_control *fc);
 
diff --git a/src/viewer/text/textarea.c b/src/viewer/text/textarea.c
index 60a0c60..7749f7b 100644
--- a/src/viewer/text/textarea.c
+++ b/src/viewer/text/textarea.c
@@ -488,9 +488,7 @@ unsigned char *
 encode_textarea(struct submitted_value *sv)
 {
        struct form_control *fc;
-       struct string newtext;
        void *blabla;
-       int i;
 
        assert(sv && sv->value);
        if_assert_failed return NULL;
@@ -503,16 +501,7 @@ encode_textarea(struct submitted_value *sv)
        blabla = format_text(sv->value, fc->cols, fc->wrap, 1);
        mem_free_if(blabla);
 
-       if (!init_string(&newtext)) return NULL;
-
-       for (i = 0; sv->value[i]; i++) {
-               if (sv->value[i] != '\n')
-                       add_char_to_string(&newtext, sv->value[i]);
-               else
-                       add_crlf_to_string(&newtext);
-       }
-
-       return newtext.source;
+       return encode_crlf(sv);
 }
 
 
-- 
1.5.2.4


-- 
Peter

Attachment: signature.asc
Description: Digital signature

_______________________________________________
elinks-dev mailing list
elinks-dev@linuxfromscratch.org
http://linuxfromscratch.org/mailman/listinfo/elinks-dev

Reply via email to