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