From ab0445c528214ca0c0ca52622afb80965b7058ef Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Fri, 16 Mar 2012 12:47:21 -0700 Subject: [PATCH] Bug 596351 - Proxies should throw TypeErrors for assignments to read-only properties in ES5 strict mode. r=luke --- js/src/jit-test/tests/basic/bug596351-1.js | 5 +++++ js/src/jit-test/tests/basic/bug596351-2.js | 7 +++++++ js/src/jsproxy.cpp | 24 ++++++++++++++++++++-- js/src/jswrapper.cpp | 3 +-- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 js/src/jit-test/tests/basic/bug596351-1.js create mode 100644 js/src/jit-test/tests/basic/bug596351-2.js diff --git a/js/src/jit-test/tests/basic/bug596351-1.js b/js/src/jit-test/tests/basic/bug596351-1.js new file mode 100644 index 00000000000..30947711255 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug596351-1.js @@ -0,0 +1,5 @@ +// |jit-test| error: TypeError +"use strict" +var g = newGlobal('new-compartment'); +g.eval("foo = {}; Object.defineProperty(foo, 'a', {value: 2, writable: false});"); +g.foo.a = 3; diff --git a/js/src/jit-test/tests/basic/bug596351-2.js b/js/src/jit-test/tests/basic/bug596351-2.js new file mode 100644 index 00000000000..162ec659d6b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug596351-2.js @@ -0,0 +1,7 @@ +// |jit-test| error: TypeError + +"use strict" +var g = newGlobal('new-compartment'); + +g.eval("bar = {}; Object.freeze(bar);"); +g.bar.a = 4; diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index 8878c2cacd9..3765a1ba291 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -182,8 +182,18 @@ ProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, b return false; /* The control-flow here differs from ::get() because of the fall-through case below. */ if (desc.obj) { - if (desc.attrs & JSPROP_READONLY) + // Check for read-only properties. + if (desc.attrs & JSPROP_READONLY) { + if (strict) { + JSAutoByteString bytes(cx, JSID_TO_STRING(id)); + if (!bytes) + return false; + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_REDEFINE_PROP, bytes.ptr()); + return false; + } return true; + } if (!desc.setter) { // Be wary of the odd explicit undefined setter case possible through // Object.defineProperty. @@ -208,8 +218,18 @@ ProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, b if (!getPropertyDescriptor(cx, proxy, id, true, &desc)) return false; if (desc.obj) { - if (desc.attrs & JSPROP_READONLY) + // Check for read-only properties. + if (desc.attrs & JSPROP_READONLY) { + if (strict) { + JSAutoByteString bytes(cx, JSID_TO_STRING(id)); + if (!bytes) + return false; + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_REDEFINE_PROP, bytes.ptr()); + return false; + } return true; + } if (!desc.setter) { // Be wary of the odd explicit undefined setter case possible through // Object.defineProperty. diff --git a/js/src/jswrapper.cpp b/js/src/jswrapper.cpp index edc06c524a0..f7d50172312 100644 --- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -230,8 +230,7 @@ bool Wrapper::set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict, Value *vp) { - // FIXME (bug 596351): Need deal with strict mode. - SET(wrappedObject(wrapper)->setGeneric(cx, id, vp, false)); + SET(wrappedObject(wrapper)->setGeneric(cx, id, vp, strict)); } bool