8015354: JSON.parse should not use [[Put]] but use [[DefineOwnProperty]] instead
Reviewed-by: lagergren, hannesw
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java Fri May 24 18:39:25 2013 +0530
@@ -40,6 +40,9 @@
*/
@ScriptClass("Float32Array")
public final class NativeFloat32Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 4;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java Fri May 24 18:39:25 2013 +0530
@@ -40,6 +40,9 @@
*/
@ScriptClass("Float64Array")
public final class NativeFloat64Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 8;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java Fri May 24 18:39:25 2013 +0530
@@ -39,6 +39,9 @@
*/
@ScriptClass("Int16Array")
public final class NativeInt16Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 2;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java Fri May 24 18:39:25 2013 +0530
@@ -39,6 +39,9 @@
*/
@ScriptClass("Int32Array")
public final class NativeInt32Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 4;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java Fri May 24 18:39:25 2013 +0530
@@ -39,6 +39,9 @@
*/
@ScriptClass("Int8Array")
public final class NativeInt8Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 1;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java Fri May 24 18:39:25 2013 +0530
@@ -39,6 +39,9 @@
*/
@ScriptClass("Uint16Array")
public final class NativeUint16Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 2;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java Fri May 24 18:39:25 2013 +0530
@@ -40,6 +40,9 @@
*/
@ScriptClass("Uint32Array")
public final class NativeUint32Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 4;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java Fri May 24 18:39:25 2013 +0530
@@ -39,6 +39,9 @@
*/
@ScriptClass("Uint8Array")
public final class NativeUint8Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 1;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Fri May 24 18:39:25 2013 +0530
@@ -40,6 +40,9 @@
*/
@ScriptClass("Uint8ClampedArray")
public final class NativeUint8ClampedArray extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 1;
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java Fri May 24 18:39:25 2013 +0530
@@ -36,6 +36,8 @@
import jdk.nashorn.internal.parser.JSONParser;
import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
+import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
+import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
/**
* Utilities used by "JSON" object implementation.
@@ -94,7 +96,7 @@
if (reviver instanceof ScriptFunction) {
assert global instanceof GlobalObject;
final ScriptObject root = ((GlobalObject)global).newObject();
- root.set("", unfiltered, root.isStrictContext());
+ root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
return walk(root, "", (ScriptFunction)reviver);
}
return unfiltered;
@@ -115,7 +117,7 @@
if (newElement == ScriptRuntime.UNDEFINED) {
valueObj.delete(key, strict);
} else {
- valueObj.set(key, newElement, strict);
+ setPropertyValue(valueObj, key, newElement, strict);
}
}
}
@@ -175,7 +177,9 @@
final PropertyNode pNode = (PropertyNode) elem;
final Node valueNode = pNode.getValue();
- object.set(pNode.getKeyName(), convertNode(global, valueNode), strict);
+ final String name = pNode.getKeyName();
+ final Object value = convertNode(global, valueNode);
+ setPropertyValue(object, name, value, strict);
}
return object;
@@ -188,6 +192,21 @@
}
}
+ // add a new property if does not exist already, or else set old property
+ private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
+ final int index = getArrayIndexNoThrow(name);
+ if (isValidArrayIndex(index)) {
+ // array index key
+ sobj.defineOwnProperty(index, value);
+ } else if (sobj.getMap().findProperty(name) != null) {
+ // pre-existing non-inherited property, call set
+ sobj.set(name, value, strict);
+ } else {
+ // add new property
+ sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
+ }
+ }
+
// does the given IR node represent a numeric array?
private static boolean isNumericArray(final Node[] values) {
for (final Node node : values) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java Fri May 24 13:54:18 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java Fri May 24 18:39:25 2013 +0530
@@ -52,6 +52,8 @@
* we can use leave flag byte initialized with (the default) zero value.
*/
+ public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000;
+
/** ECMA 8.6.1 - Is this property not writable? */
public static final int NOT_WRITABLE = 0b0000_0000_0001;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8015354.js Fri May 24 18:39:25 2013 +0530
@@ -0,0 +1,46 @@
+/*
+ * 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-8015354: JSON.parse should not use [[Put]] but use [[DefineOwnProperty]] instead
+ *
+ * @test
+ * @run
+ */
+
+Object.defineProperty(Object.prototype,
+ "", {
+ set: function(v) {
+ throw "set called";
+ }
+});
+
+JSON.parse('{}',function(){});
+
+Object.defineProperty(Object.prototype,
+ "foo",{
+ set: function(v) {
+ throw "set called";
+ }
+});
+JSON.parse('{"foo": 1}');