1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif
#include "build/build_config.h"
#include "ipc/ipc_message_protobuf_utils.h"
#include <initializer_list>
#include "ipc/test_proto.pb.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace IPC {
template <>
struct ParamTraits<ipc_message_utils_test::TestMessage1> {
typedef ipc_message_utils_test::TestMessage1 param_type;
static void Write(base::Pickle* m, const param_type& p) {
WriteParam(m, p.number());
}
static bool Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
int number;
if (!iter->ReadInt(&number))
return false;
r->set_number(number);
return true;
}
};
template <>
struct ParamTraits<ipc_message_utils_test::TestMessage2> {
typedef ipc_message_utils_test::TestMessage2 param_type;
static void Write(base::Pickle* m, const param_type& p) {
WriteParam(m, p.numbers());
WriteParam(m, p.strings());
WriteParam(m, p.messages());
}
static bool Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
return ReadParam(m, iter, r->mutable_numbers()) &&
ReadParam(m, iter, r->mutable_strings()) &&
ReadParam(m, iter, r->mutable_messages());
}
};
namespace {
template <class P1, class P2>
void AssertEqual(const P1& left, const P2& right) {
ASSERT_EQ(left, right);
}
template<>
void AssertEqual(const int& left,
const ipc_message_utils_test::TestMessage1& right) {
ASSERT_EQ(left, right.number());
}
template <template<class> class RepeatedFieldLike, class P1, class P2>
void AssertRepeatedFieldEquals(std::initializer_list<P1> expected,
const RepeatedFieldLike<P2>& fields) {
ASSERT_EQ(static_cast<int>(expected.size()), fields.size());
auto it = expected.begin();
int i = 0;
for (; it != expected.end(); it++, i++) {
AssertEqual(*it, fields.Get(i));
}
}
TEST(IPCMessageRepeatedFieldUtilsTest, RepeatedFieldShouldBeSerialized) {
ipc_message_utils_test::TestMessage2 message;
message.add_numbers(1);
message.add_numbers(100);
message.add_strings("abc");
message.add_strings("def");
message.add_messages()->set_number(1000);
message.add_messages()->set_number(10000);
base::Pickle pickle;
IPC::WriteParam(&pickle, message);
base::PickleIterator iter(pickle);
ipc_message_utils_test::TestMessage2 output;
ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
AssertRepeatedFieldEquals({1, 100}, output.numbers());
AssertRepeatedFieldEquals({"abc", "def"}, output.strings());
AssertRepeatedFieldEquals({1000, 10000}, output.messages());
}
TEST(IPCMessageRepeatedFieldUtilsTest,
PartialEmptyRepeatedFieldShouldBeSerialized) {
ipc_message_utils_test::TestMessage2 message;
message.add_numbers(1);
message.add_numbers(100);
message.add_messages()->set_number(1000);
message.add_messages()->set_number(10000);
base::Pickle pickle;
IPC::WriteParam(&pickle, message);
base::PickleIterator iter(pickle);
ipc_message_utils_test::TestMessage2 output;
ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
AssertRepeatedFieldEquals({1, 100}, output.numbers());
ASSERT_EQ(0, output.strings_size());
AssertRepeatedFieldEquals({1000, 10000}, output.messages());
}
TEST(IPCMessageRepeatedFieldUtilsTest, EmptyRepeatedFieldShouldBeSerialized) {
ipc_message_utils_test::TestMessage2 message;
base::Pickle pickle;
IPC::WriteParam(&pickle, message);
base::PickleIterator iter(pickle);
ipc_message_utils_test::TestMessage2 output;
ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
ASSERT_EQ(0, output.numbers_size());
ASSERT_EQ(0, output.strings_size());
ASSERT_EQ(0, output.messages_size());
}
TEST(IPCMessageRepeatedFieldUtilsTest,
InvalidPickleShouldNotCrashRepeatedFieldDeserialization) {
base::Pickle pickle;
IPC::WriteParam(&pickle, INT_MAX);
IPC::WriteParam(&pickle, 0);
IPC::WriteParam(&pickle, INT_MAX);
IPC::WriteParam(&pickle, std::string());
IPC::WriteParam(&pickle, 0);
base::PickleIterator iter(pickle);
ipc_message_utils_test::TestMessage2 output;
ASSERT_FALSE(IPC::ReadParam(&pickle, &iter, &output));
}
// This test needs ~20 seconds in Debug mode, or ~4 seconds in Release mode.
// See http://crbug.com/741866 for details.
TEST(IPCMessageRepeatedFieldUtilsTest,
DISABLED_InvalidPickleShouldNotCrashRepeatedFieldDeserialization2) {
base::Pickle pickle;
IPC::WriteParam(&pickle, 256 * 1024 * 1024);
IPC::WriteParam(&pickle, 0);
IPC::WriteParam(&pickle, INT_MAX);
IPC::WriteParam(&pickle, std::string());
IPC::WriteParam(&pickle, 0);
base::PickleIterator iter(pickle);
ipc_message_utils_test::TestMessage2 output;
ASSERT_FALSE(IPC::ReadParam(&pickle, &iter, &output));
}
} // namespace
} // namespace IPC
|