Closed Bug 654286 Opened 13 years ago Closed 2 years ago

evalInSandbox "re-wraps" object properties

Categories

(Core :: JavaScript Engine, defect)

2.0 Branch
x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED INCOMPLETE

People

(Reporter: arantius, Unassigned)

Details

Attachments

(2 files)

User-Agent:       Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Build Identifier: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1

Starting from a content window, wrapped by default when the extension code accesses it, Greasemonkey will unwrap a copy and place it in the "unsafeWindow" property, for script authors to use when e.g. expando properties must be accessed.

In Firefox 4, the window's properties are re-wrapped, where they are not in Firefox 3.  The following code:



var contentWin = gBrowser.contentWindow;
var sandbox = Components.utils.Sandbox(contentWin);
sandbox.window = contentWin;
sandbox.unsafeWindow = contentWin.wrappedJSObject;
Components.utils.evalInSandbox(
  "dump(window+'\\n');"
  +"dump(unsafeWindow+'\\n');"
  +"dump(unsafeWindow.document+'\\n');",
  sandbox);
dump(contentWin.wrappedJSObject.document+'\n');



Produces, in Firefox 3:

[object XPCNativeWrapper [object Window]]
[object Window]
[object HTMLDocument]
[object HTMLDocument]

But in Firefox 4:

[object XrayWrapper [object Window]]
[object Window]
[object XrayWrapper [object HTMLDocument]]
[object HTMLDocument]


That third line is the access to the un-wrapped window's document property.  The fourth line is chrome code making the same access, and still getting the property unwrapped (as expected).  Just the code in the sandbox is broken.
In Firefox 4 it is re-wrapped, and you lose access to any of its properties' expandos.

This has been reported to us as:
https://github.com/greasemonkey/greasemonkey/issues/1320
https://github.com/greasemonkey/greasemonkey/issues/1326


Reproducible: Always
Assignee: nobody → general
Component: General → JavaScript Engine
Product: Firefox → Core
QA Contact: general → general
Version: unspecified → 2.0 Branch
I am pretty sure that we fixed this bug sometime in the last year and a half. Please reopen if that isn't the case.
Status: UNCONFIRMED → RESOLVED
Closed: 12 years ago
Resolution: --- → WORKSFORME
The specific test case above does work as expected now; at least the string representation is the same.  But a more careful test case:


var contentWin = gBrowser.contentWindow;
var sandbox = new Components.utils.Sandbox(
    contentWin,
    {
      'sandboxPrototype': contentWin,
      'wantXrays': true,
    });
sandbox.unsafeWindow = contentWin.wrappedJSObject;
// This works.
Components.utils.evalInSandbox(
    "unsafeWindow.HTMLElement.wrappedJSObject.prototype.test1 = function(){alert('Hello1')};"
    +"unsafeWindow.document.body.wrappedJSObject.test1();",
    sandbox);
// This fails but should work.
Components.utils.evalInSandbox(
    "unsafeWindow.HTMLElement.prototype.test2 = function(){alert('Hello2')};"
    +"unsafeWindow.document.body.test2();",
    sandbox);
    

The HTMLElement (in this case) doesn't have a prototype unless it's  un-wrapped again.

In Firefox 15, the failing version gives: "unsafeWindow.HTMLElement.prototype is undefined" in the error console.
(In reply to Anthony Lieuallen from comment #2)
> sandbox.unsafeWindow = contentWin.wrappedJSObject;

This doesn't do what you want. The fact that you get .wrappedJSObject and then stick the resulting object on the sandbox actually re-wraps it in an Xray wrapper (because the sandbox has wantXrays: true). You need to set unsafeWindow inside the sandbox (Cu.evalInsandbox("unsafeWindow = unsafeWindow.wrappedJSObject", sandbox)) to make that work.

> In Firefox 15, the failing version gives:
> "unsafeWindow.HTMLElement.prototype is undefined" in the error console.

I *think* we have another bug filed on this. bholley, do you happen to have the # handy?
(In reply to Blake Kaplan (:mrbkap) from comment #3)
> > In Firefox 15, the failing version gives:
> > "unsafeWindow.HTMLElement.prototype is undefined" in the error console.
> 
> I *think* we have another bug filed on this. bholley, do you happen to have
> the # handy?

I don't. Maybe gabor or Ms2er do.
I only know about bug 787070 but there you don't have an unsafeWindow, but as you pointed it out in Comment 3 here you don't have it here either. So Bobby's explanation at bug 787070 comment 5 should hold here. Except I still don't quite get why .prototype on a CCW gives undefined, or is there some kind of xray mode on top of the CCW here (there)? Why the expandos on it ignored from xray is clear.
Unwrapping inside the sandbox sounded like the solution, but:

var contentWin = gBrowser.contentWindow;
var sandbox = new Components.utils.Sandbox(
    contentWin,
    {
      'sandboxPrototype': contentWin,
      'wantXrays': true,
    });
Components.utils.evalInSandbox(
    "const unsafeWindow = window.wrappedJSObject;", sandbox);
// Re-un-wrapping still works.
Components.utils.evalInSandbox(
    "unsafeWindow.HTMLElement.wrappedJSObject.prototype.test3 = function(){alert('Hello3')};"
    +"unsafeWindow.document.body.wrappedJSObject.test3();",
    sandbox);
// This also fails but should work.
Components.utils.evalInSandbox(
    "unsafeWindow.HTMLElement.prototype.test4 = function(){alert('Hello4')};"
    +"unsafeWindow.document.body.test4();",
    sandbox);
    
Produces an alert of "Hello3" then the same "Error: unsafeWindow.HTMLElement.prototype is undefined".
Status: RESOLVED → UNCONFIRMED
Resolution: WORKSFORME → ---
Attached file Alert OK
Attached file Alert ERROR (broken)
Attachment #733984 - Attachment mime type: application/octet-stream → text/javascript
Attachment #733986 - Attachment mime type: application/octet-stream → text/javascript
Assignee: general → nobody
Status: UNCONFIRMED → RESOLVED
Closed: 12 years ago2 years ago
Resolution: --- → INCOMPLETE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: