提交 75675c4d 编写于 作者: S sundar

8015355: Array.prototype functions don't honour non-writable length and / or index properties

Reviewed-by: lagergren, hannesw
上级 54b4791b
......@@ -138,18 +138,16 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
@Override
public PropertyDescriptor fillFrom(final ScriptObject sobj) {
final boolean strict = isStrictContext();
if (sobj.has(CONFIGURABLE)) {
this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
} else {
delete(CONFIGURABLE, strict);
delete(CONFIGURABLE, false);
}
if (sobj.has(ENUMERABLE)) {
this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
} else {
delete(ENUMERABLE, strict);
delete(ENUMERABLE, false);
}
if (sobj.has(GET)) {
......@@ -160,7 +158,7 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
throw typeError("not.a.function", ScriptRuntime.safeToString(getter));
}
} else {
delete(GET, strict);
delete(GET, false);
}
if (sobj.has(SET)) {
......@@ -171,7 +169,7 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
throw typeError("not.a.function", ScriptRuntime.safeToString(setter));
}
} else {
delete(SET, strict);
delete(SET, false);
}
return this;
......
......@@ -136,29 +136,28 @@ public final class DataPropertyDescriptor extends ScriptObject implements Proper
@Override
public PropertyDescriptor fillFrom(final ScriptObject sobj) {
final boolean strict = isStrictContext();
if (sobj.has(CONFIGURABLE)) {
this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
} else {
delete(CONFIGURABLE, strict);
delete(CONFIGURABLE, false);
}
if (sobj.has(ENUMERABLE)) {
this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
} else {
delete(ENUMERABLE, strict);
delete(ENUMERABLE, false);
}
if (sobj.has(WRITABLE)) {
this.writable = JSType.toBoolean(sobj.get(WRITABLE));
} else {
delete(WRITABLE, strict);
delete(WRITABLE, false);
}
if (sobj.has(VALUE)) {
this.value = sobj.get(VALUE);
} else {
delete(VALUE, strict);
delete(VALUE, false);
}
return this;
......
......@@ -124,17 +124,16 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro
@Override
public PropertyDescriptor fillFrom(final ScriptObject sobj) {
final boolean strict = isStrictContext();
if (sobj.has(CONFIGURABLE)) {
this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
} else {
delete(CONFIGURABLE, strict);
delete(CONFIGURABLE, false);
}
if (sobj.has(ENUMERABLE)) {
this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
} else {
delete(ENUMERABLE, strict);
delete(ENUMERABLE, false);
}
return this;
......
......@@ -430,15 +430,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
return instance().context;
}
/**
* Script access check for strict mode
*
* @return true if strict mode enabled in {@link Global#getThisContext()}
*/
static boolean isStrict() {
return getEnv()._strict;
}
// GlobalObject interface implementation
@Override
......@@ -616,14 +607,12 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set);
final boolean strict = context.getEnv()._strict;
if (get == null) {
desc.delete(PropertyDescriptor.GET, strict);
desc.delete(PropertyDescriptor.GET, false);
}
if (set == null) {
desc.delete(PropertyDescriptor.SET, strict);
desc.delete(PropertyDescriptor.SET, false);
}
return desc;
......@@ -1485,7 +1474,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
// Error objects
this.builtinError = (ScriptFunction)initConstructor("Error");
final ScriptObject errorProto = getErrorPrototype();
final boolean strict = Global.isStrict();
// Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
......@@ -1503,10 +1491,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
// ECMA 15.11.4.2 Error.prototype.name
// Error.prototype.name = "Error";
errorProto.set(NativeError.NAME, "Error", strict);
errorProto.set(NativeError.NAME, "Error", false);
// ECMA 15.11.4.3 Error.prototype.message
// Error.prototype.message = "";
errorProto.set(NativeError.MESSAGE, "", strict);
errorProto.set(NativeError.MESSAGE, "", false);
this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
......@@ -1519,9 +1507,8 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
final ScriptObject cons = initConstructor(name);
final ScriptObject prototype = ScriptFunction.getPrototype(cons);
final boolean strict = Global.isStrict();
prototype.set(NativeError.NAME, name, strict);
prototype.set(NativeError.MESSAGE, "", strict);
prototype.set(NativeError.NAME, name, false);
prototype.set(NativeError.MESSAGE, "", false);
prototype.setProto(errorProto);
return (ScriptFunction)cons;
}
......@@ -1730,7 +1717,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
// <anon-function>
builtinFunction.setProto(anon);
builtinFunction.setPrototype(anon);
anon.set("constructor", builtinFunction, anon.isStrict());
anon.set("constructor", builtinFunction, false);
anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
// now initialize Object
......
......@@ -118,7 +118,7 @@ public final class NativeArray extends ScriptObject {
if (value == ScriptRuntime.EMPTY) {
arrayData = arrayData.delete(index);
} else {
arrayData = arrayData.set(index, value, isStrictContext());
arrayData = arrayData.set(index, value, false);
}
}
......@@ -158,6 +158,11 @@ public final class NativeArray extends ScriptObject {
// Step 3
if ("length".equals(key)) {
// check for length being made non-writable
if (desc.has(WRITABLE) && !desc.isWritable()) {
setIsLengthNotWritable();
}
// Step 3a
if (!desc.has(VALUE)) {
return super.defineOwnProperty("length", desc, reject);
......@@ -603,7 +608,6 @@ public final class NativeArray extends ScriptObject {
public static Object pop(final Object self) {
try {
final ScriptObject sobj = (ScriptObject)self;
final boolean strict = sobj.isStrictContext();
if (bulkable(sobj)) {
return sobj.getArray().pop();
......@@ -612,15 +616,15 @@ public final class NativeArray extends ScriptObject {
final long len = JSType.toUint32(sobj.getLength());
if (len == 0) {
sobj.set("length", 0, strict);
sobj.set("length", 0, true);
return ScriptRuntime.UNDEFINED;
}
final long index = len - 1;
final Object element = sobj.get(index);
sobj.delete(index, strict);
sobj.set("length", index, strict);
sobj.delete(index, true);
sobj.set("length", index, true);
return element;
} catch (final ClassCastException | NullPointerException e) {
......@@ -639,11 +643,10 @@ public final class NativeArray extends ScriptObject {
public static Object push(final Object self, final Object... args) {
try {
final ScriptObject sobj = (ScriptObject)self;
final boolean strict = sobj.isStrictContext();
if (bulkable(sobj)) {
if (sobj.getArray().length() + args.length <= JSType.MAX_UINT) {
final ArrayData newData = sobj.getArray().push(sobj.isStrictContext(), args);
final ArrayData newData = sobj.getArray().push(true, args);
sobj.setArray(newData);
return newData.length();
}
......@@ -652,9 +655,9 @@ public final class NativeArray extends ScriptObject {
long len = JSType.toUint32(sobj.getLength());
for (final Object element : args) {
sobj.set(len++, element, strict);
sobj.set(len++, element, true);
}
sobj.set("length", len, strict);
sobj.set("length", len, true);
return len;
} catch (final ClassCastException | NullPointerException e) {
......@@ -672,7 +675,6 @@ public final class NativeArray extends ScriptObject {
public static Object reverse(final Object self) {
try {
final ScriptObject sobj = (ScriptObject)self;
final boolean strict = sobj.isStrictContext();
final long len = JSType.toUint32(sobj.getLength());
final long middle = len / 2;
......@@ -684,14 +686,14 @@ public final class NativeArray extends ScriptObject {
final boolean upperExists = sobj.has(upper);
if (lowerExists && upperExists) {
sobj.set(lower, upperValue, strict);
sobj.set(upper, lowerValue, strict);
sobj.set(lower, upperValue, true);
sobj.set(upper, lowerValue, true);
} else if (!lowerExists && upperExists) {
sobj.set(lower, upperValue, strict);
sobj.delete(upper, strict);
sobj.set(lower, upperValue, true);
sobj.delete(upper, true);
} else if (lowerExists && !upperExists) {
sobj.delete(lower, strict);
sobj.set(upper, lowerValue, strict);
sobj.delete(lower, true);
sobj.set(upper, lowerValue, true);
}
}
return sobj;
......@@ -717,7 +719,6 @@ public final class NativeArray extends ScriptObject {
}
final ScriptObject sobj = (ScriptObject) obj;
final boolean strict = Global.isStrict();
long len = JSType.toUint32(sobj.getLength());
......@@ -728,15 +729,15 @@ public final class NativeArray extends ScriptObject {
sobj.getArray().shiftLeft(1);
} else {
for (long k = 1; k < len; k++) {
sobj.set(k - 1, sobj.get(k), strict);
sobj.set(k - 1, sobj.get(k), true);
}
}
sobj.delete(--len, strict);
sobj.delete(--len, true);
} else {
len = 0;
}
sobj.set("length", len, strict);
sobj.set("length", len, true);
return first;
}
......@@ -833,7 +834,6 @@ public final class NativeArray extends ScriptObject {
public static Object sort(final Object self, final Object comparefn) {
try {
final ScriptObject sobj = (ScriptObject) self;
final boolean strict = sobj.isStrictContext();
final long len = JSType.toUint32(sobj.getLength());
ArrayData array = sobj.getArray();
......@@ -850,7 +850,7 @@ public final class NativeArray extends ScriptObject {
final Object[] sorted = sort(src.toArray(), comparefn);
for (int i = 0; i < sorted.length; i++) {
array = array.set(i, sorted[i], strict);
array = array.set(i, sorted[i], true);
}
// delete missing elements - which are at the end of sorted array
......@@ -891,7 +891,6 @@ public final class NativeArray extends ScriptObject {
}
final ScriptObject sobj = (ScriptObject)obj;
final boolean strict = Global.isStrict();
final long len = JSType.toUint32(sobj.getLength());
final long relativeStart = JSType.toLong(start);
......@@ -914,14 +913,14 @@ public final class NativeArray extends ScriptObject {
final long to = k + items.length;
if (sobj.has(from)) {
sobj.set(to, sobj.get(from), strict);
sobj.set(to, sobj.get(from), true);
} else {
sobj.delete(to, strict);
sobj.delete(to, true);
}
}
for (long k = len; k > (len - actualDeleteCount + items.length); k--) {
sobj.delete(k - 1, strict);
sobj.delete(k - 1, true);
}
} else if (items.length > actualDeleteCount) {
for (long k = len - actualDeleteCount; k > actualStart; k--) {
......@@ -930,20 +929,20 @@ public final class NativeArray extends ScriptObject {
if (sobj.has(from)) {
final Object fromValue = sobj.get(from);
sobj.set(to, fromValue, strict);
sobj.set(to, fromValue, true);
} else {
sobj.delete(to, strict);
sobj.delete(to, true);
}
}
}
long k = actualStart;
for (int i = 0; i < items.length; i++, k++) {
sobj.set(k, items[i], strict);
sobj.set(k, items[i], true);
}
final long newLength = len - actualDeleteCount + items.length;
sobj.set("length", newLength, strict);
sobj.set("length", newLength, true);
return array;
}
......@@ -964,7 +963,6 @@ public final class NativeArray extends ScriptObject {
}
final ScriptObject sobj = (ScriptObject)obj;
final boolean strict = Global.isStrict();
final long len = JSType.toUint32(sobj.getLength());
if (items == null) {
......@@ -975,7 +973,7 @@ public final class NativeArray extends ScriptObject {
sobj.getArray().shiftRight(items.length);
for (int j = 0; j < items.length; j++) {
sobj.setArray(sobj.getArray().set(j, items[j], sobj.isStrictContext()));
sobj.setArray(sobj.getArray().set(j, items[j], true));
}
} else {
for (long k = len; k > 0; k--) {
......@@ -984,19 +982,19 @@ public final class NativeArray extends ScriptObject {
if (sobj.has(from)) {
final Object fromValue = sobj.get(from);
sobj.set(to, fromValue, strict);
sobj.set(to, fromValue, true);
} else {
sobj.delete(to, strict);
sobj.delete(to, true);
}
}
for (int j = 0; j < items.length; j++) {
sobj.set(j, items[j], strict);
sobj.set(j, items[j], true);
}
}
final long newLength = len + items.length;
sobj.set("length", newLength, strict);
sobj.set("length", newLength, true);
return newLength;
}
......@@ -1239,7 +1237,7 @@ public final class NativeArray extends ScriptObject {
* @return true if optimizable
*/
private static boolean bulkable(final ScriptObject self) {
return self.isArray() && !hasInheritedArrayEntries(self);
return self.isArray() && !hasInheritedArrayEntries(self) && !self.isLengthNotWritable();
}
private static boolean hasInheritedArrayEntries(final ScriptObject self) {
......
......@@ -90,7 +90,7 @@ public final class NativeError extends ScriptObject {
if (msg != UNDEFINED) {
this.instMessage = JSType.toString(msg);
} else {
this.delete(NativeError.MESSAGE, Global.isStrict());
this.delete(NativeError.MESSAGE, false);
}
}
......@@ -166,7 +166,7 @@ public final class NativeError extends ScriptObject {
public static Object setLineNumber(final Object self, final Object value) {
Global.checkObject(self);
final ScriptObject sobj = (ScriptObject)self;
sobj.set(LINENUMBER, value, Global.isStrict());
sobj.set(LINENUMBER, value, false);
return value;
}
......@@ -194,7 +194,7 @@ public final class NativeError extends ScriptObject {
public static Object setColumnNumber(final Object self, final Object value) {
Global.checkObject(self);
final ScriptObject sobj = (ScriptObject)self;
sobj.set(COLUMNNUMBER, value, Global.isStrict());
sobj.set(COLUMNNUMBER, value, false);
return value;
}
......@@ -222,7 +222,7 @@ public final class NativeError extends ScriptObject {
public static Object setFileName(final Object self, final Object value) {
Global.checkObject(self);
final ScriptObject sobj = (ScriptObject)self;
sobj.set(FILENAME, value, Global.isStrict());
sobj.set(FILENAME, value, false);
return value;
}
......@@ -278,7 +278,7 @@ public final class NativeError extends ScriptObject {
public static Object setStack(final Object self, final Object value) {
Global.checkObject(self);
final ScriptObject sobj = (ScriptObject)self;
sobj.set(STACK, value, Global.isStrict());
sobj.set(STACK, value, false);
return value;
}
......
......@@ -59,7 +59,7 @@ public final class NativeEvalError extends ScriptObject {
if (msg != UNDEFINED) {
this.instMessage = JSType.toString(msg);
} else {
this.delete(NativeError.MESSAGE, Global.isStrict());
this.delete(NativeError.MESSAGE, false);
}
}
......
......@@ -216,7 +216,7 @@ public final class NativeFunction {
final Global global = Global.instance();
return Global.directEval(global, sb.toString(), global, "<function>", Global.isStrict());
return Global.directEval(global, sb.toString(), global, "<function>", global.isStrictContext());
}
private static void checkFunctionParameters(final String params) {
......
......@@ -158,7 +158,7 @@ public final class NativeJSON extends ScriptObject {
state.gap = gap;
final ScriptObject wrapper = Global.newEmptyInstance();
wrapper.set("", value, Global.isStrict());
wrapper.set("", value, false);
return str("", wrapper, state);
}
......
......@@ -121,7 +121,7 @@ public final class NativeJavaImporter extends ScriptObject {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final Object value = createProperty(name);
if(value != null) {
set(name, value, isStrictContext());
set(name, value, false);
return true;
}
return false;
......
......@@ -59,7 +59,7 @@ public final class NativeRangeError extends ScriptObject {
if (msg != UNDEFINED) {
this.instMessage = JSType.toString(msg);
} else {
this.delete(NativeError.MESSAGE, Global.isStrict());
this.delete(NativeError.MESSAGE, false);
}
}
......
......@@ -59,7 +59,7 @@ public final class NativeReferenceError extends ScriptObject {
if (msg != UNDEFINED) {
this.instMessage = JSType.toString(msg);
} else {
this.delete(NativeError.MESSAGE, Global.isStrict());
this.delete(NativeError.MESSAGE, false);
}
}
......
......@@ -59,7 +59,7 @@ public final class NativeSyntaxError extends ScriptObject {
if (msg != UNDEFINED) {
this.instMessage = JSType.toString(msg);
} else {
this.delete(NativeError.MESSAGE, Global.isStrict());
this.delete(NativeError.MESSAGE, false);
}
}
......
......@@ -59,7 +59,7 @@ public final class NativeTypeError extends ScriptObject {
if (msg != UNDEFINED) {
this.instMessage = JSType.toString(msg);
} else {
delete(NativeError.MESSAGE, Global.isStrict());
delete(NativeError.MESSAGE, false);
}
}
......
......@@ -58,7 +58,7 @@ public final class NativeURIError extends ScriptObject {
if (msg != UNDEFINED) {
this.instMessage = JSType.toString(msg);
} else {
this.delete(NativeError.MESSAGE, Global.isStrict());
this.delete(NativeError.MESSAGE, false);
}
}
......
......@@ -188,7 +188,7 @@ public final class Context {
private final ScriptEnvironment env;
/** is this context in strict mode? Cached from env. as this is used heavily. */
public final boolean _strict;
final boolean _strict;
/** class loader to resolve classes from script. */
private final ClassLoader appLoader;
......
......@@ -101,7 +101,6 @@ public final class JSONFunctions {
final Object val = holder.get(name);
if (val instanceof ScriptObject) {
final ScriptObject valueObj = (ScriptObject)val;
final boolean strict = valueObj.isStrictContext();
final Iterator<String> iter = valueObj.propertyIterator();
while (iter.hasNext()) {
......@@ -109,9 +108,9 @@ public final class JSONFunctions {
final Object newElement = walk(valueObj, key, reviver);
if (newElement == ScriptRuntime.UNDEFINED) {
valueObj.delete(key, strict);
valueObj.delete(key, false);
} else {
setPropertyValue(valueObj, key, newElement, strict);
setPropertyValue(valueObj, key, newElement, false);
}
}
}
......@@ -164,14 +163,13 @@ public final class JSONFunctions {
} else if (node instanceof ObjectNode) {
final ObjectNode objNode = (ObjectNode) node;
final ScriptObject object = ((GlobalObject)global).newObject();
final boolean strict = global.isStrictContext();
for (final PropertyNode pNode: objNode.getElements()) {
final Node valueNode = pNode.getValue();
final String name = pNode.getKeyName();
final Object value = convertNode(global, valueNode);
setPropertyValue(object, name, value, strict);
setPropertyValue(object, name, value, false);
}
return object;
......
......@@ -199,7 +199,6 @@ public final class NativeJavaPackage extends ScriptObject {
final String fullName = name.isEmpty() ? propertyName : name + "." + propertyName;
final Context context = getContext();
final boolean strict = context._strict;
Class<?> javaClass = null;
try {
......@@ -209,9 +208,9 @@ public final class NativeJavaPackage extends ScriptObject {
}
if (javaClass == null) {
set(propertyName, new NativeJavaPackage(fullName, getProto()), strict);
set(propertyName, new NativeJavaPackage(fullName, getProto()), false);
} else {
set(propertyName, StaticClass.forClass(javaClass), strict);
set(propertyName, StaticClass.forClass(javaClass), false);
}
return super.lookup(desc, request);
......
......@@ -105,6 +105,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
/** Is this a prototype PropertyMap? */
public static final int IS_PROTOTYPE = 0b0000_1000;
/** Is length property not-writable? */
public static final int IS_LENGTH_NOT_WRITABLE = 0b0001_0000;
/** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
public static final int SPILL_RATE = 8;
......@@ -443,7 +446,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
if (newValue && property != null) {
// Temporarily clear flags.
property = modifyOwnProperty(property, 0);
set(key, value, getContext()._strict);
set(key, value, false);
}
if (property == null) {
......@@ -998,7 +1001,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* @param value the value to write at the given index
*/
public void setArgument(final int key, final Object value) {
set(key, value, getContext()._strict);
set(key, value, false);
}
/**
......@@ -1277,20 +1280,36 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
*
* @return {@code true} if is prototype
*/
public boolean isPrototype() {
public final boolean isPrototype() {
return (flags & IS_PROTOTYPE) != 0;
}
/**
* Flag this object as having a prototype.
*/
public void setIsPrototype() {
public final void setIsPrototype() {
if (proto != null && !isPrototype()) {
proto.addPropertyListener(this);
}
flags |= IS_PROTOTYPE;
}
/**
* Check if this object has non-writable length property
*
* @return {@code true} if 'length' property is non-writable
*/
public final boolean isLengthNotWritable() {
return (flags & IS_LENGTH_NOT_WRITABLE) != 0;
}
/**
* Flag this object as having non-writable length property
*/
public void setIsLengthNotWritable() {
flags |= IS_LENGTH_NOT_WRITABLE;
}
/**
* Get the {@link ArrayData} for this ScriptObject if it is an array
* @return array data
......@@ -1393,7 +1412,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* (java.util.Map-like method to help ScriptObjectMirror implementation)
*/
public void clear() {
final boolean strict = getContext()._strict;
final boolean strict = isStrictContext();
final Iterator<String> iter = propertyIterator();
while (iter.hasNext()) {
delete(iter.next(), strict);
......@@ -1481,7 +1500,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
*/
public Object put(final Object key, final Object value) {
final Object oldValue = get(key);
set(key, value, getContext()._strict);
set(key, value, isStrictContext());
return oldValue;
}
......@@ -1493,7 +1512,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* @param otherMap a {@literal <key,value>} map of properties to add
*/
public void putAll(final Map<?, ?> otherMap) {
final boolean strict = getContext()._strict;
final boolean strict = isStrictContext();
for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
set(entry.getKey(), entry.getValue(), strict);
}
......@@ -1508,7 +1527,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
*/
public Object remove(final Object key) {
final Object oldValue = get(key);
delete(key, getContext()._strict);
delete(key, isStrictContext());
return oldValue;
}
......@@ -1520,7 +1539,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* @return if the delete was successful or not
*/
public boolean delete(final Object key) {
return delete(key, getContext()._strict);
return delete(key, isStrictContext());
}
/**
......@@ -2222,7 +2241,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
return;
}
final boolean isStrict = getContext()._strict;
final boolean isStrict = isStrictContext();
if (newLength > arrayLength) {
setArray(getArray().ensure(newLength - 1));
......
......@@ -221,10 +221,9 @@ public final class ScriptingFunctions {
final String err = errBuffer.toString();
// Set globals for secondary results.
final boolean isStrict = global.isStrictContext();
global.set(OUT_NAME, out, isStrict);
global.set(ERR_NAME, err, isStrict);
global.set(EXIT_NAME, exit, isStrict);
global.set(OUT_NAME, out, false);
global.set(ERR_NAME, err, false);
global.set(EXIT_NAME, exit, false);
// Propagate exception if present.
for (int i = 0; i < exception.length; i++) {
......
......@@ -83,6 +83,6 @@ public class ArrayIterator extends ArrayLikeIterator<Object> {
@Override
public void remove() {
array.delete(index, array.isStrictContext());
array.delete(index, false);
}
}
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8015355: Array.prototype functions don't honour non-writable length and / or index properties
*
* @test
* @run
*/
function fail(msg) {
print(msg);
}
function check(callback) {
try {
callback();
fail("TypeError expected for " + callback);
} catch (e) {
if (! (e instanceof TypeError)) {
fail("TypeError expected, got " + e);
}
}
}
var array = Object.defineProperty([],"length", { writable: false });
check(function() {
array.push(0)
});
check(function() {
array.pop()
});
check(function() {
Object.defineProperty([,,],"0",{ writable: false }).reverse();
});
check(function() {
array.shift()
});
check(function() {
array.splice(0)
});
check(function() {
array.unshift()
});
// try the above via call
check(function() {
Array.prototype.push.call(array, 0);
});
check(function() {
Array.prototype.pop.call(array);
});
check(function() {
Array.prototype.shift.call(array);
});
check(function() {
Array.prototype.unshift.call(array);
});
check(function() {
Array.prototype.splice.call(array, 0);
});
check(function() {
Array.prototype.reverse.call(Object.defineProperty([,,],"0",{ writable: false }));
});
// try the above via apply
check(function() {
Array.prototype.push.apply(array, [ 0 ]);
});
check(function() {
Array.prototype.pop.apply(array);
});
check(function() {
Array.prototype.shift.apply(array);
});
check(function() {
Array.prototype.unshift.apply(array);
});
check(function() {
Array.prototype.splice.apply(array, [ 0 ]);
});
check(function() {
Array.prototype.reverse.apply(Object.defineProperty([,,],"0",{ writable: false }));
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册