• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "common/hap_byte_buffer.h"
17 
18 #include "common/hap_verify_log.h"
19 #include "securec.h"
20 
21 namespace OHOS {
22 namespace Security {
23 namespace Verify {
24 const int HapByteBuffer::MAX_PRINT_LENGTH = 200;
25 const int HapByteBuffer::HEX_PRINT_LENGTH = 3;
26 
HapByteBuffer()27 HapByteBuffer::HapByteBuffer() : buffer(nullptr), position(0), limit(0), capacity(0)
28 {
29 }
30 
HapByteBuffer(int bufferCapacity)31 HapByteBuffer::HapByteBuffer(int bufferCapacity) : buffer(nullptr), position(0), limit(0), capacity(0)
32 {
33     Init(bufferCapacity);
34 }
35 
HapByteBuffer(const HapByteBuffer & other)36 HapByteBuffer::HapByteBuffer(const HapByteBuffer& other) : buffer(nullptr), position(0), limit(0), capacity(0)
37 {
38     Init(other.GetCapacity());
39     if (buffer != nullptr && capacity > 0) {
40         if (memcpy_s(buffer.get(), capacity, other.GetBufferPtr(), other.GetCapacity()) != EOK) {
41             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
42             return;
43         }
44         position = other.GetPosition();
45         limit = other.GetLimit();
46     }
47 }
48 
~HapByteBuffer()49 HapByteBuffer::~HapByteBuffer()
50 {
51     buffer.reset(nullptr);
52 }
53 
Init(int bufferCapacity)54 void HapByteBuffer::Init(int bufferCapacity)
55 {
56     if (bufferCapacity > 0) {
57         buffer = std::make_unique<char[]>(bufferCapacity);
58         if (buffer != nullptr) {
59             limit = bufferCapacity;
60             capacity = bufferCapacity;
61         }
62     } else {
63         HAPVERIFY_LOG_INFO(LABEL, "bufferCapacity %{public}d is too small", bufferCapacity);
64     }
65 }
66 
operator =(const HapByteBuffer & other)67 HapByteBuffer& HapByteBuffer::operator=(const HapByteBuffer& other)
68 {
69     if (&other == this) {
70         return *this;
71     }
72 
73     buffer.reset(nullptr);
74     Init(other.GetCapacity());
75     if (buffer != nullptr && other.GetBufferPtr() != nullptr && capacity > 0) {
76         if (memcpy_s(buffer.get(), capacity, other.GetBufferPtr(), other.GetCapacity()) != EOK) {
77             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
78             return *this;
79         }
80         position = other.GetPosition();
81         limit = other.GetLimit();
82     }
83     return *this;
84 }
85 
CheckInputForGettingData(int index,int dataLen)86 bool HapByteBuffer::CheckInputForGettingData(int index, int dataLen)
87 {
88     if (buffer == nullptr) {
89         HAPVERIFY_LOG_ERROR(LABEL, "buffer is nullptr");
90         return false;
91     }
92     if (index < 0) {
93         HAPVERIFY_LOG_ERROR(LABEL, "invalid index %{public}d", index);
94         return false;
95     }
96     long long getDataLast = static_cast<long long>(position) + static_cast<long long>(index) +
97         static_cast<long long>(dataLen);
98     if (getDataLast > static_cast<long long>(limit)) {
99         HAPVERIFY_LOG_ERROR(LABEL, "position %{public}d, index  %{public}d, limit %{public}d",
100             position, index, limit);
101         return false;
102     }
103     return true;
104 }
105 
GetInt64(long long & value)106 bool HapByteBuffer::GetInt64(long long& value)
107 {
108     if (!GetInt64(0, value)) {
109         HAPVERIFY_LOG_ERROR(LABEL, "GetInt64 failed");
110         return false;
111     }
112     position += sizeof(long long);
113     return true;
114 }
115 
GetInt64(int index,long long & value)116 bool HapByteBuffer::GetInt64(int index, long long& value)
117 {
118     if (!CheckInputForGettingData(index, sizeof(long long))) {
119         HAPVERIFY_LOG_ERROR(LABEL, "Failed to get Int64");
120         return false;
121     }
122 
123     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(long long)) != EOK) {
124         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
125         return false;
126     }
127     return true;
128 }
129 
GetCapacity() const130 int HapByteBuffer::GetCapacity() const
131 {
132     return capacity;
133 }
134 
GetBufferPtr() const135 const char* HapByteBuffer::GetBufferPtr() const
136 {
137     return buffer.get();
138 }
139 
GetInt32(int & value)140 bool HapByteBuffer::GetInt32(int& value)
141 {
142     if (!GetInt32(0, value)) {
143         HAPVERIFY_LOG_ERROR(LABEL, "GetInt32 failed");
144         return false;
145     }
146     position += sizeof(int);
147     return true;
148 }
149 
GetInt32(int index,int & value)150 bool HapByteBuffer::GetInt32(int index, int& value)
151 {
152     if (!CheckInputForGettingData(index, sizeof(int))) {
153         HAPVERIFY_LOG_ERROR(LABEL, "Failed to get Int32");
154         return false;
155     }
156 
157     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(int)) != EOK) {
158         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
159         return false;
160     }
161     return true;
162 }
163 
GetUInt32(int index,unsigned int & value)164 bool HapByteBuffer::GetUInt32(int index, unsigned int& value)
165 {
166     if (!CheckInputForGettingData(index, sizeof(unsigned int))) {
167         HAPVERIFY_LOG_ERROR(LABEL, "Failed to get UInt32");
168         return false;
169     }
170 
171     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(unsigned int)) != EOK) {
172         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
173         return false;
174     }
175     return true;
176 }
177 
GetUInt16(int index,unsigned short & value)178 bool HapByteBuffer::GetUInt16(int index, unsigned short& value)
179 {
180     if (!CheckInputForGettingData(index, sizeof(unsigned short))) {
181         HAPVERIFY_LOG_ERROR(LABEL, "Failed to get UInt16");
182         return false;
183     }
184 
185     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(unsigned short)) != EOK) {
186         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
187         return false;
188     }
189     return true;
190 }
191 
PutInt32(int offset,int value)192 void HapByteBuffer::PutInt32(int offset, int value)
193 {
194     if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int>(sizeof(value))) {
195         if (memcpy_s((buffer.get() + offset), (limit - offset), &value, sizeof(value)) != EOK) {
196             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
197         }
198     }
199 }
200 
PutByte(int offset,char value)201 void HapByteBuffer::PutByte(int offset, char value)
202 {
203     if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int>(sizeof(value))) {
204         if (memcpy_s((buffer.get() + offset), (limit - offset), (&value), sizeof(value)) != EOK) {
205             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
206         }
207     }
208 }
209 
PutData(int offset,const char data[],int len)210 void HapByteBuffer::PutData(int offset, const char data[], int len)
211 {
212     if (buffer != nullptr && data != nullptr && offset >= 0 && len > 0 && (limit - offset) >= len) {
213         if (memcpy_s((buffer.get() + offset), (limit - offset), data, len) != EOK) {
214             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
215         }
216     }
217 }
218 
SetPosition(int pos)219 void HapByteBuffer::SetPosition(int pos)
220 {
221     if (pos >= 0 && pos <= limit) {
222         position = pos;
223     }
224 }
225 
Slice()226 void HapByteBuffer::Slice()
227 {
228     if (position >= capacity || limit > capacity || position >= limit || buffer == nullptr) {
229         HAPVERIFY_LOG_ERROR(LABEL, "position %{public}d capacity %{public}d limit %{public}d error",
230             position, capacity, limit);
231         return;
232     }
233     int newCapacity = limit - position;
234     std::unique_ptr<char[]> newBuffer = std::make_unique<char[]>(newCapacity);
235     if (memcpy_s(newBuffer.get(), newCapacity, (buffer.get() + position), (limit - position)) != EOK) {
236         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
237         return;
238     }
239     buffer.reset(newBuffer.release());
240     position = 0;
241     capacity = newCapacity;
242     limit = capacity;
243 }
244 
GetPosition() const245 int HapByteBuffer::GetPosition() const
246 {
247     return position;
248 }
249 
GetLimit() const250 int HapByteBuffer::GetLimit() const
251 {
252     return limit;
253 }
254 
SetLimit(int lim)255 void HapByteBuffer::SetLimit(int lim)
256 {
257     if (lim <= capacity && lim >= position) {
258         limit = lim;
259     }
260 }
261 
Remaining() const262 int HapByteBuffer::Remaining() const
263 {
264     return limit - position;
265 }
266 
HasRemaining() const267 bool HapByteBuffer::HasRemaining() const
268 {
269     return position < limit;
270 }
271 
CopyPartialBuffer(const HapByteBuffer & other,int len)272 bool HapByteBuffer::CopyPartialBuffer(const HapByteBuffer& other, int len)
273 {
274     int readableDataLen = other.Remaining();
275     if (readableDataLen < len) {
276         HAPVERIFY_LOG_ERROR(LABEL, "readableDataLen %{public}d less than len %{public}d", readableDataLen, len);
277         return false;
278     }
279 
280     buffer.reset(nullptr);
281     buffer = std::make_unique<char[]>(len);
282     if (buffer != nullptr && other.GetBufferPtr() != nullptr) {
283         capacity = len;
284         limit = capacity;
285         if (memcpy_s(buffer.get(), capacity, (other.GetBufferPtr() + other.GetPosition()), len) != EOK) {
286             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
287             return false;
288         }
289     }
290     position = 0;
291     return true;
292 }
293 
Clear()294 void HapByteBuffer::Clear()
295 {
296     position = 0;
297     limit = capacity;
298 }
299 
IsEqual(const HapByteBuffer & other)300 bool HapByteBuffer::IsEqual(const HapByteBuffer& other)
301 {
302     if (&other == this) {
303         return true;
304     }
305     if (capacity != other.GetCapacity() || other.GetBufferPtr() == nullptr || buffer == nullptr) {
306         HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
307         return false;
308     }
309     const char* otherBuffer = other.GetBufferPtr();
310     for (int i = 0; i < capacity; i++) {
311         if (buffer[i] != otherBuffer[i]) {
312             HAPVERIFY_LOG_ERROR(LABEL, "diff value[%{public}d]: %{public}x %{public}x",
313                 i, buffer[i], otherBuffer[i]);
314             return false;
315         }
316     }
317     return true;
318 }
319 
IsEqual(const std::string & other)320 bool HapByteBuffer::IsEqual(const std::string& other)
321 {
322     if (capacity != static_cast<int>(other.size()) || buffer == nullptr) {
323         HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
324         return false;
325     }
326     for (int i = 0; i < capacity; i++) {
327         if (buffer[i] != other[i]) {
328             HAPVERIFY_LOG_ERROR(LABEL, "diff value[%{public}d]: %{public}x %{public}x",
329                 i, buffer[i], other[i]);
330             return false;
331         }
332     }
333     return true;
334 }
335 
SetCapacity(int cap)336 void HapByteBuffer::SetCapacity(int cap)
337 {
338     if (buffer != nullptr) {
339         buffer.reset(nullptr);
340         position = 0;
341         limit = 0;
342         capacity = 0;
343     }
344     Init(cap);
345 }
346 } // namespace Verify
347 } // namespace Security
348 } // namespace OHOS
349