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 "securec.h"
19
20 #include "common/hap_verify_log.h"
21
22 namespace OHOS {
23 namespace Security {
24 namespace Verify {
25 const int HapByteBuffer::MAX_PRINT_LENGTH = 200;
26 const int HapByteBuffer::HEX_PRINT_LENGTH = 3;
27
HapByteBuffer()28 HapByteBuffer::HapByteBuffer() : buffer(nullptr), position(0), limit(0), capacity(0)
29 {
30 }
31
HapByteBuffer(int bufferCapacity)32 HapByteBuffer::HapByteBuffer(int bufferCapacity) : buffer(nullptr), position(0), limit(0), capacity(0)
33 {
34 Init(bufferCapacity);
35 }
36
HapByteBuffer(const HapByteBuffer & other)37 HapByteBuffer::HapByteBuffer(const HapByteBuffer& other) : buffer(nullptr), position(0), limit(0), capacity(0)
38 {
39 Init(other.GetCapacity());
40 if (buffer != nullptr && capacity > 0) {
41 if (memcpy_s(buffer.get(), capacity, other.GetBufferPtr(), other.GetCapacity()) != EOK) {
42 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
43 return;
44 }
45 position = other.GetPosition();
46 limit = other.GetLimit();
47 }
48 }
49
~HapByteBuffer()50 HapByteBuffer::~HapByteBuffer()
51 {
52 buffer.reset(nullptr);
53 }
54
Init(int bufferCapacity)55 void HapByteBuffer::Init(int bufferCapacity)
56 {
57 if (bufferCapacity > 0) {
58 buffer = std::make_unique<char[]>(bufferCapacity);
59 if (buffer != nullptr) {
60 limit = bufferCapacity;
61 capacity = bufferCapacity;
62 }
63 } else {
64 HAPVERIFY_LOG_INFO(LABEL, "bufferCapacity %{public}d is too small", bufferCapacity);
65 }
66 }
67
operator =(const HapByteBuffer & other)68 HapByteBuffer& HapByteBuffer::operator=(const HapByteBuffer& other)
69 {
70 if (&other == this) {
71 return *this;
72 }
73
74 buffer.reset(nullptr);
75 Init(other.GetCapacity());
76 if (buffer != nullptr && other.GetBufferPtr() != nullptr && capacity > 0) {
77 if (memcpy_s(buffer.get(), capacity, other.GetBufferPtr(), other.GetCapacity()) != EOK) {
78 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
79 return *this;
80 }
81 position = other.GetPosition();
82 limit = other.GetLimit();
83 }
84 return *this;
85 }
86
CheckInputForGettingData(int index,int dataLen)87 bool HapByteBuffer::CheckInputForGettingData(int index, int dataLen)
88 {
89 if (buffer == nullptr) {
90 HAPVERIFY_LOG_ERROR(LABEL, "buffer is nullptr");
91 return false;
92 }
93 if (index < 0) {
94 HAPVERIFY_LOG_ERROR(LABEL, "invalid index %{public}d", index);
95 return false;
96 }
97 long long getDataLast = static_cast<long long>(position) + static_cast<long long>(index) +
98 static_cast<long long>(dataLen);
99 if (getDataLast > static_cast<long long>(limit)) {
100 HAPVERIFY_LOG_ERROR(LABEL, "position %{public}d, index %{public}d, limit %{public}d",
101 position, index, limit);
102 return false;
103 }
104 return true;
105 }
106
GetInt64(long long & value)107 bool HapByteBuffer::GetInt64(long long& value)
108 {
109 if (!GetInt64(0, value)) {
110 HAPVERIFY_LOG_ERROR(LABEL, "GetInt64 failed");
111 return false;
112 }
113 position += sizeof(long long);
114 return true;
115 }
116
GetInt64(int index,long long & value)117 bool HapByteBuffer::GetInt64(int index, long long& value)
118 {
119 if (!CheckInputForGettingData(index, sizeof(long long))) {
120 HAPVERIFY_LOG_ERROR(LABEL, "Failed to get Int64");
121 return false;
122 }
123
124 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(long long)) != EOK) {
125 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
126 return false;
127 }
128 return true;
129 }
130
GetCapacity() const131 int HapByteBuffer::GetCapacity() const
132 {
133 return capacity;
134 }
135
GetBufferPtr() const136 const char* HapByteBuffer::GetBufferPtr() const
137 {
138 return buffer.get();
139 }
140
GetInt32(int & value)141 bool HapByteBuffer::GetInt32(int& value)
142 {
143 if (!GetInt32(0, value)) {
144 HAPVERIFY_LOG_ERROR(LABEL, "GetInt32 failed");
145 return false;
146 }
147 position += sizeof(int);
148 return true;
149 }
150
GetInt32(int index,int & value)151 bool HapByteBuffer::GetInt32(int index, int& value)
152 {
153 if (!CheckInputForGettingData(index, sizeof(int))) {
154 HAPVERIFY_LOG_ERROR(LABEL, "Failed to get Int32");
155 return false;
156 }
157
158 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(int)) != EOK) {
159 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
160 return false;
161 }
162 return true;
163 }
164
GetUInt32(int index,unsigned int & value)165 bool HapByteBuffer::GetUInt32(int index, unsigned int& value)
166 {
167 if (!CheckInputForGettingData(index, sizeof(unsigned int))) {
168 HAPVERIFY_LOG_ERROR(LABEL, "Failed to get UInt32");
169 return false;
170 }
171
172 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(unsigned int)) != EOK) {
173 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
174 return false;
175 }
176 return true;
177 }
178
GetUInt16(int index,unsigned short & value)179 bool HapByteBuffer::GetUInt16(int index, unsigned short& value)
180 {
181 if (!CheckInputForGettingData(index, sizeof(unsigned short))) {
182 HAPVERIFY_LOG_ERROR(LABEL, "Failed to get UInt16");
183 return false;
184 }
185
186 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(unsigned short)) != EOK) {
187 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
188 return false;
189 }
190 return true;
191 }
192
PutInt32(int offset,int value)193 void HapByteBuffer::PutInt32(int offset, int value)
194 {
195 if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int>(sizeof(value))) {
196 if (memcpy_s((buffer.get() + offset), (limit - offset), &value, sizeof(value)) != EOK) {
197 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
198 }
199 }
200 }
201
PutByte(int offset,char value)202 void HapByteBuffer::PutByte(int offset, char value)
203 {
204 if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int>(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
PutData(int offset,const char data[],int len)211 void HapByteBuffer::PutData(int offset, const char data[], int len)
212 {
213 if (buffer != nullptr && data != nullptr && offset >= 0 && len > 0 && (limit - offset) >= len) {
214 if (memcpy_s((buffer.get() + offset), (limit - offset), data, len) != EOK) {
215 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
216 }
217 }
218 }
219
SetPosition(int pos)220 void HapByteBuffer::SetPosition(int pos)
221 {
222 if (pos >= 0 && pos <= limit) {
223 position = pos;
224 }
225 }
226
Slice()227 void HapByteBuffer::Slice()
228 {
229 if (position >= capacity || limit > capacity || position >= limit || buffer == nullptr) {
230 HAPVERIFY_LOG_ERROR(LABEL, "position %{public}d capacity %{public}d limit %{public}d error",
231 position, capacity, limit);
232 return;
233 }
234 int newCapacity = limit - position;
235 std::unique_ptr<char[]> newBuffer = std::make_unique<char[]>(newCapacity);
236 if (newBuffer == nullptr) {
237 HAPVERIFY_LOG_ERROR(LABEL, "make_unique failed");
238 return;
239 }
240 if (memcpy_s(newBuffer.get(), newCapacity, (buffer.get() + position), (limit - position)) != EOK) {
241 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
242 return;
243 }
244 buffer.reset(newBuffer.release());
245 position = 0;
246 capacity = newCapacity;
247 limit = capacity;
248 }
249
GetPosition() const250 int HapByteBuffer::GetPosition() const
251 {
252 return position;
253 }
254
GetLimit() const255 int HapByteBuffer::GetLimit() const
256 {
257 return limit;
258 }
259
SetLimit(int lim)260 void HapByteBuffer::SetLimit(int lim)
261 {
262 if (lim <= capacity && lim >= position) {
263 limit = lim;
264 }
265 }
266
Remaining() const267 int HapByteBuffer::Remaining() const
268 {
269 return limit - position;
270 }
271
HasRemaining() const272 bool HapByteBuffer::HasRemaining() const
273 {
274 return position < limit;
275 }
276
CopyPartialBuffer(const HapByteBuffer & other,int len)277 bool HapByteBuffer::CopyPartialBuffer(const HapByteBuffer& other, int len)
278 {
279 int readableDataLen = other.Remaining();
280 if (readableDataLen < len) {
281 HAPVERIFY_LOG_ERROR(LABEL, "readableDataLen %{public}d less than len %{public}d", readableDataLen, len);
282 return false;
283 }
284
285 buffer.reset(nullptr);
286 buffer = std::make_unique<char[]>(len);
287 if (buffer != nullptr && other.GetBufferPtr() != nullptr) {
288 capacity = len;
289 limit = capacity;
290 if (memcpy_s(buffer.get(), capacity, (other.GetBufferPtr() + other.GetPosition()), len) != EOK) {
291 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
292 return false;
293 }
294 }
295 position = 0;
296 return true;
297 }
298
Clear()299 void HapByteBuffer::Clear()
300 {
301 position = 0;
302 limit = capacity;
303 }
304
IsEqual(const HapByteBuffer & other)305 bool HapByteBuffer::IsEqual(const HapByteBuffer& other)
306 {
307 if (&other == this) {
308 return true;
309 }
310 if (capacity != other.GetCapacity() || other.GetBufferPtr() == nullptr || buffer == nullptr) {
311 HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
312 return false;
313 }
314 const char* otherBuffer = other.GetBufferPtr();
315 for (int i = 0; i < capacity; i++) {
316 if (buffer[i] != otherBuffer[i]) {
317 HAPVERIFY_LOG_ERROR(LABEL, "diff value[%{public}d]: %{public}x %{public}x",
318 i, buffer[i], otherBuffer[i]);
319 return false;
320 }
321 }
322 return true;
323 }
324
IsEqual(const std::string & other)325 bool HapByteBuffer::IsEqual(const std::string& other)
326 {
327 if (capacity != static_cast<int>(other.size()) || buffer == nullptr) {
328 HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
329 return false;
330 }
331 for (int i = 0; i < capacity; i++) {
332 if (buffer[i] != other[i]) {
333 HAPVERIFY_LOG_ERROR(LABEL, "diff value[%{public}d]: %{public}x %{public}x",
334 i, buffer[i], other[i]);
335 return false;
336 }
337 }
338 return true;
339 }
340
SetCapacity(int cap)341 void HapByteBuffer::SetCapacity(int cap)
342 {
343 if (buffer != nullptr) {
344 buffer.reset(nullptr);
345 position = 0;
346 limit = 0;
347 capacity = 0;
348 }
349 Init(cap);
350 }
351 } // namespace Verify
352 } // namespace Security
353 } // namespace OHOS
354