1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

Bug 943: Refuse user JS actions in unfocused tabs

(cherry picked from elinks-0.12 commit 51dc3beee7)

Conflicts:
	NEWS: Both 0.12pre5.GIT and 0.13.GIT had inserted a new section.
	src/terminal/window.c: Both had inserted a new function.
This commit is contained in:
Kalle Olavi Niemitalo 2009-07-24 16:41:30 +03:00 committed by Kalle Olavi Niemitalo
parent a96d8a17e5
commit 6f4c95cc7f
5 changed files with 72 additions and 3 deletions

14
NEWS
View File

@ -105,6 +105,20 @@ have already been considered.
(mostly reverted) (mostly reverted)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
ELinks 0.12pre5.GIT now:
------------------------
To be released as 0.12pre6 or 0.12rc1.
Bugs that should be removed from NEWS before the 0.12.0 release:
* critical bug 943: Don't let user JavaScripts call any methods of
``elinks.action'' in tabs that do not have the focus. If a tab was
closed with ``elinks.action.tab_close'' while it had pop-up windows,
ELinks could crash; as a precaution, don't allow other actions
either. ELinks 0.12pre1 was the first release that supported
``elinks.action''.
ELinks 0.12pre5: ELinks 0.12pre5:
---------------- ----------------

View File

@ -234,9 +234,10 @@ A history item has these properties:
*Compatibility:* ELinks 0.12pre1 *Compatibility:* ELinks 0.12pre1
NOTE: When you read an action function from this hash, ELinks binds it to the NOTE: When you read an action function from this hash, ELinks binds it to the
current tab; any later calls to the function affect that tab. This may be current tab; any later calls to the function throw errors if that tab no
changed in a future version. It is safest to call the function right away, longer has the focus (in its terminal). This may be changed in a future
rather than save it in a variable and call it later. version. It is safest to call the function right away, rather than save it
in a variable and call it later.
-- --
[[smjs-elinks.keymaps]] elinks.keymaps (hash):: [[smjs-elinks.keymaps]] elinks.keymaps (hash)::

View File

@ -8,9 +8,11 @@
#include "config/kbdbind.h" #include "config/kbdbind.h"
#include "ecmascript/spidermonkey-shared.h" #include "ecmascript/spidermonkey-shared.h"
#include "intl/gettext/libintl.h"
#include "scripting/smjs/core.h" #include "scripting/smjs/core.h"
#include "scripting/smjs/elinks_object.h" #include "scripting/smjs/elinks_object.h"
#include "session/session.h" #include "session/session.h"
#include "terminal/window.h"
#include "util/memory.h" #include "util/memory.h"
#include "viewer/action.h" #include "viewer/action.h"
@ -66,6 +68,32 @@ smjs_action_fn_callback(JSContext *ctx, uintN argc, jsval *rval)
return JS_TRUE; return JS_TRUE;
} }
if (!would_window_receive_keypresses(hop->ses->tab)) {
/* The user cannot run actions in this tab by pressing
* keys, and some actions could crash if run in this
* situation; so we don't let user scripts run actions
* either.
*
* In particular, this check should fix bug 943, where
* ::ACT_MAIN_TAB_CLOSE called destroy_session(),
* which freed struct type_query while BFU dialogs had
* pointers to it. That crash could be prevented in
* various ways but it seems other similar crashes are
* possible, e.g. if the link menu is open and has a
* pointer to a session that is then destroyed.
* Instead of thoroughly auditing the use of pointers
* to sessions and related structures, I'll just
* disable the feature, to bring the ELinks 0.12
* release closer.
*
* The "%s" prevents interpretation of any percent
* signs in translations. */
JS_ReportError(ctx, "%s",
_("Cannot run actions in a tab that doesn't "
"have the focus", hop->ses->tab->term));
return JS_FALSE; /* make JS propagate the exception */
}
if (argc >= 1) { if (argc >= 1) {
int32 val; int32 val;

View File

@ -219,3 +219,25 @@ set_dlg_window_ptr(struct dialog_data *dlg_data, struct window *window, int x, i
} }
set_window_ptr(window, x, y); set_window_ptr(window, x, y);
} }
#if CONFIG_SCRIPTING_SPIDERMONKEY
/** Check whether keypress events would be directed to @a win. */
int
would_window_receive_keypresses(const struct window *win)
{
struct terminal *const term = win->term;
const struct window *selected;
/* At least @win must be in the list. */
assert(!list_empty(term->windows));
if_assert_failed return 0;
selected = term->windows.next;
if (selected->type != WINDOW_TAB) return 0;
selected = get_current_tab(term);
if (selected != win) return 0;
return 1;
}
#endif /* CONFIG_SCRIPTING_SPIDERMONKEY */

View File

@ -100,4 +100,8 @@ void assert_window_stacking(struct terminal *);
#define assert_window_stacking(t) ((void) (t)) #define assert_window_stacking(t) ((void) (t))
#endif #endif
#if CONFIG_SCRIPTING_SPIDERMONKEY
int would_window_receive_keypresses(const struct window *);
#endif
#endif #endif