OSDN Git Service

Merge "Fix potential OOB write in btm_read_remote_ext_features_complete" into oc-dev
[android-x86/system-bt.git] / stack / include / advertise_data_parser.h
1 /******************************************************************************
2  *
3  *  Copyright (C) 2017 The Android Open Source Project
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 #pragma once
20
21 #include <vector>
22
23 class AdvertiseDataParser {
24  public:
25   /**
26    * Return true if this |ad| represent properly formatted advertising data.
27    */
28   static bool IsValid(const std::vector<uint8_t>& ad) {
29     size_t position = 0;
30
31     size_t ad_len = ad.size();
32     while (position != ad_len) {
33       uint8_t len = ad[position];
34
35       // A field length of 0 would be invalid as it should at least contain the
36       // EIR field type.
37       if (len == 0) return false;
38
39       // If the length of the current field would exceed the total data length,
40       // then the data is badly formatted.
41       if (position + len >= ad_len) {
42         return false;
43       }
44
45       position += len + 1;
46     }
47
48     return true;
49   }
50
51   /**
52    * This function returns a pointer inside the |ad| array of length |ad_len|
53    * where a field of |type| is located, together with its length in |p_length|
54    */
55   static const uint8_t* GetFieldByType(const uint8_t* ad, size_t ad_len,
56                                        uint8_t type, uint8_t* p_length) {
57     size_t position = 0;
58
59     while (position != ad_len) {
60       uint8_t len = ad[position];
61
62       if (len == 0) break;
63       if (position + len >= ad_len) break;
64
65       uint8_t adv_type = ad[position + 1];
66
67       if (adv_type == type) {
68         /* length doesn't include itself */
69         *p_length = len - 1; /* minus the length of type */
70         return ad + position + 2;
71       }
72
73       position += len + 1; /* skip the length of data */
74     }
75
76     *p_length = 0;
77     return NULL;
78   }
79
80   /**
81    * This function returns a pointer inside the |adv| where a field of |type| is
82    * located, together with it' length in |p_length|
83    */
84   static const uint8_t* GetFieldByType(std::vector<uint8_t> const& ad,
85                                        uint8_t type, uint8_t* p_length) {
86     return GetFieldByType(ad.data(), ad.size(), type, p_length);
87   }
88 };