1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-24 00:56:14 +00:00

Bug 943: Refuse user JS actions in unfocused tabs

This commit is contained in:
Kalle Olavi Niemitalo 2009-07-24 16:41:30 +03:00 committed by Kalle Olavi Niemitalo
parent db128fecd9
commit 51dc3beee7
5 changed files with 72 additions and 3 deletions

14
NEWS
View File

@ -5,6 +5,20 @@ You can see the complete list of recent changes, bugfixes and new features
in the http://repo.or.cz/w/elinks.git[gitweb interface]. See the ChangeLog
file for details.
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:
----------------

View File

@ -234,9 +234,10 @@ A history item has these properties:
*Compatibility:* ELinks 0.12pre1
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
changed in a future version. It is safest to call the function right away,
rather than save it in a variable and call it later.
current tab; any later calls to the function throw errors if that tab no
longer has the focus (in its terminal). This may be changed in a future
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)::

View File

@ -8,9 +8,11 @@
#include "config/kbdbind.h"
#include "ecmascript/spidermonkey-shared.h"
#include "intl/gettext/libintl.h"
#include "scripting/smjs/core.h"
#include "scripting/smjs/elinks_object.h"
#include "session/session.h"
#include "terminal/window.h"
#include "util/memory.h"
#include "viewer/action.h"
@ -60,6 +62,32 @@ smjs_action_fn_callback(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv,
(JSClass *) &action_fn_class, NULL);
if (!hop) 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) {
int32 val;

View File

@ -205,3 +205,25 @@ assert_window_stacking(struct terminal *term)
}
}
#endif /* CONFIG_DEBUG */
#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

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