• 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 int32_t HapByteBuffer::MAX_PRINT_LENGTH = 200;
25 const int32_t HapByteBuffer::HEX_PRINT_LENGTH = 3;
26 
HapByteBuffer()27 HapByteBuffer::HapByteBuffer() : buffer(nullptr), position(0), limit(0), capacity(0)
28 {
29 }
30 
HapByteBuffer(int32_t bufferCapacity)31 HapByteBuffer::HapByteBuffer(int32_t 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(int32_t bufferCapacity)54 void HapByteBuffer::Init(int32_t 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(int32_t index,int32_t dataLen)86 bool HapByteBuffer::CheckInputForGettingData(int32_t index, int32_t 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(int32_t index,long long & value)116 bool HapByteBuffer::GetInt64(int32_t 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 int32_t HapByteBuffer::GetCapacity() const
131 {
132     return capacity;
133 }
134 
GetBufferPtr() const135 const char* HapByteBuffer::GetBufferPtr() const
136 {
137     return buffer.get();
138 }
139 
GetInt32(int32_t & value)140 bool HapByteBuffer::GetInt32(int32_t& value)
141 {
142     if (!GetInt32(0, value)) {
143         HAPVERIFY_LOG_ERROR(LABEL, "GetInt32 failed");
144         return false;
145     }
146     position += sizeof(int32_t);
147     return true;
148 }
149 
GetInt32(int32_t index,int32_t & value)150 bool HapByteBuffer::GetInt32(int32_t index, int32_t& value)
151 {
152     if (!CheckInputForGettingData(index, sizeof(int32_t))) {
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(int32_t)) != EOK) {
158         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
159         return false;
160     }
161     return true;
162 }
163 
GetUInt32(int32_t index,uint32_t & value)164 bool HapByteBuffer::GetUInt32(int32_t index, uint32_t& value)
165 {
166     if (!CheckInputForGettingData(index, sizeof(uint32_t))) {
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(uint32_t)) != EOK) {
172         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
173         return false;
174     }
175     return true;
176 }
177 
GetUInt32(uint32_t & value)178 bool HapByteBuffer::GetUInt32(uint32_t& value)
179 {
180     if (!GetUInt32(0, value)) {
181         HAPVERIFY_LOG_ERROR(LABEL, "GetUInt32 failed");
182         return false;
183     }
184     position += sizeof(uint32_t);
185     return true;
186 }
187 
GetUInt16(int32_t index,uint16_t & value)188 bool HapByteBuffer::GetUInt16(int32_t index, uint16_t& value)
189 {
190     if (!CheckInputForGettingData(index, sizeof(uint16_t))) {
191         HAPVERIFY_LOG_ERROR(LABEL, "Failed to get UInt16");
192         return false;
193     }
194 
195     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(uint16_t)) != EOK) {
196         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
197         return false;
198     }
199     return true;
200 }
201 
PutInt32(int32_t offset,int32_t value)202 void HapByteBuffer::PutInt32(int32_t offset, int32_t value)
203 {
204     if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int32_t>(sizeof(value))) {
205         if (memcpy_s((buffer.get() + offset), (limit - offset), &value, sizeof(value)) != EOK) {
206             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
207         }
208     }
209 }
210 
PutByte(int32_t offset,char value)211 void HapByteBuffer::PutByte(int32_t offset, char value)
212 {
213     if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int32_t>(sizeof(value))) {
214         if (memcpy_s((buffer.get() + offset), (limit - offset), (&value), sizeof(value)) != EOK) {
215             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
216         }
217     }
218 }
219 
PutData(int32_t offset,const char data[],int32_t len)220 void HapByteBuffer::PutData(int32_t offset, const char data[], int32_t len)
221 {
222     if (buffer != nullptr && data != nullptr && offset >= 0 && len > 0 && (limit - offset) >= len) {
223         if (memcpy_s((buffer.get() + offset), (limit - offset), data, len) != EOK) {
224             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
225         }
226     }
227 }
228 
SetPosition(int32_t pos)229 void HapByteBuffer::SetPosition(int32_t pos)
230 {
231     if (pos >= 0 && pos <= limit) {
232         position = pos;
233     }
234 }
235 
Slice()236 void HapByteBuffer::Slice()
237 {
238     if (position >= capacity || limit > capacity || position >= limit || buffer == nullptr) {
239         HAPVERIFY_LOG_ERROR(LABEL, "position %{public}d capacity %{public}d limit %{public}d error",
240             position, capacity, limit);
241         return;
242     }
243     int32_t newCapacity = limit - position;
244     std::unique_ptr<char[]> newBuffer = std::make_unique<char[]>(newCapacity);
245     if (memcpy_s(newBuffer.get(), newCapacity, (buffer.get() + position), (limit - position)) != EOK) {
246         HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
247         return;
248     }
249     buffer.reset(newBuffer.release());
250     position = 0;
251     capacity = newCapacity;
252     limit = capacity;
253 }
254 
GetPosition() const255 int32_t HapByteBuffer::GetPosition() const
256 {
257     return position;
258 }
259 
GetLimit() const260 int32_t HapByteBuffer::GetLimit() const
261 {
262     return limit;
263 }
264 
SetLimit(int32_t lim)265 void HapByteBuffer::SetLimit(int32_t lim)
266 {
267     if (lim <= capacity && lim >= position) {
268         limit = lim;
269     }
270 }
271 
Remaining() const272 int32_t HapByteBuffer::Remaining() const
273 {
274     return limit - position;
275 }
276 
HasRemaining() const277 bool HapByteBuffer::HasRemaining() const
278 {
279     return position < limit;
280 }
281 
CopyPartialBuffer(const HapByteBuffer & other,int32_t len)282 bool HapByteBuffer::CopyPartialBuffer(const HapByteBuffer& other, int32_t len)
283 {
284     int32_t readableDataLen = other.Remaining();
285     if (readableDataLen < len) {
286         HAPVERIFY_LOG_ERROR(LABEL, "readableDataLen %{public}d less than len %{public}d", readableDataLen, len);
287         return false;
288     }
289 
290     buffer.reset(nullptr);
291     buffer = std::make_unique<char[]>(len);
292     if (buffer != nullptr && other.GetBufferPtr() != nullptr) {
293         capacity = len;
294         limit = capacity;
295         if (memcpy_s(buffer.get(), capacity, (other.GetBufferPtr() + other.GetPosition()), len) != EOK) {
296             HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
297             return false;
298         }
299     }
300     position = 0;
301     return true;
302 }
303 
Clear()304 void HapByteBuffer::Clear()
305 {
306     position = 0;
307     limit = capacity;
308 }
309 
IsEqual(const HapByteBuffer & other)310 bool HapByteBuffer::IsEqual(const HapByteBuffer& other)
311 {
312     if (&other == this) {
313         return true;
314     }
315     if (capacity != other.GetCapacity() || other.GetBufferPtr() == nullptr || buffer == nullptr) {
316         HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
317         return false;
318     }
319     const char* otherBuffer = other.GetBufferPtr();
320     for (int32_t i = 0; i < capacity; i++) {
321         if (buffer[i] != otherBuffer[i]) {
322             HAPVERIFY_LOG_ERROR(LABEL, "diff value[%{public}d]: %{public}x %{public}x",
323                 i, buffer[i], otherBuffer[i]);
324             return false;
325         }
326     }
327     return true;
328 }
329 
IsEqual(const std::string & other)330 bool HapByteBuffer::IsEqual(const std::string& other)
331 {
332     if (capacity != static_cast<int32_t>(other.size()) || buffer == nullptr) {
333         HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
334         return false;
335     }
336     for (int32_t i = 0; i < capacity; i++) {
337         if (buffer[i] != other[i]) {
338             HAPVERIFY_LOG_ERROR(LABEL, "diff value[%{public}d]: %{public}x %{public}x",
339                 i, buffer[i], other[i]);
340             return false;
341         }
342     }
343     return true;
344 }
345 
SetCapacity(int32_t cap)346 void HapByteBuffer::SetCapacity(int32_t cap)
347 {
348     if (buffer != nullptr) {
349         buffer.reset(nullptr);
350         position = 0;
351         limit = 0;
352         capacity = 0;
353     }
354     Init(cap);
355 }
356 } // namespace Verify
357 } // namespace Security
358 } // namespace OHOS
359