"David Glasser" <[EMAIL PROTECTED]> writes:
> (Commit as [EMAIL PROTECTED], not [EMAIL PROTECTED])
> I don't know if the idiom I made up for doing a mode keymap was
> reasonable.
I'd say it is not quite correct, but it is not your fault; I didn't
properly define the page mode handling stuff so as to properly reset the
keymaps. I planned to commit a change to do that shortly. Once this
change is in, the proper way to define gmail mode would simply be:
define_page_mode("gmail_mode", "GMail", $enable = function (buffer) {
buffer.local_variables.content_buffer_normal_keymap = gmail_keymap;
});
Note that the page mode infrastructure already resets
buffer.local_variables whenever the page mode changes (maybe this will
prove to not be a good idea, though), and so it is not necessary to
delete stuff from it.
In order to have it properly handle page mode-specific keymaps, I'll
just change it to also reload the keymap for the current input mode
whenever the page mode changes.
> gmail-label-go really ought to take a list of labels as a completion.
> The greasemonkey script I use does this to get that list:
> function getLabels() {
> var navPaneNode = gmail.getNavPaneElement();
> var labelNodes = getNodesByTagNameAndClass(
> navPaneNode, "div", LABEL_ITEM_CLASS_NAME);
> var labels = [];
> for (var i = 0, labelNode; labelNode = labelNodes[i]; i++) {
> var labelName = labelNode.textContent.replace(UNREAD_COUNT_RE, "");
> labels.push(labelName);
> }
> return labels;
> }
> In this context, "gmail" is the gmail API object loaded from the
> gmonkey object described here:
> http://code.google.com/p/gmail-greasemonkey/wiki/GmailGreasemonkey10API
> I couldn't get that to work, though. Maybe Conkeror doesn't have
> unsafeWindow?
unsafeWindow is indeed a Greasemonkey-specific name.
The Conkeror analogue might be buffer.top_frame.wrappedJSObject. Some
quick checking reveals that the gmonkey object exists as a member of
that. However, using the "wrappedJSObject" property bypasses a default
security measure in Mozilla: this security measure essentially shields
you from any JavaScript on content pages; you can access DOM nodes and
windows in the content page, but you see only the normal DOM interface,
and if you set JavaScript properties on these nodes, the content page
doesn't see that. When you use wrappedJSObject property, you _do_ see
properties sett by content page JavaScript, and if content JavaScript
happens to override some DOM property or method, then attempting to use
the DOM property or method will not have the expected result. Thus, if
you call any method on an unwrapped content page object, you have to
assume that you might be running arbitrary content page JavaScript
(though it still runs unprivileged). Similarly, if you set any property
on these unwrapped content page objects, the content page JavaScript
will have access to those values.
As I said, this doesn't directly allow content page JavaScript to run
arbitrary privileged operations (although certain bugs in the past did
allow it to do that), but if you set some property on a content page
object equal to some function that has been defined in chrome code, then
content page JavaScript is free to call that function at any time, and
it will run as privileged code. This means that if you are going to
give a content page access to some privileged function, you have to be
extremely careful in checking the arguments given to the function, and
also you need to be sure it is safe for that function to be called an
arbitrary number of times at arbitrary points in time.
I believe in addition if chrome code happens to add any additional
properties to String.prototype, Function.prototype, or Object.prototype,
many casual accesses to unwrapped content page objects can allow content
page code to gain access to those properties as well. If those
functions are not written in a sufficiently careful way (and it would
seem very easy to make a mistake about that, since in general you would
not expect unprivileged code to be able to access such properties) then
you might likewise have a security risk.
It is particularly easy to accidentally invoke content page JavaScript
code because of several features of JavaScript: objects can define
getters and setters which are functions that are invoked when you
attempt to read or write a property, and operator == may invoke the
valueOf method of an object. If you use operator ===, the valueOf
operator is not invoked, and therefore === should be safe.
I believe that Greasemonkey helps reduce these dangers to some extent by
running the Greasemonkey scripts themselves in an unprivileged sandbox
environment.
See: http://developer.mozilla.org/en/docs/Components.utils.evalInSandbox
However, in order to allow greasemonkey scripts to be more useful, there
is a greasemonkey API that provides a limited set of slightly more
privileged operations that is accessible to greasemonkey scripts.
Greasemonkey also attempts to prevent content page code from calling
these special greasemonkey API functions even if it somehow obtains a
reference to such a function by checking the stack when one of those API
functions is called, and if there is anything other than chrome code or
greasemonkey script code in the call chain, it doesn't allow the call.
I think it is probably a bad idea to access content page objects via
wrappedJSObject without these precautions. At the very least, probably
any attempts to access content page objects should be done using
evalInSandbox. I'm not sure whether the stack call chain checking is
actually necessary, or whether it is merely a precaution in case of
(inevitable for something like greasemonkey) sloppy coding of
greasemonkey scripts.
--
Jeremy Maitin-Shepard
_______________________________________________
Conkeror mailing list
[email protected]
https://www.mozdev.org/mailman/listinfo/conkeror