Bug 1076588 - Object.freeze() should return its argument with no conversion when the argument is a primitive value. r=till, r=Yoric
authorziyunfei <446240525@qq.com>
Fri, 03 Oct 2014 02:42:00 -0400
changeset 231925 1b532d05bccf46194922ec52acf91e78bcdd0a04
parent 231924 939cf8134947cc9d5061ec022ce9f9985bdbd160
child 231926 91ffa2ab03aa45d35668db72612e32049d8b241b
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill, Yoric
bugs1076588
milestone35.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 1076588 - Object.freeze() should return its argument with no conversion when the argument is a primitive value. r=till, r=Yoric
js/src/builtin/Object.cpp
js/src/tests/ecma_6/Object/freeze.js
toolkit/components/crashmonitor/CrashMonitor.jsm
toolkit/components/crashmonitor/test/unit/test_invalid_file.js
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -1046,26 +1046,29 @@ obj_preventExtensions(JSContext *cx, uns
         return true;
 
     // Steps 2-5.
     RootedObject obj(cx, &args.get(0).toObject());
 
     return JSObject::preventExtensions(cx, obj);
 }
 
+// ES6 draft rev27 (2014/08/24) 19.1.2.5 Object.freeze(O)
 static bool
 obj_freeze(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    RootedObject obj(cx);
-    if (!GetFirstArgumentAsObject(cx, args, "Object.freeze", &obj))
-        return false;
+    args.rval().set(args.get(0));
 
-    args.rval().setObject(*obj);
+    // Step 1.
+    if (!args.get(0).isObject())
+        return true;
 
+    // Steps 2-5.
+    RootedObject obj(cx, &args.get(0).toObject());
     return JSObject::freeze(cx, obj);
 }
 
 // ES6 draft rev27 (2014/08/24) 19.1.2.12 Object.isFrozen(O)
 static bool
 obj_isFrozen(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Object/freeze.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1076588;
+var summary = "Object.freeze() should return its argument with no conversion when the argument is a primitive value";
+
+print(BUGNUMBER + ": " + summary);
+assertEq(Object.freeze(), undefined);
+assertEq(Object.freeze(undefined), undefined);
+assertEq(Object.freeze(null), null);
+assertEq(Object.freeze(1), 1);
+assertEq(Object.freeze("foo"), "foo");
+assertEq(Object.freeze(true), true);
+if (typeof Symbol === "function") {
+    assertEq(Object.freeze(Symbol.for("foo")), Symbol.for("foo"));
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
--- a/toolkit/components/crashmonitor/CrashMonitor.jsm
+++ b/toolkit/components/crashmonitor/CrashMonitor.jsm
@@ -113,16 +113,22 @@ let CrashMonitorInternal = {
       let notifications;
       try {
         notifications = JSON.parse(data);
       } catch (ex) {
         Cu.reportError("Error while parsing crash monitor data: " + ex);
         return null;
       }
 
+      // If `notifications` isn't an object, then the monitor data isn't valid.
+      if (Object(notifications) !== notifications) {
+        Cu.reportError("Error while parsing crash monitor data: invalid monitor data");
+        return null;
+      }
+
       return Object.freeze(notifications);
     });
 
     return this.previousCheckpoints;
   }
 };
 
 this.CrashMonitor = {
--- a/toolkit/components/crashmonitor/test/unit/test_invalid_file.js
+++ b/toolkit/components/crashmonitor/test/unit/test_invalid_file.js
@@ -7,24 +7,16 @@
  * Test with sessionCheckpoints.json containing invalid data
  */
 add_task(function test_invalid_file() {
   // Write bogus data to checkpoint file
   let data = "1234";
   yield OS.File.writeAtomic(sessionCheckpointsPath, data,
                             {tmpPath: sessionCheckpointsPath + ".tmp"});
 
-  // An invalid file will cause |init| to throw an exception
-  try {
-    let status = yield CrashMonitor.init();
-    do_check_true(false);
-  } catch (ex) {
-    do_check_true(true);
-  }
+  // An invalid file will cause |init| to return null
+  let status = yield CrashMonitor.init();
+  do_check_true(status === null ? true : false);
 
-  // and |previousCheckpoints| will be rejected
-  try {
-    let checkpoints = yield CrashMonitor.previousCheckpoints;
-    do_check_true(false);
-  } catch (ex) {
-    do_check_true(true);
-  }
+  // and |previousCheckpoints| will be null
+  let checkpoints = yield CrashMonitor.previousCheckpoints;
+  do_check_true(checkpoints === null ? true : false);
 });