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