OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/value-serializer.h" | 5 #include "src/value-serializer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "include/v8.h" | 10 #include "include/v8.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 ASSERT_FALSE(try_catch.HasCaught()); | 101 ASSERT_FALSE(try_catch.HasCaught()); |
102 ASSERT_TRUE(deserialization_context() | 102 ASSERT_TRUE(deserialization_context() |
103 ->Global() | 103 ->Global() |
104 ->CreateDataProperty(deserialization_context_, | 104 ->CreateDataProperty(deserialization_context_, |
105 StringFromUtf8("result"), result) | 105 StringFromUtf8("result"), result) |
106 .FromMaybe(false)); | 106 .FromMaybe(false)); |
107 output_functor(result); | 107 output_functor(result); |
108 ASSERT_FALSE(try_catch.HasCaught()); | 108 ASSERT_FALSE(try_catch.HasCaught()); |
109 } | 109 } |
110 | 110 |
| 111 template <typename OutputFunctor> |
| 112 void DecodeTestForVersion0(const std::vector<uint8_t>& data, |
| 113 const OutputFunctor& output_functor) { |
| 114 Context::Scope scope(deserialization_context()); |
| 115 TryCatch try_catch(isolate()); |
| 116 // TODO(jbroman): Use the public API once it exists. |
| 117 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate()); |
| 118 i::HandleScope handle_scope(internal_isolate); |
| 119 i::ValueDeserializer deserializer( |
| 120 internal_isolate, |
| 121 i::Vector<const uint8_t>(&data[0], static_cast<int>(data.size()))); |
| 122 // TODO(jbroman): Enable legacy support. |
| 123 ASSERT_TRUE(deserializer.ReadHeader().FromMaybe(false)); |
| 124 // TODO(jbroman): Check version 0. |
| 125 Local<Value> result; |
| 126 ASSERT_TRUE(ToLocal<Value>( |
| 127 deserializer.ReadObjectUsingEntireBufferForLegacyFormat(), &result)); |
| 128 ASSERT_FALSE(result.IsEmpty()); |
| 129 ASSERT_FALSE(try_catch.HasCaught()); |
| 130 ASSERT_TRUE(deserialization_context() |
| 131 ->Global() |
| 132 ->CreateDataProperty(deserialization_context_, |
| 133 StringFromUtf8("result"), result) |
| 134 .FromMaybe(false)); |
| 135 output_functor(result); |
| 136 ASSERT_FALSE(try_catch.HasCaught()); |
| 137 } |
| 138 |
111 void InvalidDecodeTest(const std::vector<uint8_t>& data) { | 139 void InvalidDecodeTest(const std::vector<uint8_t>& data) { |
112 Context::Scope scope(deserialization_context()); | 140 Context::Scope scope(deserialization_context()); |
113 TryCatch try_catch(isolate()); | 141 TryCatch try_catch(isolate()); |
114 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate()); | 142 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate()); |
115 i::HandleScope handle_scope(internal_isolate); | 143 i::HandleScope handle_scope(internal_isolate); |
116 i::ValueDeserializer deserializer( | 144 i::ValueDeserializer deserializer( |
117 internal_isolate, | 145 internal_isolate, |
118 i::Vector<const uint8_t>(&data[0], static_cast<int>(data.size()))); | 146 i::Vector<const uint8_t>(&data[0], static_cast<int>(data.size()))); |
119 Maybe<bool> header_result = deserializer.ReadHeader(); | 147 Maybe<bool> header_result = deserializer.ReadHeader(); |
120 if (header_result.IsNothing()) return; | 148 if (header_result.IsNothing()) return; |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 // If an exception is thrown by script, encoding must fail and the exception | 648 // If an exception is thrown by script, encoding must fail and the exception |
621 // must be thrown. | 649 // must be thrown. |
622 InvalidEncodeTest("({ get a() { throw new Error('sentinel'); } })", | 650 InvalidEncodeTest("({ get a() { throw new Error('sentinel'); } })", |
623 [](Local<Message> message) { | 651 [](Local<Message> message) { |
624 ASSERT_FALSE(message.IsEmpty()); | 652 ASSERT_FALSE(message.IsEmpty()); |
625 EXPECT_NE(std::string::npos, | 653 EXPECT_NE(std::string::npos, |
626 Utf8Value(message->Get()).find("sentinel")); | 654 Utf8Value(message->Get()).find("sentinel")); |
627 }); | 655 }); |
628 } | 656 } |
629 | 657 |
| 658 TEST_F(ValueSerializerTest, DecodeDictionaryObjectVersion0) { |
| 659 // Empty object. |
| 660 DecodeTestForVersion0( |
| 661 {0x7b, 0x00}, |
| 662 [this](Local<Value> value) { |
| 663 ASSERT_TRUE(value->IsObject()); |
| 664 EXPECT_TRUE(EvaluateScriptForResultBool( |
| 665 "Object.getPrototypeOf(result) === Object.prototype")); |
| 666 EXPECT_TRUE(EvaluateScriptForResultBool( |
| 667 "Object.getOwnPropertyNames(result).length === 0")); |
| 668 }); |
| 669 // String key. |
| 670 DecodeTestForVersion0( |
| 671 {0x53, 0x01, 0x61, 0x49, 0x54, 0x7b, 0x01, 0x00}, |
| 672 [this](Local<Value> value) { |
| 673 ASSERT_TRUE(value->IsObject()); |
| 674 EXPECT_TRUE(EvaluateScriptForResultBool( |
| 675 "Object.getPrototypeOf(result) === Object.prototype")); |
| 676 EXPECT_TRUE(EvaluateScriptForResultBool("result.hasOwnProperty('a')")); |
| 677 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === 42")); |
| 678 EXPECT_TRUE(EvaluateScriptForResultBool( |
| 679 "Object.getOwnPropertyNames(result).length === 1")); |
| 680 }); |
| 681 // Integer key (treated as a string, but may be encoded differently). |
| 682 DecodeTestForVersion0( |
| 683 {0x49, 0x54, 0x53, 0x01, 0x61, 0x7b, 0x01, 0x00}, |
| 684 [this](Local<Value> value) { |
| 685 ASSERT_TRUE(value->IsObject()); |
| 686 EXPECT_TRUE(EvaluateScriptForResultBool("result.hasOwnProperty('42')")); |
| 687 EXPECT_TRUE(EvaluateScriptForResultBool("result[42] === 'a'")); |
| 688 EXPECT_TRUE(EvaluateScriptForResultBool( |
| 689 "Object.getOwnPropertyNames(result).length === 1")); |
| 690 }); |
| 691 // Key order must be preserved. |
| 692 DecodeTestForVersion0( |
| 693 {0x53, 0x01, 0x78, 0x49, 0x02, 0x53, 0x01, 0x79, 0x49, 0x04, 0x53, 0x01, |
| 694 0x61, 0x49, 0x06, 0x7b, 0x03, 0x00}, |
| 695 [this](Local<Value> value) { |
| 696 EXPECT_TRUE(EvaluateScriptForResultBool( |
| 697 "Object.getOwnPropertyNames(result).toString() === 'x,y,a'")); |
| 698 }); |
| 699 // A property and an element. |
| 700 DecodeTestForVersion0( |
| 701 {0x49, 0x54, 0x53, 0x01, 0x61, 0x53, 0x01, 0x61, 0x49, 0x54, 0x7b, 0x02}, |
| 702 [this](Local<Value> value) { |
| 703 EXPECT_TRUE(EvaluateScriptForResultBool( |
| 704 "Object.getOwnPropertyNames(result).toString() === '42,a'")); |
| 705 EXPECT_TRUE(EvaluateScriptForResultBool("result[42] === 'a'")); |
| 706 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === 42")); |
| 707 }); |
| 708 } |
| 709 |
630 } // namespace | 710 } // namespace |
631 } // namespace v8 | 711 } // namespace v8 |
OLD | NEW |