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
signature.asc
Description: Digital signature
_______________________________________________ elinks-dev mailing list elinks-dev@linuxfromscratch.org http://linuxfromscratch.org/mailman/listinfo/elinks-dev