Bug 1137326 - Fix out of bounds error in JS_iterateCompartments. r=terrence, a=abillings
authorSteve Fink <sfink@mozilla.com>
Mon, 12 Jan 2015 14:19:27 -0800
changeset 250239 10eff960b898
parent 250238 41929a7c55f5
child 250240 ea414ee32231
push id4524
push userryanvm@gmail.com
push date2015-03-04 18:49 +0000
treeherdermozilla-beta@666a1aafecfd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence, abillings
bugs1137326
milestone37.0
Bug 1137326 - Fix out of bounds error in JS_iterateCompartments. r=terrence, a=abillings
js/src/gc/Zone.h
js/src/jsapi.h
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -375,43 +375,44 @@ class ZonesIter
     }
 
     operator JS::Zone *() const { return get(); }
     JS::Zone *operator->() const { return get(); }
 };
 
 struct CompartmentsInZoneIter
 {
-    explicit CompartmentsInZoneIter(JS::Zone *zone) {
+    explicit CompartmentsInZoneIter(JS::Zone *zone) : zone(zone) {
         it = zone->compartments.begin();
-        end = zone->compartments.end();
     }
 
     bool done() const {
         MOZ_ASSERT(it);
-        return it == end;
+        return it < zone->compartments.begin() ||
+               it >= zone->compartments.end();
     }
     void next() {
         MOZ_ASSERT(!done());
         it++;
     }
 
     JSCompartment *get() const {
         MOZ_ASSERT(it);
         return *it;
     }
 
     operator JSCompartment *() const { return get(); }
     JSCompartment *operator->() const { return get(); }
 
   private:
-    JSCompartment **it, **end;
+    JS::Zone *zone;
+    JSCompartment **it;
 
     CompartmentsInZoneIter()
-      : it(nullptr), end(nullptr)
+      : zone(nullptr), it(nullptr)
     {}
 
     // This is for the benefit of CompartmentsIterT::comp.
     friend class mozilla::Maybe<CompartmentsInZoneIter>;
 };
 
 // This iterator iterates over all the compartments in a given set of zones. The
 // set of zones is determined by iterating ZoneIterT.
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1761,19 +1761,20 @@ extern JS_PUBLIC_API(JSCompartment *)
 JS_EnterCompartment(JSContext *cx, JSObject *target);
 
 extern JS_PUBLIC_API(void)
 JS_LeaveCompartment(JSContext *cx, JSCompartment *oldCompartment);
 
 typedef void (*JSIterateCompartmentCallback)(JSRuntime *rt, void *data, JSCompartment *compartment);
 
 /*
- * This function calls |compartmentCallback| on every compartment.  Beware that
+ * This function calls |compartmentCallback| on every compartment. Beware that
  * there is no guarantee that the compartment will survive after the callback
- * returns.
+ * returns. Also, if the callback can GC, there is no guarantee that every
+ * compartment will be visited.
  */
 extern JS_PUBLIC_API(void)
 JS_IterateCompartments(JSRuntime *rt, void *data,
                        JSIterateCompartmentCallback compartmentCallback);
 
 /*
  * Initialize standard JS class constructors, prototypes, and any top-level
  * functions and constants associated with the standard classes (e.g. isNaN