mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Merge branch 'elinks-0.12' into elinks-0.13
Conflicts: AUTHORS
This commit is contained in:
commit
0ec4f380fa
2
AUTHORS
2
AUTHORS
@ -457,6 +457,8 @@ Peder Stray <peder@ifi.uio.no>
|
|||||||
Fix handling of key presses turning up as key prefixes
|
Fix handling of key presses turning up as key prefixes
|
||||||
|
|
||||||
Peter Collingbourne <peter@peter.uk.to>
|
Peter Collingbourne <peter@peter.uk.to>
|
||||||
|
Allows relicensing under GPLv2-or-later and linking with OpenSSL
|
||||||
|
Fixed bug relating to newlines in hidden input fields
|
||||||
Fixed compiler errors and warnings in src/util/random.c where CONFIG_SSL undefined
|
Fixed compiler errors and warnings in src/util/random.c where CONFIG_SSL undefined
|
||||||
|
|
||||||
Peter Gervai <grin@tolna.net>
|
Peter Gervai <grin@tolna.net>
|
||||||
|
2
NEWS
2
NEWS
@ -75,6 +75,8 @@ ELinks 0.12pre2.GIT now:
|
|||||||
To be released as 0.12pre3, 0.12rc1, or even 0.12.0. This branch also
|
To be released as 0.12pre3, 0.12rc1, or even 0.12.0. This branch also
|
||||||
includes the changes listed under ``ELinks 0.11.5.GIT'' below.
|
includes the changes listed under ``ELinks 0.11.5.GIT'' below.
|
||||||
|
|
||||||
|
* Preserve newlines in hidden input fields, and submit them as CRLF.
|
||||||
|
Previously, they could turn into spaces or disappear entirely.
|
||||||
* Perl scripts can use modules that dynamically load C libraries, like
|
* Perl scripts can use modules that dynamically load C libraries, like
|
||||||
XML::LibXML::SAX does.
|
XML::LibXML::SAX does.
|
||||||
* enhancement: Updated ISO 8859-7, ISO 8859-16, KOI8-R, and MacRoman.
|
* enhancement: Updated ISO 8859-7, ISO 8859-16, KOI8-R, and MacRoman.
|
||||||
|
@ -287,7 +287,9 @@ html_input(struct html_context *html_context, unsigned char *a,
|
|||||||
mem_free(al);
|
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);
|
fc->default_value = get_attr_val(a, "value", cp);
|
||||||
if (!fc->default_value) {
|
if (!fc->default_value) {
|
||||||
if (fc->type == FC_CHECKBOX)
|
if (fc->type == FC_CHECKBOX)
|
||||||
|
@ -179,9 +179,11 @@ next_attr:
|
|||||||
|
|
||||||
/* parse_quoted_value: */
|
/* parse_quoted_value: */
|
||||||
while (*(++e) != quote) {
|
while (*(++e) != quote) {
|
||||||
if (*e == ASCII_CR) continue;
|
|
||||||
if (!*e) goto parse_error;
|
if (!*e) goto parse_error;
|
||||||
if (*e != ASCII_TAB && *e != ASCII_LF)
|
if (flags & HTML_ATTR_LITERAL_NL)
|
||||||
|
add_chr(attr, attrlen, *e);
|
||||||
|
else if (*e == ASCII_CR) continue;
|
||||||
|
else if (*e != ASCII_TAB && *e != ASCII_LF)
|
||||||
add_chr(attr, attrlen, *e);
|
add_chr(attr, attrlen, *e);
|
||||||
else if (!(flags & HTML_ATTR_EAT_NL))
|
else if (!(flags & HTML_ATTR_EAT_NL))
|
||||||
add_chr(attr, attrlen, ' ');
|
add_chr(attr, attrlen, ' ');
|
||||||
|
@ -25,6 +25,10 @@ enum html_attr_flags {
|
|||||||
/* If HTML_ATTR_NO_CONV is set, then convert_string() is not called
|
/* If HTML_ATTR_NO_CONV is set, then convert_string() is not called
|
||||||
* on value. Unused for now. */
|
* on value. Unused for now. */
|
||||||
/* HTML_ATTR_NO_CONV = 4, */
|
/* HTML_ATTR_NO_CONV = 4, */
|
||||||
|
|
||||||
|
/* If HTML_ATTR_LITERAL_NL is set, carriage return, newline and tab
|
||||||
|
* characters are returned literally. */
|
||||||
|
HTML_ATTR_LITERAL_NL = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Parses html element attributes.
|
/* 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(). */
|
/* Wrappers for get_attr_value(). */
|
||||||
#define get_attr_val(e, name, cp) get_attr_value(e, name, cp, HTML_ATTR_NONE)
|
#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 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))
|
#define has_attr(e, name, cp) (!!get_attr_value(e, name, cp, HTML_ATTR_TEST))
|
||||||
|
|
||||||
|
@ -807,6 +807,30 @@ get_successful_controls(struct document_view *doc_view,
|
|||||||
sort_submitted_values(list);
|
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] == '\r') {
|
||||||
|
if (sv->value[i+1] != '\n')
|
||||||
|
add_crlf_to_string(&newtext);
|
||||||
|
} else if (sv->value[i] == '\n')
|
||||||
|
add_crlf_to_string(&newtext);
|
||||||
|
else
|
||||||
|
add_char_to_string(&newtext, sv->value[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newtext.source;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encode_controls(LIST_OF(struct submitted_value) *l, struct string *data,
|
encode_controls(LIST_OF(struct submitted_value) *l, struct string *data,
|
||||||
int cp_from, int cp_to)
|
int cp_from, int cp_to)
|
||||||
@ -850,6 +874,8 @@ encode_controls(LIST_OF(struct submitted_value) *l, struct string *data,
|
|||||||
|
|
||||||
p2 = convert_string(convert_table, sv->value,
|
p2 = convert_string(convert_table, sv->value,
|
||||||
strlen(sv->value), -1, CSM_FORM, NULL, NULL, NULL);
|
strlen(sv->value), -1, CSM_FORM, NULL, NULL, NULL);
|
||||||
|
} else if (sv->type == FC_HIDDEN) {
|
||||||
|
p2 = encode_crlf(sv);
|
||||||
} else {
|
} else {
|
||||||
p2 = stracpy(sv->value);
|
p2 = stracpy(sv->value);
|
||||||
}
|
}
|
||||||
@ -1120,6 +1146,10 @@ encode_text_plain(LIST_OF(struct submitted_value) *l, struct string *data,
|
|||||||
value = area51 = encode_textarea(sv);
|
value = area51 = encode_textarea(sv);
|
||||||
if (!area51) break;
|
if (!area51) break;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
case FC_HIDDEN:
|
||||||
|
if (!area51) value = area51 = encode_crlf(sv);
|
||||||
|
if (!area51) break;
|
||||||
|
/* Fall through */
|
||||||
case FC_TEXT:
|
case FC_TEXT:
|
||||||
case FC_PASSWORD:
|
case FC_PASSWORD:
|
||||||
/* Convert back to original encoding (see
|
/* Convert back to original encoding (see
|
||||||
|
@ -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);
|
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(struct submitted_value *sv);
|
||||||
void done_submitted_value_list(LIST_OF(struct submitted_value) *list);
|
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);
|
struct uri *get_form_uri(struct session *ses, struct document_view *doc_view, struct form_control *fc);
|
||||||
|
|
||||||
|
@ -488,9 +488,7 @@ unsigned char *
|
|||||||
encode_textarea(struct submitted_value *sv)
|
encode_textarea(struct submitted_value *sv)
|
||||||
{
|
{
|
||||||
struct form_control *fc;
|
struct form_control *fc;
|
||||||
struct string newtext;
|
|
||||||
void *blabla;
|
void *blabla;
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(sv && sv->value);
|
assert(sv && sv->value);
|
||||||
if_assert_failed return NULL;
|
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);
|
blabla = format_text(sv->value, fc->cols, fc->wrap, 1);
|
||||||
mem_free_if(blabla);
|
mem_free_if(blabla);
|
||||||
|
|
||||||
if (!init_string(&newtext)) return NULL;
|
return encode_crlf(sv);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
2
test/server/crlf.conf
Normal file
2
test/server/crlf.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
set document.browse.forms.confirm_submit = 0
|
||||||
|
set ecmascript.enable = 1
|
121
test/server/crlf.py
Executable file
121
test/server/crlf.py
Executable file
@ -0,0 +1,121 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
from BaseHTTPServer import *
|
||||||
|
import tempfile
|
||||||
|
import signal
|
||||||
|
|
||||||
|
r, w = os.pipe()
|
||||||
|
|
||||||
|
C_CR = 0
|
||||||
|
C_LF = 1
|
||||||
|
C_CRLF = 2
|
||||||
|
|
||||||
|
E_Raw = 0
|
||||||
|
E_Entity = 1
|
||||||
|
E_JavaScript = 2
|
||||||
|
|
||||||
|
F_Hidden = 0
|
||||||
|
F_TextArea = 1
|
||||||
|
|
||||||
|
def encode(ch, encoding):
|
||||||
|
if ch == C_CRLF:
|
||||||
|
return encode(C_CR, encoding) + encode(C_LF, encoding)
|
||||||
|
if ch == C_CR:
|
||||||
|
if encoding == E_Raw:
|
||||||
|
return "\r"
|
||||||
|
if encoding == E_JavaScript:
|
||||||
|
return "\\r"
|
||||||
|
if encoding == E_Entity:
|
||||||
|
return "
"
|
||||||
|
if ch == C_LF:
|
||||||
|
if encoding == E_Raw:
|
||||||
|
return "\n"
|
||||||
|
if encoding == E_JavaScript:
|
||||||
|
return "\\n"
|
||||||
|
if encoding == E_Entity:
|
||||||
|
return "
"
|
||||||
|
|
||||||
|
def get_form(ch, encoding, field):
|
||||||
|
text = "foo" + encode(ch, encoding) + "bar"
|
||||||
|
if encoding == E_JavaScript:
|
||||||
|
text_initial = ""
|
||||||
|
else:
|
||||||
|
text_initial = text
|
||||||
|
|
||||||
|
s = """<html>
|
||||||
|
<head>
|
||||||
|
<title>Form Test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form id="form1" name="form1" action="http://127.0.0.1:8090/">
|
||||||
|
"""
|
||||||
|
if field == F_Hidden:
|
||||||
|
s += '<input type="hidden" id="field1" name="field1" value="' + text_initial + '">'
|
||||||
|
elif field == F_TextArea:
|
||||||
|
s += '<textarea id="field1" name="field1">' + text_initial + '</textarea>'
|
||||||
|
s += "\n</form>"
|
||||||
|
if encoding == E_JavaScript:
|
||||||
|
s += """
|
||||||
|
<script>
|
||||||
|
document.form1.field1.value = '%s';
|
||||||
|
</script>""" % (text)
|
||||||
|
|
||||||
|
s += "</body></html>"
|
||||||
|
return s
|
||||||
|
|
||||||
|
class forwarder(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
w.write(self.path + "\n")
|
||||||
|
w.flush()
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-Type", "text/plain")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write("Dummy response")
|
||||||
|
|
||||||
|
def runtest(r, *args):
|
||||||
|
form = get_form(*args)
|
||||||
|
|
||||||
|
tmpfile, tmpname = tempfile.mkstemp(".html")
|
||||||
|
tmpfile = os.fdopen(tmpfile, 'w')
|
||||||
|
tmpfile.write(form)
|
||||||
|
tmpfile.close()
|
||||||
|
|
||||||
|
linkspid = os.spawnlp(os.P_NOWAIT, 'elinks', 'elinks',
|
||||||
|
'-config-dir', os.getcwd(),
|
||||||
|
'-config-file', 'crlf.conf',
|
||||||
|
'-no-connect', '1',
|
||||||
|
'-auto-submit', '1',
|
||||||
|
tmpname)
|
||||||
|
path = r.readline()
|
||||||
|
os.kill(linkspid, signal.SIGINT)
|
||||||
|
os.waitpid(linkspid, 0)
|
||||||
|
|
||||||
|
os.unlink(tmpname)
|
||||||
|
|
||||||
|
return path
|
||||||
|
|
||||||
|
pid = os.fork()
|
||||||
|
|
||||||
|
if pid:
|
||||||
|
os.close(w)
|
||||||
|
r = os.fdopen(r)
|
||||||
|
|
||||||
|
paths = []
|
||||||
|
|
||||||
|
for c in [C_CR, C_LF, C_CRLF]:
|
||||||
|
for e in [E_Raw, E_Entity, E_JavaScript]:
|
||||||
|
for f in [F_Hidden, F_TextArea]:
|
||||||
|
paths.append(("%d %d %d " % (c, e, f)) + runtest(r, c, e, f))
|
||||||
|
|
||||||
|
for path in paths:
|
||||||
|
print path,
|
||||||
|
|
||||||
|
os.kill(pid, signal.SIGTERM)
|
||||||
|
os.waitpid(pid, 0)
|
||||||
|
else:
|
||||||
|
os.close(r)
|
||||||
|
w = os.fdopen(w, 'w')
|
||||||
|
server_address = ('127.0.0.1', 8090)
|
||||||
|
httpd = HTTPServer(server_address, forwarder)
|
||||||
|
httpd.serve_forever()
|
Loading…
Reference in New Issue
Block a user