mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 02:35:41 +00:00
Bug 886087 - Explicitly tell js_ReportGetterOnlyAssignment whether the assignment was strict rather than examining the stack. r=Waldo.
This commit is contained in:
parent
11c11d8f5b
commit
50a04a5f70
@ -0,0 +1,13 @@
|
||||
// Array.prototype.pop does a strict assignment to this.length even if the
|
||||
// caller is nonstrict. Bug 886087.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
// obj.length is read-only
|
||||
var obj = {pop: [].pop, 0: "zero"};
|
||||
Object.defineProperty(obj, "length", {configurable: true, value: 1, writable: false});
|
||||
assertThrowsInstanceOf(() => obj.pop(), TypeError);
|
||||
|
||||
// obj.length has only a getter
|
||||
obj = {pop: [].pop, 0: "zero", get length() { return 1; }};
|
||||
assertThrowsInstanceOf(() => obj.pop(), TypeError);
|
@ -0,0 +1,13 @@
|
||||
// Array.prototype.reverse does a strict assignment to this.length even if the
|
||||
// caller is nonstrict. Bug 886087.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
// obj[1] is read-only
|
||||
var obj = {0: "zero", length: 2, reverse: [].reverse};
|
||||
Object.defineProperty(obj, "1", {configurable: true, value: "one", writable: false});
|
||||
assertThrowsInstanceOf(() => obj.reverse(), TypeError);
|
||||
|
||||
// obj[1] has only a getter
|
||||
Object.defineProperty(obj, "1", {configurable: true, get: () => "one"});
|
||||
assertThrowsInstanceOf(() => obj.reverse(), TypeError);
|
29
js/src/jit-test/tests/arrays/sort-getter-only.js
Normal file
29
js/src/jit-test/tests/arrays/sort-getter-only.js
Normal file
@ -0,0 +1,29 @@
|
||||
// The property assignments in Array.prototype.sort are strict assignments.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var a = ["A", , "B", "C", "D"];
|
||||
var normalArrayElementDesc = Object.getOwnPropertyDescriptor(a, 0);
|
||||
var getterDesc = {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
get: function () { return "F"; },
|
||||
set: undefined
|
||||
};
|
||||
Object.defineProperty(a, 1, getterDesc);
|
||||
|
||||
// a.sort is permitted to try to delete a[1] or to try to assign a[1], but it
|
||||
// must try one or the other. Either one will fail, throwing a TypeError.
|
||||
assertThrowsInstanceOf(() => a.sort(), TypeError);
|
||||
|
||||
// a.sort() is not permitted to delete the nonconfigurable property.
|
||||
assertDeepEq(Object.getOwnPropertyDescriptor(a, 1), getterDesc);
|
||||
|
||||
// The values left in the other elements of a are unspecified; some or all may
|
||||
// have been deleted.
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (i !== 1 && a.hasOwnProperty(i)) {
|
||||
normalArrayElementDesc.value = a[i];
|
||||
assertDeepEq(Object.getOwnPropertyDescriptor(a, i), normalArrayElementDesc);
|
||||
}
|
||||
}
|
@ -328,7 +328,7 @@ CallSetter(JSContext *cx, HandleObject obj, HandleId id, StrictPropertyOp op, un
|
||||
}
|
||||
|
||||
if (attrs & JSPROP_GETTER)
|
||||
return js_ReportGetterOnlyAssignment(cx);
|
||||
return js_ReportGetterOnlyAssignment(cx, strict);
|
||||
|
||||
if (!(attrs & JSPROP_SHORTID))
|
||||
return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp);
|
||||
|
@ -3944,7 +3944,7 @@ js_NativeSet(JSContext *cx, Handle<JSObject*> obj, Handle<JSObject*> receiver,
|
||||
* or throw if we're in strict mode.
|
||||
*/
|
||||
if (!shape->hasGetterValue() && shape->hasDefaultSetter())
|
||||
return js_ReportGetterOnlyAssignment(cx);
|
||||
return js_ReportGetterOnlyAssignment(cx, strict);
|
||||
}
|
||||
|
||||
RootedValue ovp(cx, vp);
|
||||
@ -4475,7 +4475,7 @@ baseops::SetPropertyHelper(JSContext *cx, HandleObject obj, HandleObject receive
|
||||
/* ES5 8.12.4 [[Put]] step 2. */
|
||||
if (shape->isAccessorDescriptor()) {
|
||||
if (shape->hasDefaultSetter())
|
||||
return js_ReportGetterOnlyAssignment(cx);
|
||||
return js_ReportGetterOnlyAssignment(cx, strict);
|
||||
} else {
|
||||
JS_ASSERT(shape->isDataDescriptor());
|
||||
|
||||
@ -5132,11 +5132,12 @@ js_GetObjectSlotName(JSTracer *trc, char *buf, size_t bufsize)
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_ReportGetterOnlyAssignment(JSContext *cx)
|
||||
js_ReportGetterOnlyAssignment(JSContext *cx, bool strict)
|
||||
{
|
||||
return JS_ReportErrorFlagsAndNumber(cx,
|
||||
JSREPORT_WARNING | JSREPORT_STRICT |
|
||||
JSREPORT_STRICT_MODE_ERROR,
|
||||
strict
|
||||
? JSREPORT_ERROR
|
||||
: JSREPORT_WARNING | JSREPORT_STRICT,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_GETTER_ONLY);
|
||||
}
|
||||
|
@ -1513,7 +1513,7 @@ extern void
|
||||
js_GetObjectSlotName(JSTracer *trc, char *buf, size_t bufsize);
|
||||
|
||||
extern JSBool
|
||||
js_ReportGetterOnlyAssignment(JSContext *cx);
|
||||
js_ReportGetterOnlyAssignment(JSContext *cx, bool strict);
|
||||
|
||||
extern unsigned
|
||||
js_InferFlags(JSContext *cx, unsigned defaultFlags);
|
||||
|
@ -26,12 +26,7 @@ reportCompare("3|54|1|", actual, "forEach");
|
||||
actual = a.join(' - ');
|
||||
reportCompare("3 - 54 - 1", actual, "join");
|
||||
|
||||
actual = String(a.sort());
|
||||
reportCompare("1,54,54", actual, "sort");
|
||||
|
||||
a[2]=3;
|
||||
reportCompare(actual, "1,54,54", "setter");
|
||||
|
||||
actual = a.pop();
|
||||
reportCompare(actual, 3, "pop");
|
||||
|
||||
|
@ -327,7 +327,7 @@ Shape::set(JSContext* cx, HandleObject obj, HandleObject receiver, bool strict,
|
||||
}
|
||||
|
||||
if (attrs & JSPROP_GETTER)
|
||||
return js_ReportGetterOnlyAssignment(cx);
|
||||
return js_ReportGetterOnlyAssignment(cx, strict);
|
||||
|
||||
Rooted<Shape *> self(cx, this);
|
||||
RootedId id(cx);
|
||||
|
Loading…
Reference in New Issue
Block a user