1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/public/common/messaging/string_message_codec.h"
6 
7 #include "base/strings/utf_string_conversions.h"
8 #include "base/test/task_environment.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "v8/include/v8.h"
11 
12 namespace blink {
13 namespace {
14 
DecodeWithV8(const std::vector<uint8_t> & encoded)15 base::string16 DecodeWithV8(const std::vector<uint8_t>& encoded) {
16   base::test::TaskEnvironment task_environment;
17   base::string16 result;
18 
19   v8::Isolate::CreateParams params;
20   params.array_buffer_allocator =
21       v8::ArrayBuffer::Allocator::NewDefaultAllocator();
22   v8::Isolate* isolate = v8::Isolate::New(params);
23   {
24     v8::HandleScope scope(isolate);
25     v8::TryCatch try_catch(isolate);
26 
27     v8::Local<v8::Context> context = v8::Context::New(isolate);
28 
29     v8::ValueDeserializer deserializer(isolate, encoded.data(), encoded.size());
30     deserializer.SetSupportsLegacyWireFormat(true);
31 
32     EXPECT_TRUE(deserializer.ReadHeader(context).ToChecked());
33 
34     v8::Local<v8::Value> value =
35         deserializer.ReadValue(context).ToLocalChecked();
36     v8::Local<v8::String> str = value->ToString(context).ToLocalChecked();
37 
38     result.resize(str->Length());
39     str->Write(isolate, reinterpret_cast<uint16_t*>(&result[0]), 0,
40                result.size());
41   }
42   isolate->Dispose();
43   delete params.array_buffer_allocator;
44 
45   return result;
46 }
47 
EncodeWithV8(const base::string16 & message)48 std::vector<uint8_t> EncodeWithV8(const base::string16& message) {
49   base::test::TaskEnvironment task_environment;
50   std::vector<uint8_t> result;
51 
52   v8::Isolate::CreateParams params;
53   params.array_buffer_allocator =
54       v8::ArrayBuffer::Allocator::NewDefaultAllocator();
55   v8::Isolate* isolate = v8::Isolate::New(params);
56   {
57     v8::HandleScope scope(isolate);
58     v8::TryCatch try_catch(isolate);
59 
60     v8::Local<v8::Context> context = v8::Context::New(isolate);
61 
62     v8::Local<v8::String> message_as_value =
63         v8::String::NewFromTwoByte(
64             isolate, reinterpret_cast<const uint16_t*>(message.data()),
65             v8::NewStringType::kNormal, message.size())
66             .ToLocalChecked();
67 
68     v8::ValueSerializer serializer(isolate);
69     serializer.WriteHeader();
70     EXPECT_TRUE(serializer.WriteValue(context, message_as_value).ToChecked());
71 
72     std::pair<uint8_t*, size_t> buffer = serializer.Release();
73     result = std::vector<uint8_t>(buffer.first, buffer.first + buffer.second);
74     free(buffer.first);
75   }
76   isolate->Dispose();
77   delete params.array_buffer_allocator;
78 
79   return result;
80 }
81 
TEST(StringMessageCodecTest,SelfTest_ASCII)82 TEST(StringMessageCodecTest, SelfTest_ASCII) {
83   base::string16 message = base::ASCIIToUTF16("hello");
84   base::string16 decoded;
85   EXPECT_TRUE(DecodeStringMessage(EncodeStringMessage(message), &decoded));
86   EXPECT_EQ(message, decoded);
87 }
88 
TEST(StringMessageCodecTest,SelfTest_NonASCII)89 TEST(StringMessageCodecTest, SelfTest_NonASCII) {
90   base::string16 message = base::WideToUTF16(L"hello \u263A");
91   base::string16 decoded;
92   EXPECT_TRUE(DecodeStringMessage(EncodeStringMessage(message), &decoded));
93   EXPECT_EQ(message, decoded);
94 }
95 
TEST(StringMessageCodecTest,SelfTest_NonASCIILongEnoughToForcePadding)96 TEST(StringMessageCodecTest, SelfTest_NonASCIILongEnoughToForcePadding) {
97   base::string16 message(200, 0x263A);
98   base::string16 decoded;
99   EXPECT_TRUE(DecodeStringMessage(EncodeStringMessage(message), &decoded));
100   EXPECT_EQ(message, decoded);
101 }
102 
TEST(StringMessageCodecTest,SelfToV8Test_ASCII)103 TEST(StringMessageCodecTest, SelfToV8Test_ASCII) {
104   base::string16 message = base::ASCIIToUTF16("hello");
105   EXPECT_EQ(message, DecodeWithV8(EncodeStringMessage(message)));
106 }
107 
TEST(StringMessageCodecTest,SelfToV8Test_NonASCII)108 TEST(StringMessageCodecTest, SelfToV8Test_NonASCII) {
109   base::string16 message = base::WideToUTF16(L"hello \u263A");
110   EXPECT_EQ(message, DecodeWithV8(EncodeStringMessage(message)));
111 }
112 
TEST(StringMessageCodecTest,SelfToV8Test_NonASCIILongEnoughToForcePadding)113 TEST(StringMessageCodecTest, SelfToV8Test_NonASCIILongEnoughToForcePadding) {
114   base::string16 message(200, 0x263A);
115   EXPECT_EQ(message, DecodeWithV8(EncodeStringMessage(message)));
116 }
117 
TEST(StringMessageCodecTest,V8ToSelfTest_ASCII)118 TEST(StringMessageCodecTest, V8ToSelfTest_ASCII) {
119   base::string16 message = base::ASCIIToUTF16("hello");
120   base::string16 decoded;
121   EXPECT_TRUE(DecodeStringMessage(EncodeWithV8(message), &decoded));
122   EXPECT_EQ(message, decoded);
123 }
124 
TEST(StringMessageCodecTest,V8ToSelfTest_NonASCII)125 TEST(StringMessageCodecTest, V8ToSelfTest_NonASCII) {
126   base::string16 message = base::WideToUTF16(L"hello \u263A");
127   base::string16 decoded;
128   EXPECT_TRUE(DecodeStringMessage(EncodeWithV8(message), &decoded));
129   EXPECT_EQ(message, decoded);
130 }
131 
TEST(StringMessageCodecTest,V8ToSelfTest_NonASCIILongEnoughToForcePadding)132 TEST(StringMessageCodecTest, V8ToSelfTest_NonASCIILongEnoughToForcePadding) {
133   base::string16 message(200, 0x263A);
134   base::string16 decoded;
135   EXPECT_TRUE(DecodeStringMessage(EncodeWithV8(message), &decoded));
136   EXPECT_EQ(message, decoded);
137 }
138 
139 }  // namespace
140 }  // namespace blink
141