1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-09-30 03:26:23 -04:00

Ecmascript: 8 last urls opened by window.open() remembered in a safer way.

This commit is contained in:
Witold Filipczyk 2006-04-02 17:00:55 +02:00 committed by Witold Filipczyk
parent 9cca645dac
commit c571aea567
4 changed files with 80 additions and 81 deletions

View File

@ -64,6 +64,51 @@ static struct option_info ecmascript_options[] = {
NULL_OPTION_INFO, NULL_OPTION_INFO,
}; };
#define NUMBER_OF_URLS_TO_REMEMBER 8
static struct {
unsigned char *url;
unsigned char *frame;
} u[NUMBER_OF_URLS_TO_REMEMBER];
static int url_index = 0;
int
ecmascript_check_url(unsigned char *url, unsigned char *frame)
{
int i;
/* Because of gradual rendering window.open is called many
* times with the same arguments.
* This workaround remembers NUMBER_OF_URLS_TO_REMEMBER last
* opened URLs and do not let open them again.
*/
for (i = 0; i < NUMBER_OF_URLS_TO_REMEMBER; i++) {
if (!u[i].url) break;
if (!strcmp(u[i].url, url) && !strcmp(u[i].frame, frame)) {
mem_free(url);
mem_free(frame);
return 0;
}
}
u[url_index].url = url;
u[url_index].frame = frame;
url_index++;
if (url_index >= NUMBER_OF_URLS_TO_REMEMBER) url_index = 0;
return 1;
}
void
ecmascript_free_urls(struct module *module)
{
int i;
for (i = 0; i < NUMBER_OF_URLS_TO_REMEMBER; i++) {
mem_free_if(u[i].url);
mem_free_if(u[i].frame);
}
}
#undef NUMBER_OF_URLS_TO_REMEMBER
struct ecmascript_interpreter * struct ecmascript_interpreter *
ecmascript_get_interpreter(struct view_state *vs) ecmascript_get_interpreter(struct view_state *vs)
{ {
@ -266,5 +311,5 @@ struct module ecmascript_module = struct_module(
/* submodules: */ ecmascript_modules, /* submodules: */ ecmascript_modules,
/* data: */ NULL, /* data: */ NULL,
/* init: */ NULL, /* init: */ NULL,
/* done: */ NULL /* done: */ ecmascript_free_urls
); );

View File

@ -54,6 +54,9 @@ struct ecmascript_interpreter {
* reset for each rerendering, and it sucks to do all the magic to preserve the * reset for each rerendering, and it sucks to do all the magic to preserve the
* interpreter over the rerenderings (we tried). */ * interpreter over the rerenderings (we tried). */
int ecmascript_check_url(unsigned char *url, unsigned char *frame);
void ecmascript_free_urls(struct module *module);
struct ecmascript_interpreter *ecmascript_get_interpreter(struct view_state*vs); struct ecmascript_interpreter *ecmascript_get_interpreter(struct view_state*vs);
void ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter); void ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter);

View File

@ -93,8 +93,6 @@ js_try_resolve_frame(struct document_view *doc_view, unsigned char *id)
return js_get_global_object(target->vs.ecmascript->backend_data); return js_get_global_object(target->vs.ecmascript->backend_data);
} }
static void static void
window_get(struct SEE_interpreter *interp, struct SEE_object *o, window_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res) struct SEE_string *p, struct SEE_value *res)
@ -228,10 +226,10 @@ js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
struct view_state *vs = win->vs; struct view_state *vs = win->vs;
struct document_view *doc_view = vs->doc_view; struct document_view *doc_view = vs->doc_view;
struct session *ses = doc_view->session; struct session *ses = doc_view->session;
unsigned char *target = NULL; unsigned char *frame = "";
unsigned char *url, *url2; unsigned char *url;
struct uri *uri; struct uri *uri;
struct SEE_value url_value, target_value; struct SEE_value url_value;
#if 0 #if 0
static time_t ratelimit_start; static time_t ratelimit_start;
static int ratelimit_count; static int ratelimit_count;
@ -261,70 +259,42 @@ js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
} }
#endif #endif
SEE_ToString(interp, argv[0], &url_value); SEE_ToString(interp, argv[0], &url_value);
if (argc > 1) {
/* Because of gradual rendering window.open is called many
* times with the same arguments.
* This workaround remembers NUMBER_OF_URLS_TO_REMEMBER last
* opened URLs and do not let open them again.
*/
#define NUMBER_OF_URLS_TO_REMEMBER 8
static struct {
struct SEE_interpreter *interp;
struct SEE_string *url;
struct SEE_string *target;
} strings[NUMBER_OF_URLS_TO_REMEMBER];
static int indeks = 0;
int i;
SEE_ToString(interp, argv[1], &target_value);
for (i = 0; i < NUMBER_OF_URLS_TO_REMEMBER; i++) {
if (!(strings[i].url && strings[i].target
&& strings[i].interp))
continue;
if (strings[i].interp == interp
&& !SEE_string_cmp(url_value.u.string, strings[i].url)
&& !SEE_string_cmp(target_value.u.string, strings[i].target))
return;
}
strings[indeks].interp = interp;
strings[indeks].url = url_value.u.string;
strings[indeks].target = target_value.u.string;
indeks++;
if (indeks >= NUMBER_OF_URLS_TO_REMEMBER) indeks = 0;
#undef NUMBER_OF_URLS_TO_REMEMBER
}
url = SEE_string_to_unsigned_char(url_value.u.string); url = SEE_string_to_unsigned_char(url_value.u.string);
if (!url) return; if (!url) return;
trim_chars(url, ' ', 0);
if (argc > 1) {
struct SEE_value target_value;
SEE_ToString(interp, argv[1], &target_value);
frame = SEE_string_to_unsigned_char(target_value.u.string);
if (!frame) {
mem_free(url);
return;
}
/* url and frame will be freed by ecmascript_check_url */
if (!ecmascript_check_url(url, frame)) return;
}
/* TODO: Support for window naming and perhaps some window features? */ /* TODO: Support for window naming and perhaps some window features? */
url2 = join_urls(doc_view->document->uri, url = join_urls(doc_view->document->uri, url);
trim_chars(url, ' ', 0)); if (!url) return;
uri = get_uri(url, 0);
mem_free(url); mem_free(url);
if (!url2) return;
uri = get_uri(url2, 0);
mem_free(url2);
if (!uri) return; if (!uri) return;
if (argc > 1) { if (*frame && strcasecmp(frame, "_blank")) {
target = SEE_string_to_unsigned_char(target_value.u.string);
}
if (target && *target && strcasecmp(target, "_blank")) {
struct delayed_open *deo = mem_calloc(1, sizeof(*deo)); struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
if (deo) { if (deo) {
deo->ses = ses; deo->ses = ses;
deo->uri = get_uri_reference(uri); deo->uri = get_uri_reference(uri);
deo->target = target; deo->target = stracpy(frame);
/* target will be freed in delayed_goto_uri_frame */ /* target will be freed in delayed_goto_uri_frame */
register_bottom_half(delayed_goto_uri_frame, deo); register_bottom_half(delayed_goto_uri_frame, deo);
goto end; goto end;
} }
} }
mem_free_if(target);
if (!get_cmd_opt_bool("no-connect") if (!get_cmd_opt_bool("no-connect")
&& !get_cmd_opt_bool("no-home") && !get_cmd_opt_bool("no-home")
&& !get_cmd_opt_bool("anonymous") && !get_cmd_opt_bool("anonymous")
@ -345,10 +315,8 @@ js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
end: end:
done_uri(uri); done_uri(uri);
} }
void void
init_js_window_object(struct ecmascript_interpreter *interpreter) init_js_window_object(struct ecmascript_interpreter *interpreter)
{ {

View File

@ -295,7 +295,7 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
struct view_state *vs = JS_GetPrivate(ctx, obj); struct view_state *vs = JS_GetPrivate(ctx, obj);
struct document_view *doc_view = vs->doc_view; struct document_view *doc_view = vs->doc_view;
struct session *ses = doc_view->session; struct session *ses = doc_view->session;
unsigned char *target = ""; unsigned char *frame = "";
unsigned char *url; unsigned char *url;
struct uri *uri; struct uri *uri;
static time_t ratelimit_start; static time_t ratelimit_start;
@ -310,31 +310,15 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (argc < 1) return JS_TRUE; if (argc < 1) return JS_TRUE;
url = jsval_to_string(ctx, &argv[0]); url = stracpy(jsval_to_string(ctx, &argv[0]));
trim_chars(url, ' ', 0);
if (argc > 1) { if (argc > 1) {
JSString *url_string = JS_ValueToString(ctx, argv[0]); frame = stracpy(jsval_to_string(ctx, &argv[1]));
JSString *target_string = JS_ValueToString(ctx, argv[1]); if (!frame) {
int i; mem_free(url);
#define NUMBER_OF_URLS_TO_REMEMBER 8 return JS_TRUE;
static struct {
JSString *url;
JSString *frame;
} strings[NUMBER_OF_URLS_TO_REMEMBER];
static int indeks;
target = jsval_to_string(ctx, &argv[1]);
for (i = 0; i < NUMBER_OF_URLS_TO_REMEMBER; i++) {
if (!(strings[i].url && strings[i].frame))
continue;
if (!JS_CompareStrings(url_string, strings[i].url)
&& !JS_CompareStrings(target_string, strings[i].frame))
return JS_TRUE;
} }
strings[indeks].url = JS_InternString(ctx, url); if (!ecmascript_check_url(url, frame)) return JS_TRUE;
strings[indeks].frame = JS_InternString(ctx, target);
indeks++;
if (indeks >= NUMBER_OF_URLS_TO_REMEMBER) indeks = 0;
#undef NUMBER_OF_URLS_TO_REMEMBER
} }
/* Ratelimit window opening. Recursive window.open() is very nice. /* Ratelimit window opening. Recursive window.open() is very nice.
@ -351,21 +335,20 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
/* TODO: Support for window naming and perhaps some window features? */ /* TODO: Support for window naming and perhaps some window features? */
url = join_urls(doc_view->document->uri, url = join_urls(doc_view->document->uri, url);
trim_chars(url, ' ', 0));
if (!url) return JS_TRUE; if (!url) return JS_TRUE;
uri = get_uri(url, 0); uri = get_uri(url, 0);
mem_free(url); mem_free(url);
if (!uri) return JS_TRUE; if (!uri) return JS_TRUE;
if (*target && strcasecmp(target, "_blank")) { if (*frame && strcasecmp(frame, "_blank")) {
struct delayed_open *deo = mem_calloc(1, sizeof(*deo)); struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
if (deo) { if (deo) {
deo->ses = ses; deo->ses = ses;
deo->uri = get_uri_reference(uri); deo->uri = get_uri_reference(uri);
deo->target = stracpy(target); deo->target = stracpy(frame);
register_bottom_half(delayed_goto_uri_frame, deo); register_bottom_half(delayed_goto_uri_frame, deo);
boolean_to_jsval(ctx, rval, 1); boolean_to_jsval(ctx, rval, 1);
goto end; goto end;