Bug 1018620 - Make sure RegExpShareds fetched from objects are in the right compartment, r=billm.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 02 Jun 2014 15:05:48 -0600
changeset 205430 ae6bd0223b532929c93a9b3ee9aaed4f134b513a
parent 205429 39034630898e26c2e214b1562138cc7aa54f6a23
child 205431 1d273c0ae7a33e7241d1a2aafd52de9d0491766d
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1018620
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1018620 - Make sure RegExpShareds fetched from objects are in the right compartment, r=billm.
js/src/jit-test/tests/basic/bug1018620.js
js/src/jswrapper.cpp
js/src/vm/RegExpObject.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug1018620.js
@@ -0,0 +1,5 @@
+
+String.prototype.search = evalcx('').String.prototype.search;
+''.search(/()/);
+gcPreserveCode();
+gc(this);
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -562,18 +562,26 @@ CrossCompartmentWrapper::fun_toString(JS
     if (!cx->compartment()->wrap(cx, str.address()))
         return nullptr;
     return str;
 }
 
 bool
 CrossCompartmentWrapper::regexp_toShared(JSContext *cx, HandleObject wrapper, RegExpGuard *g)
 {
-    AutoCompartment call(cx, wrappedObject(wrapper));
-    return Wrapper::regexp_toShared(cx, wrapper, g);
+    RegExpGuard wrapperGuard(cx);
+    {
+        AutoCompartment call(cx, wrappedObject(wrapper));
+        if (!Wrapper::regexp_toShared(cx, wrapper, &wrapperGuard))
+            return false;
+    }
+
+    // Get an equivalent RegExpShared associated with the current compartment.
+    RegExpShared *re = wrapperGuard.re();
+    return cx->compartment()->regExps.get(cx, re->getSource(), re->getFlags(), g);
 }
 
 bool
 CrossCompartmentWrapper::defaultValue(JSContext *cx, HandleObject wrapper, JSType hint,
                                       MutableHandleValue vp)
 {
     PIERCE(cx, wrapper,
            NOTHING,
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -497,24 +497,17 @@ class RegExpObject : public JSObject
  * Parse regexp flags. Report an error and return false if an invalid
  * sequence of flags is encountered (repeat/invalid flag).
  *
  * N.B. flagStr must be rooted.
  */
 bool
 ParseRegExpFlags(JSContext *cx, JSString *flagStr, RegExpFlag *flagsOut);
 
-/*
- * Assuming ObjectClassIs(obj, ESClass_RegExp), return obj's RegExpShared.
- *
- * Beware: this RegExpShared can be owned by a compartment other than
- * cx->compartment. Normal RegExpGuard (which is necessary anyways)
- * will protect the object but it is important not to assign the return value
- * to be the private of any RegExpObject.
- */
+/* Assuming ObjectClassIs(obj, ESClass_RegExp), return a RegExpShared for obj. */
 inline bool
 RegExpToShared(JSContext *cx, HandleObject obj, RegExpGuard *g)
 {
     if (obj->is<RegExpObject>())
         return obj->as<RegExpObject>().getShared(cx, g);
     return Proxy::regexp_toShared(cx, obj, g);
 }