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:
parent
a96d8a17e5
commit
6f4c95cc7f
14
NEWS
14
NEWS
@ -105,6 +105,20 @@ have already been considered.
|
||||
(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:
|
||||
----------------
|
||||
|
||||
|
@ -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)::
|
||||
|
@ -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"
|
||||
|
||||
@ -66,6 +68,32 @@ smjs_action_fn_callback(JSContext *ctx, uintN argc, jsval *rval)
|
||||
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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
#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 */
|
||||
|
@ -100,4 +100,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
|
||||
|
Loading…
Reference in New Issue
Block a user