Reviewers: Mads Ager,

Description:
Fix bug in JSON.parse for objects containing "__proto__" as key.

It added the __proto__ key as a normal key, which made it visible
in enumeration, while reading still hit the hard-coded accessor.

Please review this at http://codereview.chromium.org/6451002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge/build-ia32

Affected files:
  M src/parser.cc
  M test/mjsunit/json.js


Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 5353a63460bf12025e2a6986247104e807fa25fc..2217f23e58977fd47b4d730bcd3b51e768f132e2 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -4058,6 +4058,11 @@ Handle<Object> JsonParser::ParseJsonObject() {
       uint32_t index;
       if (key->AsArrayIndex(&index)) {
         SetOwnElement(json_object, index, value);
+      } else if (key->Equals(Heap::Proto_symbol())) {
+        // We can't remove the __proto__ accessor since it's hardcoded
+        // in several places. Instead go along and add the value as
+        // the prototype of the created object if possible.
+        SetPrototype(json_object, value);
       } else {
         SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
       }
Index: test/mjsunit/json.js
diff --git a/test/mjsunit/json.js b/test/mjsunit/json.js
index a0be8dd133504f192403335d4523445b52b332d8..812ffeb5a7ba3c74ca51f4cec34ee32945a88686 100644
--- a/test/mjsunit/json.js
+++ b/test/mjsunit/json.js
@@ -415,3 +415,17 @@ var falseNum = Object("37");
 falseNum.__proto__ = Number.prototype;
 falseNum.toString = function() { return 42; };
 assertEquals('"42"', JSON.stringify(falseNum));
+
+// We don't currently allow plain properties called __proto__ in JSON
+// objects in JSON.parse. Instead we read them as we would JS object
+// literals. If we change that, this test should change with it.
+//
+// Parse a non-object value as __proto__. This must not create a
+// __proto__ property different from the original, and should not
+// change the original.
+var o = JSON.parse('{"__proto__":5}');
+assertEquals(Object.prototype, o.__proto__);  // __proto__ isn't changed.
+assertEquals(0, Object.keys(o).length); // __proto__ isn't added as enumerable.
+
+
+


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to