• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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