• 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 <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