From 0f53941fef749ac22893993427eb5d79e6923176 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Tue, 28 Aug 2007 20:09:37 +0200 Subject: [PATCH 01/18] Introduce test library in util/test.h containing the die() function Fix the die() function to exit with EXIT_FAILURE value as pointed out by Kalle on elinks-dev in <87tzqkxhlp.fsf@Astalo.kon.iki.fi>. --- src/dom/test/dom-select.c | 16 +--------------- src/dom/test/sgml-parser.c | 16 +--------------- src/mime/backend/mailcap.c | 17 +++-------------- src/protocol/ftp/ftp-parser.c | 16 +--------------- src/protocol/test/stub.c | 16 +--------------- src/util/test.h | 23 +++++++++++++++++++++++ 6 files changed, 30 insertions(+), 74 deletions(-) create mode 100644 src/util/test.h diff --git a/src/dom/test/dom-select.c b/src/dom/test/dom-select.c index e4cc6f23..1da1cbfe 100644 --- a/src/dom/test/dom-select.c +++ b/src/dom/test/dom-select.c @@ -15,21 +15,7 @@ #include "dom/select.h" #include "dom/sgml/parser.h" #include "dom/stack.h" - - -void die(const char *msg, ...) -{ - va_list args; - - if (msg) { - va_start(args, msg); - vfprintf(stderr, msg, args); - fputs("\n", stderr); - va_end(args); - } - - exit(!!NULL); -} +#include "util/test.h" int main(int argc, char *argv[]) diff --git a/src/dom/test/sgml-parser.c b/src/dom/test/sgml-parser.c index 5446ccd7..3eca7f1b 100644 --- a/src/dom/test/sgml-parser.c +++ b/src/dom/test/sgml-parser.c @@ -16,6 +16,7 @@ #include "dom/sgml/dump.h" #include "dom/sgml/parser.h" #include "dom/stack.h" +#include "util/test.h" unsigned int number_of_lines = 0; @@ -242,21 +243,6 @@ sgml_error_function(struct sgml_parser *parser, struct dom_string *string, return DOM_CODE_OK; } -static void -die(const char *msg, ...) -{ - va_list args; - - if (msg) { - va_start(args, msg); - vfprintf(stderr, msg, args); - fputs("\n", stderr); - va_end(args); - } - - exit(!!NULL); -} - static int get_opt(char **argref, const char *name, int *argi, int argc, char *argv[], const char *expect_msg) diff --git a/src/mime/backend/mailcap.c b/src/mime/backend/mailcap.c index 1ca637a6..e7b14d61 100644 --- a/src/mime/backend/mailcap.c +++ b/src/mime/backend/mailcap.c @@ -678,6 +678,9 @@ struct module mailcap_mime_module = struct_module( ); #ifdef TEST_MAILCAP + +#include "util/test.h" + /* Some ugly shortcuts for getting defined symbols to work. */ int default_mime_backend, install_signal_handler, @@ -685,20 +688,6 @@ int default_mime_backend, program; LIST_OF(struct terminal) terminals; -void die(const char *msg, ...) -{ - va_list args; - - if (msg) { - va_start(args, msg); - vfprintf(stderr, msg, args); - fputs("\n", stderr); - va_end(args); - } - - exit(1); -} - int main(int argc, char *argv[]) { diff --git a/src/protocol/ftp/ftp-parser.c b/src/protocol/ftp/ftp-parser.c index 197466a5..dbdb677b 100644 --- a/src/protocol/ftp/ftp-parser.c +++ b/src/protocol/ftp/ftp-parser.c @@ -13,21 +13,7 @@ #include "osdep/stat.h" #include "protocol/ftp/parse.h" - - -void die(const char *msg, ...) -{ - va_list args; - - if (msg) { - va_start(args, msg); - vfprintf(stderr, msg, args); - fputs("\n", stderr); - va_end(args); - } - - exit(!!NULL); -} +#include "util/test.h" int main(int argc, char *argv[]) diff --git a/src/protocol/test/stub.c b/src/protocol/test/stub.c index 4ed9b672..8b66e34a 100644 --- a/src/protocol/test/stub.c +++ b/src/protocol/test/stub.c @@ -13,6 +13,7 @@ #include "main/module.h" #include "protocol/user.h" #include "session/session.h" +#include "util/test.h" #define STUB_MODULE(name) \ struct module name = struct_module( \ @@ -38,21 +39,6 @@ STUB_MODULE(smb_protocol_module); STUB_MODULE(uri_rewrite_module); STUB_MODULE(user_protocol_module); -static void -die(const char *msg, ...) -{ - va_list args; - - if (msg) { - va_start(args, msg); - vfprintf(stderr, msg, args); - fputs("\n", stderr); - va_end(args); - } - - exit(!!NULL); -} - static void stub_called(const unsigned char *fun) { diff --git a/src/util/test.h b/src/util/test.h new file mode 100644 index 00000000..bef09c96 --- /dev/null +++ b/src/util/test.h @@ -0,0 +1,23 @@ +/* Test library */ + +#ifndef EL__UTIL_TEST_H +#define EL__UTIL_TEST_H + +#include + +static inline void +die(const char *msg, ...) +{ + va_list args; + + if (msg) { + va_start(args, msg); + vfprintf(stderr, msg, args); + fputs("\n", stderr); + va_end(args); + } + + exit(EXIT_FAILURE); +} + +#endif From 5d88ea78f97fd69268e837da3ecf4e75fcc88909 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Tue, 28 Aug 2007 20:16:27 +0200 Subject: [PATCH 02/18] dom/test: rename get_opt to get_test_opt to avoid namespace problems --- src/dom/test/sgml-parser.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dom/test/sgml-parser.c b/src/dom/test/sgml-parser.c index 3eca7f1b..9c97bb84 100644 --- a/src/dom/test/sgml-parser.c +++ b/src/dom/test/sgml-parser.c @@ -244,8 +244,8 @@ sgml_error_function(struct sgml_parser *parser, struct dom_string *string, } static int -get_opt(char **argref, const char *name, int *argi, int argc, char *argv[], - const char *expect_msg) +get_test_opt(char **argref, const char *name, int *argi, int argc, char *argv[], + const char *expect_msg) { char *arg = *argref; int namelen = strlen(name); @@ -291,17 +291,17 @@ main(int argc, char *argv[]) arg += 2; - if (get_opt(&arg, "uri", &i, argc, argv, "a URI")) { + if (get_test_opt(&arg, "uri", &i, argc, argv, "a URI")) { set_dom_string(&uri, arg, strlen(arg)); - } else if (get_opt(&arg, "src", &i, argc, argv, "a string")) { + } else if (get_test_opt(&arg, "src", &i, argc, argv, "a string")) { set_dom_string(&source, arg, strlen(arg)); - } else if (get_opt(&arg, "stdin", &i, argc, argv, "a number")) { + } else if (get_test_opt(&arg, "stdin", &i, argc, argv, "a number")) { read_stdin = atoi(arg); flags |= SGML_PARSER_INCREMENTAL; - } else if (get_opt(&arg, "normalize", &i, argc, argv, "a string")) { + } else if (get_test_opt(&arg, "normalize", &i, argc, argv, "a string")) { normalize = 1; normalize_flags = parse_dom_config(arg, ','); type = SGML_PARSER_TREE; From c6a223c8ddfca453b3b326341e910c241c0eec69 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Tue, 28 Aug 2007 20:22:22 +0200 Subject: [PATCH 03/18] dom/test: properly test test option matches in get_test_opt --- src/dom/test/sgml-parser.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dom/test/sgml-parser.c b/src/dom/test/sgml-parser.c index 9c97bb84..09f4185a 100644 --- a/src/dom/test/sgml-parser.c +++ b/src/dom/test/sgml-parser.c @@ -256,11 +256,15 @@ get_test_opt(char **argref, const char *name, int *argi, int argc, char *argv[], arg += namelen; if (*arg == '=') { (*argref) = arg + 1; - } else { + + } else if (!*arg) { (*argi)++; if ((*argi) >= argc) die("--%s expects %s", name, expect_msg); (*argref) = argv[(*argi)]; + + } else { + return 0; } return 1; From bbd7c8354a6aa228ab92227e2fd6445c82ba6fc9 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Tue, 28 Aug 2007 20:32:10 +0200 Subject: [PATCH 04/18] Move get_test_opt to util/test.h and use throughout test programs --- src/dom/test/dom-select.c | 39 ++++++----------------------------- src/dom/test/sgml-parser.c | 27 ------------------------ src/mime/backend/mailcap.c | 38 +++++----------------------------- src/protocol/ftp/ftp-parser.c | 13 ++---------- src/util/test.h | 27 ++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 104 deletions(-) diff --git a/src/dom/test/dom-select.c b/src/dom/test/dom-select.c index 1da1cbfe..52b4a6a3 100644 --- a/src/dom/test/dom-select.c +++ b/src/dom/test/dom-select.c @@ -37,41 +37,14 @@ main(int argc, char *argv[]) arg += 2; - if (!strncmp(arg, "uri", 3)) { - arg += 3; - if (*arg == '=') { - arg++; - set_dom_string(&uri, arg, strlen(arg)); - } else { - i++; - if (i >= argc) - die("--uri expects a URI"); - set_dom_string(&uri, argv[i], strlen(argv[i])); - } + if (get_test_opt(&arg, "uri", &i, argc, argv, "a URI")) { + set_dom_string(&uri, arg, strlen(arg)); - } else if (!strncmp(arg, "src", 3)) { - arg += 3; - if (*arg == '=') { - arg++; - set_dom_string(&source, arg, strlen(arg)); - } else { - i++; - if (i >= argc) - die("--src expects a string"); - set_dom_string(&source, argv[i], strlen(argv[i])); - } + } else if (get_test_opt(&arg, "src", &i, argc, argv, "a string")) { + set_dom_string(&source, arg, strlen(arg)); - } else if (!strncmp(arg, "selector", 3)) { - arg += 8; - if (*arg == '=') { - arg++; - set_dom_string(&selector, arg, strlen(arg)); - } else { - i++; - if (i >= argc) - die("--selector expects a string"); - set_dom_string(&selector, argv[i], strlen(argv[i])); - } + } else if (get_test_opt(&arg, "selector", &i, argc, argv, "a string")) { + set_dom_string(&selector, arg, strlen(arg)); } else if (!strcmp(arg, "help")) { die(NULL); diff --git a/src/dom/test/sgml-parser.c b/src/dom/test/sgml-parser.c index 09f4185a..eee862ae 100644 --- a/src/dom/test/sgml-parser.c +++ b/src/dom/test/sgml-parser.c @@ -243,33 +243,6 @@ sgml_error_function(struct sgml_parser *parser, struct dom_string *string, return DOM_CODE_OK; } -static int -get_test_opt(char **argref, const char *name, int *argi, int argc, char *argv[], - const char *expect_msg) -{ - char *arg = *argref; - int namelen = strlen(name); - - if (strncmp(arg, name, namelen)) - return 0; - - arg += namelen; - if (*arg == '=') { - (*argref) = arg + 1; - - } else if (!*arg) { - (*argi)++; - if ((*argi) >= argc) - die("--%s expects %s", name, expect_msg); - (*argref) = argv[(*argi)]; - - } else { - return 0; - } - - return 1; -} - int main(int argc, char *argv[]) { diff --git a/src/mime/backend/mailcap.c b/src/mime/backend/mailcap.c index e7b14d61..752c626c 100644 --- a/src/mime/backend/mailcap.c +++ b/src/mime/backend/mailcap.c @@ -703,44 +703,16 @@ main(int argc, char *argv[]) arg += 2; - if (!strncmp(arg, "path", 4)) { - arg += 4; - if (*arg == '=') { - arg++; - get_mailcap_path() = arg; - } else { - i++; - if (i >= argc) - die("--path expects a parameter"); - get_mailcap_path() = argv[i]; - } + if (get_test_opt(&arg, "path", &i, argc, argv, "a string")) { + get_mailcap_path() = arg; done_mailcap(NULL); - } else if (!strncmp(arg, "format", 6)) { - arg += 6; - if (*arg == '=') { - arg++; - format = arg; - } else { - i++; - if (i >= argc) - die("--format expects a parameter"); - format = argv[i]; - } + } else if (get_test_opt(&arg, "format", &i, argc, argv, "a string")) { + format = arg; - } else if (!strncmp(arg, "get", 3)) { + } else if (get_test_opt(&arg, "get", &i, argc, argv, "a string")) { struct mime_handler *handler; - arg += 3; - if (*arg == '=') { - arg++; - } else { - i++; - if (i >= argc) - die("--get expects a parameter"); - arg = argv[i]; - } - if (has_gotten) printf("\n"); has_gotten = 1; diff --git a/src/protocol/ftp/ftp-parser.c b/src/protocol/ftp/ftp-parser.c index dbdb677b..b2b7fbf9 100644 --- a/src/protocol/ftp/ftp-parser.c +++ b/src/protocol/ftp/ftp-parser.c @@ -31,17 +31,8 @@ main(int argc, char *argv[]) arg += 2; - if (!strncmp(arg, "response", 8)) { - arg += 8; - if (*arg == '=') { - arg++; - response = arg; - } else { - i++; - if (i >= argc) - die("--response expects a string"); - response = argv[i]; - } + if (get_test_opt(&arg, "response", &i, argc, argv, "a string")) { + response = arg; responselen = strlen(response); } else { diff --git a/src/util/test.h b/src/util/test.h index bef09c96..152a943e 100644 --- a/src/util/test.h +++ b/src/util/test.h @@ -20,4 +20,31 @@ die(const char *msg, ...) exit(EXIT_FAILURE); } +static inline int +get_test_opt(char **argref, const char *name, int *argi, int argc, char *argv[], + const char *expect_msg) +{ + char *arg = *argref; + int namelen = strlen(name); + + if (strncmp(arg, name, namelen)) + return 0; + + arg += namelen; + if (*arg == '=') { + (*argref) = arg + 1; + + } else if (!*arg) { + (*argi)++; + if ((*argi) >= argc) + die("--%s expects %s", name, expect_msg); + (*argref) = argv[(*argi)]; + + } else { + return 0; + } + + return 1; +} + #endif From 8376feb6b18f6a7642106fbcd988bdf2b1875711 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Tue, 28 Aug 2007 20:35:14 +0200 Subject: [PATCH 05/18] Fix protocol/test ignore rule for the uri-test program --- src/protocol/test/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocol/test/.gitignore b/src/protocol/test/.gitignore index 6656e2d0..6b153e58 100644 --- a/src/protocol/test/.gitignore +++ b/src/protocol/test/.gitignore @@ -1 +1 @@ -uri-parser +uri-test From 78f733c6c1e7641384b8d40316f0101d90a0e81b Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Wed, 29 Aug 2007 09:57:18 +0300 Subject: [PATCH 06/18] More doc comments about coordinates. --- src/terminal/window.h | 14 +++++++++++++- src/viewer/text/link.c | 5 +++++ src/viewer/text/vs.h | 2 ++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/terminal/window.h b/src/terminal/window.h index 1d47d270..e94da64b 100644 --- a/src/terminal/window.h +++ b/src/terminal/window.h @@ -47,8 +47,20 @@ struct window { /** The terminal (and screen) that hosts the window */ struct terminal *term; - /** Used for tabs focus detection. */ + /** For ::WINDOW_TAB, the position and size in the tab bar. + * Updated while the tab bar is being drawn, and read if the + * user clicks there with the mouse. */ int xpos, width; + + /** The position of something that has focus in the window. + * Any popup menus are drawn near this position. + * In tab windows, during ::NAVIGATE_CURSOR_ROUTING, this is + * also the position of the cursor that the user can move; + * there is no separate cursor position for each frame. + * In dialog boxes, this is typically the top left corner of + * the focused widget, while the cursor is somewhere within + * the widget. + * @see set_window_ptr, get_parent_ptr, set_cursor */ int x, y; /** For delayed tab resizing */ diff --git a/src/viewer/text/link.c b/src/viewer/text/link.c index 175a0ff1..77f0cb2a 100644 --- a/src/viewer/text/link.c +++ b/src/viewer/text/link.c @@ -1080,6 +1080,11 @@ enter(struct session *ses, struct document_view *doc_view, int do_reload) return activate_link(ses, doc_view, link, do_reload); } +/** Get the link at the coordinates @a x and @a y, or NULL if none. + * The coordinates are relative to the document view; not to the + * terminal, nor to the document. So (0, 0) means whatever part of + * the document has been scrolled to the top left corner of the + * document view. */ struct link * get_link_at_coordinates(struct document_view *doc_view, int x, int y) { diff --git a/src/viewer/text/vs.h b/src/viewer/text/vs.h index 87343411..1de9e583 100644 --- a/src/viewer/text/vs.h +++ b/src/viewer/text/vs.h @@ -28,6 +28,8 @@ struct view_state { * should never be negative. */ int y; + /** The index of the focused link in the document.links array, + * or -1 of none. */ int current_link; int old_current_link; From 7f49eda39ed03afa1f4a12a8c121b888049cf665 Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Sun, 29 Apr 2007 21:06:03 +0200 Subject: [PATCH 07/18] DOM renderer: off by one error. --- src/document/dom/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/document/dom/renderer.c b/src/document/dom/renderer.c index 87f7e1b9..6391ff82 100644 --- a/src/document/dom/renderer.c +++ b/src/document/dom/renderer.c @@ -138,7 +138,7 @@ init_dom_renderer(struct dom_renderer *renderer, struct document *document, /* When someone will get here earlier than at 4am, * this will be done in some init function, perhaps * not overriding the user's default stylesheet. */ - css_parse_stylesheet(css, NULL, styles, styles + sizeof(default_colors) + 1); + css_parse_stylesheet(css, NULL, styles, styles + sizeof(default_colors)); } if (name) From af14d00d17c0be75ec3fd8fac1011064ac40b54b Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Mon, 3 Sep 2007 20:53:27 +0300 Subject: [PATCH 08/18] Add missing va_ends. I'm not sure they're needed anywhere nowadays, but still. --- src/util/string.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/util/string.c b/src/util/string.c index c3c953fa..076c491b 100644 --- a/src/util/string.c +++ b/src/util/string.c @@ -445,7 +445,6 @@ add_format_to_string(struct string *string, const unsigned char *format, ...) int newlength; int width; va_list ap; - va_list ap2; assertm(string && format, "[add_format_to_string]"); if_assert_failed { return NULL; } @@ -453,17 +452,16 @@ add_format_to_string(struct string *string, const unsigned char *format, ...) check_string_magic(string); va_start(ap, format); - VA_COPY(ap2, ap); - - width = vsnprintf(NULL, 0, format, ap2); + width = vsnprintf(NULL, 0, format, ap); + va_end(ap); if (width <= 0) return NULL; newlength = string->length + width; if (!realloc_string(string, newlength)) return NULL; + va_start(ap, format); vsnprintf(&string->source[string->length], width + 1, format, ap); - va_end(ap); string->length = newlength; From a59f44c4b5ca3e0fbae3c1a43ef4ad62eae365d1 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Mon, 3 Sep 2007 20:56:59 +0300 Subject: [PATCH 09/18] Document Unicode characters for ACS_S[1379]. --- src/terminal/screen.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/terminal/screen.c b/src/terminal/screen.c index e02c6c20..db560210 100644 --- a/src/terminal/screen.c +++ b/src/terminal/screen.c @@ -74,11 +74,11 @@ static const unsigned char frame_vt100_u[48] = { * 0x8D U+250C 'l' ACS_ULCORNER * 0x8E U+2514 'm' ACS_LLCORNER * 0x8F U+253C 'n' ACS_PLUS - * 0x90 - 'o' ACS_S1 - * 0x91 - 'p' ACS_S3 + * 0x90 U+23BA 'o' ACS_S1 + * 0x91 U+23BB 'p' ACS_S3 * 0x92 U+2500 'q' ACS_HLINE - * 0x93 - 'r' ACS_S7 - * 0x94 - 's' ACS_S9 + * 0x93 U+23BC 'r' ACS_S7 + * 0x94 U+23BD 's' ACS_S9 * 0x95 U+251C 't' ACS_LTEE * 0x96 U+2524 'u' ACS_RTEE * 0x97 U+2534 'v' ACS_BTEE From c44739e0399e65a4ff46128db7dda4514fcf3c67 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Mon, 3 Sep 2007 20:58:05 +0300 Subject: [PATCH 10/18] Refer to bug 96 in a comment. --- src/terminal/screen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/terminal/screen.c b/src/terminal/screen.c index db560210..8f838a66 100644 --- a/src/terminal/screen.c +++ b/src/terminal/screen.c @@ -27,7 +27,8 @@ #include "util/string.h" -/* TODO: We must use termcap/terminfo if available! --pasky */ +/* TODO: We must use termcap/terminfo if available! --pasky + * Please mention ELinks bug 96 in commit logs. --KON */ /** Mapping from (enum ::border_char - 0xB0) to ASCII characters. */ const unsigned char frame_dumb[48] = " ||||++||++++++--|-+||++--|-+----++++++++ "; From cdf2d8181ce0a9dafa3fdadd1e2942e9ff7432f1 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Tue, 4 Sep 2007 10:26:57 +0300 Subject: [PATCH 11/18] More missing va_ends. Somehow, these slipped from commit af14d00d17c0be75ec3fd8fac1011064ac40b54b yesterday. --- src/main/event.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/event.c b/src/main/event.c index 91e1c0c9..9b3bc5dc 100644 --- a/src/main/event.c +++ b/src/main/event.c @@ -177,6 +177,7 @@ trigger_event(int id, ...) va_start(ap, id); trigger_event_va(id, ap); + va_end(ap); } void @@ -187,6 +188,7 @@ trigger_event_name(unsigned char *name, ...) va_start(ap, name); trigger_event_va(id, ap); + va_end(ap); } static inline void From a1a8696ccea253c3f0b05dad4a689dfd6f908109 Mon Sep 17 00:00:00 2001 From: Miciah Dashiel Butler Masters Date: Thu, 6 Sep 2007 18:37:17 +0000 Subject: [PATCH 12/18] Introduce start_document_refreshes start_document_refreshes performs the NULL-pointer checks that previously all callers to start_document_refresh must perform and then calls start_document_refresh. --- src/document/refresh.c | 17 ++++++++++++++++- src/document/refresh.h | 2 +- src/session/session.c | 8 +------- src/viewer/text/draw.c | 8 +------- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/document/refresh.c b/src/document/refresh.c index cb8cc9fb..795f22e2 100644 --- a/src/document/refresh.c +++ b/src/document/refresh.c @@ -94,7 +94,7 @@ do_document_refresh(void *data) } } -void +static void start_document_refresh(struct document_refresh *refresh, struct session *ses) { milliseconds_T minimum = (milliseconds_T) get_opt_int("document.browse.minimum_refresh_time", ses); @@ -120,3 +120,18 @@ start_document_refresh(struct document_refresh *refresh, struct session *ses) install_timer(&refresh->timer, time, do_document_refresh, ses); } + +void +start_document_refreshes(struct session *ses) +{ + + assert(ses); + + if (!ses->doc_view + || !ses->doc_view->document + || !ses->doc_view->document->refresh + || !get_opt_bool("document.browse.refresh", ses)) + return; + + start_document_refresh(ses->doc_view->document->refresh, ses); +} diff --git a/src/document/refresh.h b/src/document/refresh.h index f9b4c9c5..2d8732cd 100644 --- a/src/document/refresh.h +++ b/src/document/refresh.h @@ -16,6 +16,6 @@ struct document_refresh { struct document_refresh *init_document_refresh(unsigned char *url, unsigned long seconds); void done_document_refresh(struct document_refresh *refresh); void kill_document_refresh(struct document_refresh *refresh); -void start_document_refresh(struct document_refresh *refresh, struct session *ses); +void start_document_refreshes(struct session *ses); #endif diff --git a/src/session/session.c b/src/session/session.c index 70980963..34d83bd6 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -588,13 +588,7 @@ doc_loading_callback(struct download *download, struct session *ses) load_ecmascript_imports(ses, ses->doc_view); process_file_requests(ses); - if (ses->doc_view - && ses->doc_view->document - && ses->doc_view->document->refresh - && get_opt_bool("document.browse.refresh", ses)) { - start_document_refresh(ses->doc_view->document->refresh, - ses); - } + start_document_refreshes(ses); if (download->state != S_OK) { print_error_dialog(ses, download->state, diff --git a/src/viewer/text/draw.c b/src/viewer/text/draw.c index 07df0f7f..e0676ded 100644 --- a/src/viewer/text/draw.c +++ b/src/viewer/text/draw.c @@ -351,13 +351,7 @@ draw_formatted(struct session *ses, int rerender) render_document_frames(ses, rerender); /* Rerendering kills the document refreshing so restart it. */ - if (ses->doc_view - && ses->doc_view->document - && ses->doc_view->document->refresh - && get_opt_bool("document.browse.refresh", ses)) { - start_document_refresh(ses->doc_view->document->refresh, - ses); - } + start_document_refreshes(ses); } if (ses->tab != get_current_tab(ses->tab->term)) From 66d62ca11b54e420f99c9ecac1d6b41ba0481e24 Mon Sep 17 00:00:00 2001 From: Miciah Dashiel Butler Masters Date: Thu, 6 Sep 2007 19:13:25 +0000 Subject: [PATCH 13/18] start_document_refresh: take document_view instead of session --- src/document/refresh.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/document/refresh.c b/src/document/refresh.c index 795f22e2..33b0ddbf 100644 --- a/src/document/refresh.c +++ b/src/document/refresh.c @@ -95,9 +95,10 @@ do_document_refresh(void *data) } static void -start_document_refresh(struct document_refresh *refresh, struct session *ses) +start_document_refresh(struct document_refresh *refresh, + struct document_view *doc_view) { - milliseconds_T minimum = (milliseconds_T) get_opt_int("document.browse.minimum_refresh_time", ses); + milliseconds_T minimum = (milliseconds_T) get_opt_int("document.browse.minimum_refresh_time", doc_view->session); milliseconds_T refresh_delay = sec_to_ms(refresh->seconds); milliseconds_T time = ms_max(refresh_delay, minimum); struct type_query *type_query; @@ -114,11 +115,11 @@ start_document_refresh(struct document_refresh *refresh, struct session *ses) /* Like bug 289 another sourceforge download thingy this time with * number 434. It should take care when refreshing to the same URI or * what ever the cause is. */ - foreach (type_query, ses->type_queries) + foreach (type_query, doc_view->session->type_queries) if (compare_uri(refresh->uri, type_query->uri, URI_BASE)) return; - install_timer(&refresh->timer, time, do_document_refresh, ses); + install_timer(&refresh->timer, time, do_document_refresh, doc_view->session); } void @@ -133,5 +134,5 @@ start_document_refreshes(struct session *ses) || !get_opt_bool("document.browse.refresh", ses)) return; - start_document_refresh(ses->doc_view->document->refresh, ses); + start_document_refresh(ses->doc_view->document->refresh, ses->doc_view); } From 2676fcc2cd105dd54026302ac4618084741da49d Mon Sep 17 00:00:00 2001 From: Miciah Dashiel Butler Masters Date: Thu, 6 Sep 2007 19:14:35 +0000 Subject: [PATCH 14/18] do_document_refresh: take document_view instead of session --- src/document/refresh.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/document/refresh.c b/src/document/refresh.c index 33b0ddbf..7dc3ece8 100644 --- a/src/document/refresh.c +++ b/src/document/refresh.c @@ -66,8 +66,8 @@ done_document_refresh(struct document_refresh *refresh) static void do_document_refresh(void *data) { - struct session *ses = data; - struct document_refresh *refresh = ses->doc_view->document->refresh; + struct document_view *doc_view = data; + struct document_refresh *refresh = doc_view->document->refresh; struct type_query *type_query; assert(refresh); @@ -78,16 +78,16 @@ do_document_refresh(void *data) /* When refreshing documents that will trigger a download (like * sourceforge's download pages) make sure that we do not endlessly * trigger the download (bug 289). */ - foreach (type_query, ses->type_queries) + foreach (type_query, doc_view->session->type_queries) if (compare_uri(refresh->uri, type_query->uri, URI_BASE)) return; - if (compare_uri(refresh->uri, ses->doc_view->document->uri, 0)) { + if (compare_uri(refresh->uri, doc_view->document->uri, 0)) { /* If the refreshing is for the current URI, force a reload. */ - reload(ses, CACHE_MODE_FORCE_RELOAD); + reload(doc_view->session, CACHE_MODE_FORCE_RELOAD); } else { /* This makes sure that we send referer. */ - goto_uri_frame(ses, refresh->uri, NULL, CACHE_MODE_NORMAL); + goto_uri_frame(doc_view->session, refresh->uri, NULL, CACHE_MODE_NORMAL); /* XXX: A possible very wrong work-around for refreshing used when * downloading files. */ refresh->restart = 0; @@ -119,7 +119,7 @@ start_document_refresh(struct document_refresh *refresh, if (compare_uri(refresh->uri, type_query->uri, URI_BASE)) return; - install_timer(&refresh->timer, time, do_document_refresh, doc_view->session); + install_timer(&refresh->timer, time, do_document_refresh, doc_view); } void From dbacc9ead292e8630caf5e57ca68f48e564184c3 Mon Sep 17 00:00:00 2001 From: Miciah Dashiel Butler Masters Date: Thu, 6 Sep 2007 20:47:17 +0000 Subject: [PATCH 15/18] Support document refresh in frames Introduce reload_frame, which takes a frame @name argument in addition to the arguments that reload takes. --- src/document/refresh.c | 22 +++++++++++++++++++--- src/session/session.c | 9 +++++++++ src/session/session.h | 1 + 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/document/refresh.c b/src/document/refresh.c index 7dc3ece8..1580e1ef 100644 --- a/src/document/refresh.c +++ b/src/document/refresh.c @@ -84,10 +84,11 @@ do_document_refresh(void *data) if (compare_uri(refresh->uri, doc_view->document->uri, 0)) { /* If the refreshing is for the current URI, force a reload. */ - reload(doc_view->session, CACHE_MODE_FORCE_RELOAD); + reload_frame(doc_view->session, doc_view->name, + CACHE_MODE_FORCE_RELOAD); } else { /* This makes sure that we send referer. */ - goto_uri_frame(doc_view->session, refresh->uri, NULL, CACHE_MODE_NORMAL); + goto_uri_frame(doc_view->session, refresh->uri, doc_view->name, CACHE_MODE_NORMAL); /* XXX: A possible very wrong work-around for refreshing used when * downloading files. */ refresh->restart = 0; @@ -130,9 +131,24 @@ start_document_refreshes(struct session *ses) if (!ses->doc_view || !ses->doc_view->document - || !ses->doc_view->document->refresh || !get_opt_bool("document.browse.refresh", ses)) return; + if (document_has_frames(ses->doc_view->document)) { + struct document_view *doc_view; + + foreach (doc_view, ses->scrn_frames) { + if (!doc_view->document + || !doc_view->document->refresh) + continue; + + start_document_refresh(doc_view->document->refresh, + doc_view); + } + } + + if (!ses->doc_view->document->refresh) + return; + start_document_refresh(ses->doc_view->document->refresh, ses->doc_view); } diff --git a/src/session/session.c b/src/session/session.c index 34d83bd6..96317100 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -1179,6 +1179,13 @@ destroy_session(struct session *ses) void reload(struct session *ses, enum cache_mode cache_mode) +{ + reload_frame(ses, NULL, cache_mode); +} + +void +reload_frame(struct session *ses, unsigned char *name, + enum cache_mode cache_mode) { abort_loading(ses, 0); @@ -1206,6 +1213,8 @@ reload(struct session *ses, enum cache_mode cache_mode) loc->download.data = ses; loc->download.callback = (download_callback_T *) doc_loading_callback; + ses->task.target.frame = name; + load_uri(loc->vs.uri, ses->referrer, &loc->download, PRI_MAIN, cache_mode, -1); foreach (ftl, ses->more_files) { diff --git a/src/session/session.h b/src/session/session.h index 0473d1d2..d23c00fe 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -255,6 +255,7 @@ struct session *init_session(struct session *ses, struct terminal *term, void doc_loading_callback(struct download *, struct session *); void abort_loading(struct session *, int); +void reload_frame(struct session *, unsigned char *, enum cache_mode); void reload(struct session *, enum cache_mode); void load_frames(struct session *, struct document_view *); From 4a6a6909ea93ada367e147d9831f44254fad9031 Mon Sep 17 00:00:00 2001 From: Laurent MONIN Date: Sat, 8 Sep 2007 21:03:22 +0200 Subject: [PATCH 16/18] Make meta refresh content attribute parsing more tolerant. Simply search for 'url' marker ignoring anything before it. ELinks is now able to follow incorrectly written meta refresh content attribute with missing ; before url= parameter. As an example, try http://akkada.tivi.net.pl/ --- src/document/html/parser.c | 81 +++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/src/document/html/parser.c b/src/document/html/parser.c index b6b13d7c..cdc8745c 100644 --- a/src/document/html/parser.c +++ b/src/document/html/parser.c @@ -1,5 +1,9 @@ /* HTML parser */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* XXX: we _WANT_ strcasestr() ! */ +#endif + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -296,6 +300,81 @@ parse_old_meta_refresh(unsigned char *str, unsigned char **ret) if (len) *ret = memacpy(p, len); } +/* Search for the url part in the content attribute and returns + * it if found. + * It searches the first occurence of 'url' marker somewhere ignoring + * anything before it. + * It should cope with most situations including: + * content="0; URL='http://www.site.com/path/xxx.htm'" + * content="0 url=http://www.site.com/path/xxx.htm" + * content="anything ; some url === ''''http://www.site.com/path/xxx.htm'''' + * + * The return value is one of: + * + * - HEADER_PARAM_FOUND: the parameter was found, copied, and stored in *@ret. + * - HEADER_PARAM_NOT_FOUND: the parameter is not there. *@ret is now NULL. + * - HEADER_PARAM_OUT_OF_MEMORY: error. *@ret is now NULL. + * + * If @ret is NULL, then this function doesn't actually access *@ret, + * and cannot fail with HEADER_PARAM_OUT_OF_MEMORY. Some callers may + * rely on this. */ +static enum parse_header_param +search_for_url_param(unsigned char *str, unsigned char **ret) +{ +#define LWS(c) ((c) == ' ' || (c) == ASCII_TAB) + unsigned char *p; + int plen = 0; + + if (ret) *ret = NULL; /* default in case of early return */ + + assert(str); + if_assert_failed return HEADER_PARAM_NOT_FOUND; + + /* Returns now if string @str is empty. */ + if (!*str) return HEADER_PARAM_NOT_FOUND; + + p = strcasestr(str, "url"); + if (!p) return HEADER_PARAM_NOT_FOUND; + p += 3; + + while (*p && (*p <= ' ' || *p == '=')) p++; + if (!*p) { + if (ret) { + *ret = stracpy(""); + if (!*ret) + return HEADER_PARAM_OUT_OF_MEMORY; + } + return HEADER_PARAM_FOUND; + } + + while ((p[plen] > ' ' || LWS(p[plen])) && p[plen] != ';') plen++; + + /* Trim ending spaces */ + while (plen > 0 && LWS(p[plen - 1])) plen--; + + /* XXX: Drop enclosing single quotes if there's some. + * + * Some websites like newsnow.co.uk are using single quotes around url + * in URL field in meta tag content attribute like this: + * + * + * This is an attempt to handle that, but it may break something else. + * We drop all pair of enclosing quotes found (eg. '''url''' => url). + * Please report any issue related to this. --Zas */ + while (plen > 1 && *p == '\'' && p[plen - 1] == '\'') { + p++; + plen -= 2; + } + + if (ret) { + *ret = memacpy(p, plen); + if (!*ret) + return HEADER_PARAM_OUT_OF_MEMORY; + } + return HEADER_PARAM_FOUND; +#undef LWS +} + static void check_head_for_refresh(struct html_context *html_context, unsigned char *head) { @@ -304,7 +383,7 @@ check_head_for_refresh(struct html_context *html_context, unsigned char *head) refresh = parse_header(head, "Refresh", NULL); if (!refresh) return; - parse_header_param(refresh, "URL", &url); + search_for_url_param(refresh, &url); if (!url) { /* Let's try a more tolerant parsing. */ parse_old_meta_refresh(refresh, &url); From 24d88d2f3e77faa1865485911b04361915e0c4e0 Mon Sep 17 00:00:00 2001 From: Laurent MONIN Date: Sat, 8 Sep 2007 21:06:28 +0200 Subject: [PATCH 17/18] Add a simple testcase for missing ; in meta refresh content attribute. --- test/refresh2.html | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 test/refresh2.html diff --git a/test/refresh2.html b/test/refresh2.html new file mode 100644 index 00000000..bae21659 --- /dev/null +++ b/test/refresh2.html @@ -0,0 +1,6 @@ + + + + Redirect to /somewhere after 3 seconds. + + From 58b3b1e75239fac7f48d54609b4033c228d6a5da Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Sun, 9 Sep 2007 18:03:47 +0200 Subject: [PATCH 18/18] Reinstate "canonicalization" of path names for file URIs This reverts commit 4f0aaa166e245aba08c574c0b4b8ae32bbc535dc and insert check for the "//" -> "/" change only to occur for file:// URIs. This fixes the recent reports on broken handling of relative file URIs starting with "..". --- src/protocol/uri.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/protocol/uri.c b/src/protocol/uri.c index d9381148..33316ebf 100644 --- a/src/protocol/uri.c +++ b/src/protocol/uri.c @@ -766,6 +766,11 @@ normalize_uri(struct uri *uri, unsigned char *uristring) continue; } + } else if (is_uri_dir_sep(uri, src[1]) && + uri->protocol == PROTOCOL_FILE) { + /* // - ignore first '/'. */ + src += 1; + continue; } /* We don't want to access memory past the NUL char. */