Bug 1076588 - Object.freeze() should return its argument with no conversion when the argument is a primitive value. r=till, r=Yoric
--- 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);
});