1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <base/logging.h>
18 #include <gtest/gtest.h>
19
20 #include "common/data_element_reader.h"
21
22 namespace bluetooth {
23 namespace sdp {
24
25 using namespace testing;
26 using DataElement = DataElementReader::DataElement;
27
28 // A helper class to help work with the Data Element classes.
29 class ReaderPacket : public ::bluetooth::Packet {
30 public:
31 using Packet::Packet;
32
Make(std::vector<uint8_t> payload)33 static std::shared_ptr<ReaderPacket> Make(std::vector<uint8_t> payload) {
34 auto pkt = std::shared_ptr<ReaderPacket>(new ReaderPacket());
35 pkt->packet_start_index_ = 0;
36 pkt->packet_end_index_ = payload.size();
37 pkt->data_ = std::make_shared<std::vector<uint8_t>>(std::move(payload));
38 return pkt;
39 }
40
ToString() const41 std::string ToString() const override { return ""; }
IsValid() const42 bool IsValid() const override { return true; }
GetPayloadIndecies() const43 std::pair<size_t, size_t> GetPayloadIndecies() const override {
44 return std::pair<size_t, size_t>(packet_start_index_, packet_end_index_);
45 }
46 };
47
48 bool operator!=(DataElementReader a, DataElementReader b);
49
50 // A helper function to help compare DataElementReader objects.
operator ==(DataElementReader a,DataElementReader b)51 bool operator==(DataElementReader a, DataElementReader b) {
52 while (true) {
53 DataElement a_elem = a.ReadNext();
54 DataElement b_elem = b.ReadNext();
55
56 if (a_elem != b_elem) return false;
57
58 // If we get here that means both a and b have reached the end.
59 if (a_elem == DataElement(std::monostate())) break;
60 }
61
62 return true;
63 }
64
operator !=(DataElementReader a,DataElementReader b)65 bool operator!=(DataElementReader a, DataElementReader b) { return !(a == b); }
66
67 // A helper function to convert a type and a size to a descriptor byte.
Desc(DataElementType t,DataElementSize s)68 constexpr uint8_t Desc(DataElementType t, DataElementSize s) {
69 return static_cast<uint8_t>(t) << 3 | static_cast<uint8_t>(s);
70 }
71
72 // Helper that can create a Data Element reader from a vector.
CreateReader(std::vector<uint8_t> payload)73 DataElementReader CreateReader(std::vector<uint8_t> payload) {
74 auto packet = ReaderPacket::Make(std::move(payload));
75 return DataElementReader(packet->begin(), packet->end());
76 }
77
78 // Test all the valid cases of reading the next Data Element.
79 using ValidTestParam = std::tuple<std::vector<uint8_t>, DataElement>;
80 class ValidReadTest : public TestWithParam<ValidTestParam> {};
81
82 std::vector<ValidTestParam> valid_values = {
83 // Boolean Tests
84 ValidTestParam{
85 {Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01},
86 true,
87 },
88 ValidTestParam{
89 {Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00},
90 false,
91 },
92
93 // Signed Integer Tests
94 ValidTestParam{
95 {Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE1), 0xFF},
96 static_cast<int8_t>(-1)},
97 ValidTestParam{
98 {Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE2), 0xFF, 0xFF},
99 static_cast<int16_t>(-1)},
100 ValidTestParam{{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE4),
101 0xFF, 0xFF, 0xFF, 0xFF},
102 static_cast<int32_t>(-1)},
103 ValidTestParam{{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE8),
104 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
105 static_cast<int64_t>(-1)},
106 ValidTestParam{{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE16),
107 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
109 std::array<uint8_t, 16>{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
110 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
111 0xFF, 0xFF, 0xFF, 0xFF}},
112
113 // Unsigned Integer Tests
114 ValidTestParam{
115 {Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE1), 0x01},
116 static_cast<uint8_t>(1)},
117 ValidTestParam{{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE2),
118 0x00, 0x01},
119 static_cast<uint16_t>(1)},
120 ValidTestParam{{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE4),
121 0x00, 0x00, 0x00, 0x01},
122 static_cast<uint32_t>(1)},
123 ValidTestParam{{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE8),
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
125 static_cast<uint64_t>(1)},
126 ValidTestParam{
127 {Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE16), 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x01},
130 std::array<uint8_t, 16>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x01}},
133
134 // UUID Tests
135 ValidTestParam{
136 {Desc(DataElementType::UUID, DataElementSize::BYTE2), 0x01, 0x02},
137 Uuid::From16Bit(0x0102)},
138 ValidTestParam{{Desc(DataElementType::UUID, DataElementSize::BYTE4), 0x01,
139 0x02, 0x03, 0x04},
140 Uuid::From32Bit(0x01020304)},
141 ValidTestParam{
142 {Desc(DataElementType::UUID, DataElementSize::BYTE16), 0x00, 0x01, 0x02,
143 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
144 0x0F},
145 Uuid::From128BitBE({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
146 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F})},
147
148 // String Tests
149 ValidTestParam{
150 {Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_8BIT), 0x05,
151 'T', 'e', 's', 't', '1'},
152 std::string("Test1")},
153 ValidTestParam{
154 {Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_16BIT), 0x00,
155 0x05, 'T', 'e', 's', 't', '2'},
156 std::string("Test2")},
157 ValidTestParam{
158 {Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_32BIT), 0x00,
159 0x00, 0x00, 0x05, 'T', 'e', 's', 't', '3'},
160 std::string("Test3")},
161
162 // Nested Data Element List Tests
163 ValidTestParam{
164 {Desc(DataElementType::DATA_ELEMENT_SEQUENCE,
165 DataElementSize::ADDITIONAL_8BIT),
166 0x04, Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
167 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00},
168 CreateReader(
169 {Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
170 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00})},
171 ValidTestParam{
172 {Desc(DataElementType::DATA_ELEMENT_SEQUENCE,
173 DataElementSize::ADDITIONAL_16BIT),
174 0x00, 0x04, Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1),
175 0x01, Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00},
176 CreateReader(
177 {Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
178 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00})},
179 ValidTestParam{
180 {Desc(DataElementType::DATA_ELEMENT_SEQUENCE,
181 DataElementSize::ADDITIONAL_32BIT),
182 0x00, 0x00, 0x00, 0x04,
183 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
184 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00},
185 CreateReader(
186 {Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
187 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00})},
188 };
189
190 INSTANTIATE_TEST_CASE_P(ReadNext, ValidReadTest, ValuesIn(valid_values));
TEST_P(ValidReadTest,Test)191 TEST_P(ValidReadTest, Test) {
192 auto packet = ReaderPacket::Make(std::get<0>(GetParam()));
193 auto value = std::get<1>(GetParam());
194
195 DataElementReader reader(packet->begin(), packet->end());
196 auto read_value = reader.ReadNext();
197
198 ASSERT_EQ(value, read_value);
199
200 // Test that there is no additional data to read.
201 ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
202 }
203
204 // Test that a nested reader is correctly bounded and can't read past its
205 // defined end.
TEST(ReadNext,BoundedSubreaderTest)206 TEST(ReadNext, BoundedSubreaderTest) {
207 std::vector<uint8_t> payload = {
208 // Subsequence descriptor byte.
209 Desc(DataElementType::DATA_ELEMENT_SEQUENCE,
210 DataElementSize::ADDITIONAL_8BIT),
211 // Subsequence length.
212 0x04,
213 // Subsequence that contains two booleans with values true and false.
214 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
215 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00,
216 // Additional int16 at the end of the original sequence.
217 Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE2), 0x01, 0x23};
218
219 auto packet = ReaderPacket::Make(payload);
220 DataElementReader reader(packet->begin(), packet->end());
221
222 // The first thing read should be the subsequence.
223 auto data_element = reader.ReadNext();
224 ASSERT_TRUE(std::holds_alternative<DataElementReader>(data_element));
225
226 // Check that the subsequence matches the premade sequence.
227 auto subreader = std::get<DataElementReader>(data_element);
228 data_element = subreader.ReadNext();
229 ASSERT_TRUE(std::holds_alternative<bool>(data_element));
230 ASSERT_TRUE(std::get<bool>(data_element));
231 data_element = subreader.ReadNext();
232 ASSERT_TRUE(std::holds_alternative<bool>(data_element));
233 ASSERT_FALSE(std::get<bool>(data_element));
234
235 // Check that there is no additional data to be read from the subreader.
236 ASSERT_EQ(subreader.ReadNext(), DataElement(std::monostate()));
237
238 // Check that we can still read the int16 from the original reader.
239 data_element = reader.ReadNext();
240 ASSERT_TRUE(std::holds_alternative<int16_t>(data_element));
241 auto int16_value = std::get<int16_t>(data_element);
242 ASSERT_EQ(int16_value, 0x0123);
243
244 // Check that there is no additional data to be read from the base reader.
245 ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
246 }
247
248 // Test that trying to read an empty packet fails.
TEST(ReadNext,NoDataTest)249 TEST(ReadNext, NoDataTest) {
250 auto packet = ReaderPacket::Make({});
251 DataElementReader reader(packet->begin(), packet->end());
252
253 ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
254 }
255
256 // Test that using a reserved value for type fails.
TEST(ReadNext,InvalidTypeTest)257 TEST(ReadNext, InvalidTypeTest) {
258 auto packet = ReaderPacket::Make({0xFF});
259 DataElementReader reader(packet->begin(), packet->end());
260
261 ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
262 }
263
264 // Test all invalid parses due to incorrect lengths or invalid sizes. All tests
265 // should return std::monostate.
266 using InvalidTestParam = std::vector<uint8_t>;
267 class InvalidReadTest : public TestWithParam<InvalidTestParam> {};
268
269 std::vector<InvalidTestParam> invalid_values = {
270 // Boolean Tests:
271 // Invalid size field.
272 InvalidTestParam{
273 Desc(DataElementType::BOOLEAN, DataElementSize::BYTE2),
274 },
275 // Insufficient data.
276 InvalidTestParam{Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1)},
277
278 // Signed Integer Tests:
279 // Invalid size field.
280 InvalidTestParam{
281 Desc(DataElementType::SIGNED_INT, DataElementSize::ADDITIONAL_8BIT)},
282 // 1 byte insufficient data.
283 InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE1)},
284 // 2 byte insufficient data.
285 InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE2),
286 0x00},
287 // 4 byte insufficient data.
288 InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE4),
289 0x00, 0x00, 0x00},
290 // 8 Byte insufficient data.
291 InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE8),
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
293 // 16 Byte insufficient data.
294 InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE16),
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00},
297
298 // Unsigned Integer Tests:
299 // Invalid size field.
300 InvalidTestParam{
301 Desc(DataElementType::UNSIGNED_INT, DataElementSize::ADDITIONAL_8BIT)},
302 // 1 byte insufficient data.
303 InvalidTestParam{
304 Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE1)},
305 // 2 byte insufficient data.
306 InvalidTestParam{
307 Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE2), 0x00},
308 // 4 byte insufficient data.
309 InvalidTestParam{
310 Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE4), 0x00, 0x00,
311 0x00},
312 // 8 Byte insufficient data.
313 InvalidTestParam{
314 Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE8), 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00},
316 // 16 Byte insufficient data.
317 InvalidTestParam{
318 Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE16), 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
320
321 // UUID Tests:
322 // Invalid size field.
323 InvalidTestParam{
324 Desc(DataElementType::UUID, DataElementSize::ADDITIONAL_8BIT)},
325 // 2 byte insufficient data.
326 InvalidTestParam{Desc(DataElementType::UUID, DataElementSize::BYTE2), 0x00},
327 // 4 byte insufficient data.
328 InvalidTestParam{Desc(DataElementType::UUID, DataElementSize::BYTE4), 0x00,
329 0x00, 0x00},
330 // 16 Byte insufficient data.
331 InvalidTestParam{Desc(DataElementType::UUID, DataElementSize::BYTE16), 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00},
334
335 // String Tests:
336 // Invalid size field.
337 InvalidTestParam{Desc(DataElementType::STRING, DataElementSize::BYTE1)},
338 // Insufficient data for additional 8 bits len.
339 InvalidTestParam{
340 Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_8BIT)},
341 // Insufficient data for additional 16 bits len.
342 InvalidTestParam{
343 Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_16BIT),
344 0x00,
345 },
346 // Insufficient data for additional 32 bit len.
347 InvalidTestParam{
348 Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_32BIT),
349 0x00,
350 0x00,
351 0x00,
352 },
353 // Insufficient data for reported length.
354 InvalidTestParam{
355 Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_8BIT), 0x04,
356 '1', '2', '3'},
357
358 // Nested Data Element List Tests:
359 // Invalid size field.
360 InvalidTestParam{
361 Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::BYTE1)},
362 // Insufficient data for additional 8 bits len.
363 InvalidTestParam{Desc(DataElementType::DATA_ELEMENT_SEQUENCE,
364 DataElementSize::ADDITIONAL_8BIT)},
365 // Insufficient data for additional 16 bits len.
366 InvalidTestParam{
367 Desc(DataElementType::DATA_ELEMENT_SEQUENCE,
368 DataElementSize::ADDITIONAL_16BIT),
369 0x00,
370 },
371 // Insufficient data for additional 32 bit len.
372 InvalidTestParam{
373 Desc(DataElementType::DATA_ELEMENT_SEQUENCE,
374 DataElementSize::ADDITIONAL_32BIT),
375 0x00,
376 0x00,
377 0x00,
378 },
379 // Insufficient data for reported length.
380 InvalidTestParam{Desc(DataElementType::DATA_ELEMENT_SEQUENCE,
381 DataElementSize::ADDITIONAL_8BIT),
382 0x04, 0x00, 0x00, 0x00},
383
384 // Unhandled Data Element Types Tests:
385 // NOTE: These tests should go away as we begin to handle the types.
386 // Nil Type.
387 InvalidTestParam{Desc(DataElementType::NIL, DataElementSize::BYTE1)},
388 // Data Element Alternative List Type.
389 InvalidTestParam{Desc(DataElementType::DATA_ELEMENT_ALTERNATIVE,
390 DataElementSize::ADDITIONAL_8BIT),
391 0x00},
392 // URL Type.
393 InvalidTestParam{
394 Desc(DataElementType::URL, DataElementSize::ADDITIONAL_8BIT), 0x00}};
395
396 INSTANTIATE_TEST_CASE_P(ReadNext, InvalidReadTest, ValuesIn(invalid_values));
TEST_P(InvalidReadTest,Test)397 TEST_P(InvalidReadTest, Test) {
398 auto packet = ReaderPacket::Make(GetParam());
399 DataElementReader reader(packet->begin(), packet->end());
400
401 ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
402 }
403
404 // Test that trying to read from a reader with start > end crashes.
TEST(DataElementReader,BadBoundsDeathTest)405 TEST(DataElementReader, BadBoundsDeathTest) {
406 auto packet = ReaderPacket::Make({0x00, 0x00, 0x00, 0x00});
407 DataElementReader reader(packet->end(), packet->begin());
408 ASSERT_DEATH(reader.ReadNext(), "Beginning of buffer is past end of buffer.");
409 }
410
411 } // namespace sdp
412 } // namespace bluetooth
413