Closed Bug 781521 Opened 12 years ago Closed 12 years ago

Fix new __exposedProps__ culprits

Categories

(Core :: XPConnect, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla17

People

(Reporter: bholley, Assigned: bholley)

References

Details

Attachments

(4 files)

In the last two months since we've been waiting to make __exposedProps__ mandatory (in bug 553102), a bunch of code has landed that goes orange when __exposedProps__ is required. Time to fix stuff again...
The constructor function lives in content, but it's being invoked from chrome, so the |this| object is actually privileged.
Attachment #650934 - Flags: review?(khuey)
Comment on attachment 650934 [details] [diff] [review]
Part 1 - Fix test_SpecialPowersExtension. v1

Review of attachment 650934 [details] [diff] [review]:
-----------------------------------------------------------------

I'm not a test peer.
Attachment #650934 - Flags: review?(khuey)
Attachment #650937 - Flags: review?(anygregor)
This one might still need some tweaking. There are some XXX comments in the code that I'm hoping justin can comment on.
Attachment #650938 - Flags: review?(justin.lebar+bug)
Attachment #650934 - Flags: review?(khuey)
(In reply to Kyle Huey [:khuey] (khuey@mozilla.com) from comment #2)
> I'm not a test peer.

Yeah, but I was already flagging you for review on patch 4, since I think you're the one there who's most familiar with both the message manager and SpecialPowers wrapping. So I figured you could probably review this one-liner while you're at it.
Comment on attachment 650938 [details] [diff] [review]
Part 3 - Fix BrowserElement API. v1

>diff --git a/dom/browser-element/BrowserElementParent.js b/dom/browser-element/BrowserElementParent.js
>+function exposeAll(obj) {
>+  // Filter for Objects and Arrays.
>+  if (typeof obj !== "object" || !obj)
>+    return;
>+
>+  // Recursively expose our children.
>+  Object.keys(obj).forEach(function(key) {
>+    exposeAll(obj[key]);
>+  });
>+
>+  // If we're not an Array, generate an __exposedProps__ object for ourselves.
>+  if (obj instanceof Array)
>+    return;
>+  var exposed = {};
>+  Object.keys(obj).forEach(function(key) {
>+    exposed[key] = 'rw';
>+  });
>+  obj.__exposedProps__ = exposed;
>+}

Oh, cool; I can make some things read-only?  I'll go back though and fix that up later.

>+function defineAndExpose(obj, name, value) {
>+  // XXXbholley - why do we need to waive Xray here? Are these objects sometimes
>+  // native and sometimes JS-implemented?

They sometimes come from the message manager.  I dunno if that answers your question.

>   _createEvent: function(evtName, detail, cancelable) {
>     // This will have to change if we ever want to send a CustomEvent with null
>     // detail.  For now, it's OK.
>     if (detail !== undefined && detail !== null) {
>+      if (typeof detail == "object")
>+        detail = JSON.parse(JSON.stringify(detail));

Is this to make sure that the object is "js-implemented" rather than native?
If so, do you still need to unwrap in defineAndExpose?

>+      exposeAll(detail);

>+++ b/dom/browser-element/mochitest/browserElement_PromptConfirm.js
>-        e.detail.returnValue = curPrompt.rv;
>+        // XXXbholley - This is probably wrong. What are the semantics of
>+        // returnValue? Is it supposed to be writable from content?
>+        SpecialPowers.wrap(e).detail.returnValue = curPrompt.rv;

Yes.  That's how content tells BrowserElementParent what the return value of the
prompt() should be.

I think you just need to set returnValue on the detail before dispatching the
event, and then we should be able to write it here, right?

>+++ b/dom/browser-element/mochitest/browserElement_Alert.js
>-    ok(true, msg.json);
>+    ok(true, 'Good!');//SpecialPowers.wrap(msg).json);
>   });
>   mm.addMessageListener('test-fail', function(msg) {
>     numPendingChildTests--;
>-    ok(false, msg.json);
>+    ok(false, 'Bad!');//SpecialPowers.wrap(msg).json);

I'd prefer the SpecialPowers.wrap(msg).json version, unless that doesn't work
for some reason.  Otherwise, these test logs will become much more difficult to
read ("Bad!" and "Good!" instead of a descriptive message).  We've had enough
problems with randomoranges in these tests that I'd like to keep the logs
useful, if we can.

This is good enough for r+, but we definitely need to figure out the returnValue business, because as written, this will break prompt().
Attachment #650938 - Flags: review?(justin.lebar+bug) → review+
Attachment #650937 - Flags: review?(anygregor) → review+
Comment on attachment 650939 [details] [diff] [review]
Part 4 - Fix Message Manager blob test. v1

Review of attachment 650939 [details] [diff] [review]:
-----------------------------------------------------------------

r=me, if you file a followup to see if this can be a chrome test instead.
Attachment #650939 - Flags: review+
Comment on attachment 650934 [details] [diff] [review]
Part 1 - Fix test_SpecialPowersExtension. v1

Review of attachment 650934 [details] [diff] [review]:
-----------------------------------------------------------------

r=me, but a comment would be nice
Attachment #650934 - Flags: review+
Comment on attachment 650934 [details] [diff] [review]
Part 1 - Fix test_SpecialPowersExtension. v1

Consider these reviews officially delegated to Ms2ger.
Attachment #650934 - Flags: review?(khuey)
Justin and I did an interactive discussion about IRC. Here are the results:

(In reply to Justin Lebar [:jlebar] from comment #7)

> >+function defineAndExpose(obj, name, value) {
> >+  // XXXbholley - why do we need to waive Xray here? Are these objects sometimes
> >+  // native and sometimes JS-implemented?
> 
> They sometimes come from the message manager.  I dunno if that answers your
> question.

We concluded that it wasn't necessary. I removed it.

> >+      if (typeof detail == "object")
> >+        detail = JSON.parse(JSON.stringify(detail));
> 
> Is this to make sure that the object is "js-implemented" rather than native?
> If so, do you still need to unwrap in defineAndExpose?

It was to deep clone the object to avoid exposing a potentially-held copy. Justin said it wasn't necessary, so I removed it.


> >+        // XXXbholley - This is probably wrong. What are the semantics of
> >+        // returnValue? Is it supposed to be writable from content?
> >+        SpecialPowers.wrap(e).detail.returnValue = curPrompt.rv;
> 
> Yes.  That's how content tells BrowserElementParent what the return value of
> the
> prompt() should be.
> 
> I think you just need to set returnValue on the detail before dispatching the
> event, and then we should be able to write it here, right?

I gave the calls to showModalPrompt for |alert| and |confirm| an initial returnValue of |undefined| so that exposeAll can pick up on it.
> >   mm.addMessageListener('test-fail', function(msg) {
> >     numPendingChildTests--;
> >-    ok(false, msg.json);
> >+    ok(false, 'Bad!');//SpecialPowers.wrap(msg).json);
> 
> I'd prefer the SpecialPowers.wrap(msg).json version, unless that doesn't work
> for some reason.  Otherwise, these test logs will become much more difficult
> to
> read ("Bad!" and "Good!" instead of a descriptive message).  We've had enough
> problems with randomoranges in these tests that I'd like to keep the logs
> useful, if we can.

Didn't mean to add that to the patch. Fixed.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: