1 /*
2 * Copyright (c) 2024-2024 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 #include "byte_buffer.h"
16 #include <cstdio>
17 #include <algorithm>
18 #include "securec.h"
19 #include "signature_tools_log.h"
20
21 namespace OHOS {
22 namespace SignatureTools {
23
24 const int32_t ByteBuffer::MAX_PRINT_LENGTH = 200;
25 const int32_t ByteBuffer::HEX_PRINT_LENGTH = 3;
26 const int64_t MAX_MEMORY = 2L * 1024L * 1024L * 1024L;
27
28 template<typename T>
make_shared_array(size_t size)29 std::shared_ptr<T> make_shared_array(size_t size)
30 {
31 if (size == 0) {
32 return NULL;
33 }
34 if (size > MAX_MEMORY) {
35 SIGNATURE_TOOLS_LOGE("size %zu is too large", size);
36 return NULL;
37 }
38 T* buffer = new (std::nothrow)T[size];
39 if (!buffer) {
40 SIGNATURE_TOOLS_LOGE("new size failed");
41 return NULL;
42 }
43 return std::shared_ptr<T>(buffer, [] (T* p) { delete[] p; });
44 }
45
ByteBuffer()46 ByteBuffer::ByteBuffer() : buffer(nullptr), position(0), limit(0), capacity(0)
47 {
48 }
49
ByteBuffer(int32_t bufferCapacity)50 ByteBuffer::ByteBuffer(int32_t bufferCapacity) : buffer(nullptr), position(0), limit(0), capacity(0)
51 {
52 Init(bufferCapacity);
53 }
54
ByteBuffer(const char * arr,int32_t length)55 ByteBuffer::ByteBuffer(const char* arr, int32_t length) : buffer(nullptr), position(0), limit(0), capacity(0)
56 {
57 Init(length);
58 PutData(0, arr, length);
59 }
60
ByteBuffer(const ByteBuffer & other)61 ByteBuffer::ByteBuffer(const ByteBuffer& other) : buffer(nullptr), position(0), limit(0), capacity(0)
62 {
63 Init(other.GetCapacity());
64 if (buffer != nullptr && capacity > 0) {
65 if (memcpy_s(buffer.get(), capacity, other.GetBufferPtr(), other.GetCapacity()) != EOK) {
66 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
67 return;
68 }
69 position = other.GetPosition();
70 limit = other.GetLimit();
71 }
72 }
73
~ByteBuffer()74 ByteBuffer::~ByteBuffer()
75 {
76 }
77
Init(int32_t bufferCapacity)78 void ByteBuffer::Init(int32_t bufferCapacity)
79 {
80 if (bufferCapacity > 0) {
81 buffer = make_shared_array<char>(bufferCapacity);
82 if (buffer != nullptr) {
83 if (memset_s(buffer.get(), bufferCapacity, 0, bufferCapacity) != EOK) {
84 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
85 }
86 limit = bufferCapacity;
87 capacity = bufferCapacity;
88 }
89 } else {
90 SIGNATURE_TOOLS_LOGE("bufferCapacity %d is too small", bufferCapacity);
91 }
92 }
93
operator =(const ByteBuffer & other)94 ByteBuffer& ByteBuffer::operator=(const ByteBuffer& other)
95 {
96 if (&other == this) {
97 return *this;
98 }
99 // std::unique_ptr reset(),will first release the original object and then point to the new object
100 buffer = nullptr;
101 Init(other.GetCapacity());
102 if (buffer != nullptr && other.GetBufferPtr() != nullptr && capacity > 0) {
103 if (memcpy_s(buffer.get(), capacity, other.GetBufferPtr(), other.GetCapacity()) != EOK) {
104 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
105 return *this;
106 }
107 position = other.GetPosition();
108 limit = other.GetLimit();
109 }
110 return *this;
111 }
112
CheckInputForGettingData(int32_t index,int32_t dataLen)113 bool ByteBuffer::CheckInputForGettingData(int32_t index, int32_t dataLen)
114 {
115 if (buffer == nullptr) {
116 SIGNATURE_TOOLS_LOGE("buffer is nullptr");
117 return false;
118 }
119 if (index < 0) {
120 SIGNATURE_TOOLS_LOGE("invalid index %d", index);
121 return false;
122 }
123 int64_t getDataLast = static_cast<int64_t>(position) + static_cast<int64_t>(index) +
124 static_cast<int64_t>(dataLen);
125 if (getDataLast > static_cast<int64_t>(limit)) {
126 SIGNATURE_TOOLS_LOGE("position: %d, index: %d, limit: %d", position, index, limit);
127 return false;
128 }
129 return true;
130 }
131
GetInt64(int64_t & value)132 bool ByteBuffer::GetInt64(int64_t& value)
133 {
134 if (!GetInt64(0, value)) {
135 SIGNATURE_TOOLS_LOGE("GetInt64 failed");
136 return false;
137 }
138 position += sizeof(int64_t);
139 return true;
140 }
141
GetInt64(int32_t index,int64_t & value)142 bool ByteBuffer::GetInt64(int32_t index, int64_t& value)
143 {
144 if (!CheckInputForGettingData(index, sizeof(int64_t))) {
145 SIGNATURE_TOOLS_LOGE("Failed to get Int64");
146 return false;
147 }
148 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(int64_t)) != EOK) {
149 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
150 return false;
151 }
152 return true;
153 }
154
GetCapacity() const155 int32_t ByteBuffer::GetCapacity() const
156 {
157 return capacity;
158 }
159
GetBufferPtr() const160 const char* ByteBuffer::GetBufferPtr() const
161 {
162 return buffer.get();
163 }
164
GetInt32(int32_t & value)165 bool ByteBuffer::GetInt32(int32_t& value)
166 {
167 if (!GetInt32(0, value)) {
168 SIGNATURE_TOOLS_LOGE("GetInt32 failed");
169 return false;
170 }
171 position += sizeof(int32_t);
172 return true;
173 }
174
GetInt32(int32_t index,int32_t & value)175 bool ByteBuffer::GetInt32(int32_t index, int32_t& value)
176 {
177 if (!CheckInputForGettingData(index, sizeof(int32_t))) {
178 SIGNATURE_TOOLS_LOGE("Failed to get Int32");
179 return false;
180 }
181 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(int32_t)) != EOK) {
182 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
183 return false;
184 }
185 return true;
186 }
187
GetUInt32(int32_t index,uint32_t & value)188 bool ByteBuffer::GetUInt32(int32_t index, uint32_t& value)
189 {
190 if (!CheckInputForGettingData(index, sizeof(uint32_t))) {
191 SIGNATURE_TOOLS_LOGE("Failed to get UInt32");
192 return false;
193 }
194 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(uint32_t)) != EOK) {
195 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
196 return false;
197 }
198 return true;
199 }
200
GetUInt32(uint32_t & value)201 bool ByteBuffer::GetUInt32(uint32_t& value)
202 {
203 if (!GetUInt32(0, value)) {
204 SIGNATURE_TOOLS_LOGE("GetUInt32 failed");
205 return false;
206 }
207 position += sizeof(uint32_t);
208 return true;
209 }
210
GetUInt16(uint16_t & value)211 bool ByteBuffer::GetUInt16(uint16_t& value)
212 {
213 if (!GetUInt16(0, value)) {
214 SIGNATURE_TOOLS_LOGE("GetUInt16 failed");
215 return false;
216 }
217 position += sizeof(uint16_t);
218 return true;
219 }
220
GetUInt16(int32_t index,uint16_t & value)221 bool ByteBuffer::GetUInt16(int32_t index, uint16_t& value)
222 {
223 if (!CheckInputForGettingData(index, sizeof(uint16_t))) {
224 SIGNATURE_TOOLS_LOGE("Failed to get UInt16");
225 return false;
226 }
227 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(uint16_t)) != EOK) {
228 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
229 return false;
230 }
231 return true;
232 }
233
GetInt16(int16_t & value)234 bool ByteBuffer::GetInt16(int16_t& value)
235 {
236 if (!GetInt16(0, value)) {
237 SIGNATURE_TOOLS_LOGE("GetInt16 failed");
238 return false;
239 }
240 position += sizeof(int16_t);
241 return true;
242 }
243
GetInt16(int32_t index,int16_t & value)244 bool ByteBuffer::GetInt16(int32_t index, int16_t& value)
245 {
246 if (!CheckInputForGettingData(index, sizeof(int16_t))) {
247 SIGNATURE_TOOLS_LOGE("Failed to get Int16");
248 return false;
249 }
250 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(int16_t)) != EOK) {
251 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
252 return false;
253 }
254 return true;
255 }
256
GetUInt8(uint8_t & value)257 bool ByteBuffer::GetUInt8(uint8_t& value)
258 {
259 if (!GetUInt8(0, value)) {
260 SIGNATURE_TOOLS_LOGE("GetUInt8 failed");
261 return false;
262 }
263 position += sizeof(uint8_t);
264 return true;
265 }
266
GetUInt8(int32_t index,uint8_t & value)267 bool ByteBuffer::GetUInt8(int32_t index, uint8_t& value)
268 {
269 if (!CheckInputForGettingData(index, sizeof(uint8_t))) {
270 SIGNATURE_TOOLS_LOGE("Failed to get UInt8");
271 return false;
272 }
273 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(uint8_t)) != EOK) {
274 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
275 return false;
276 }
277 return true;
278 }
279
GetInt8(int8_t & value)280 bool ByteBuffer::GetInt8(int8_t& value)
281 {
282 if (!GetInt8(0, value)) {
283 SIGNATURE_TOOLS_LOGE("GetInt8 failed");
284 return false;
285 }
286 position += sizeof(int8_t);
287 return true;
288 }
289
GetInt8(int32_t index,int8_t & value)290 bool ByteBuffer::GetInt8(int32_t index, int8_t& value)
291 {
292 if (!CheckInputForGettingData(index, sizeof(int8_t))) {
293 SIGNATURE_TOOLS_LOGE("Failed to get Int8");
294 return false;
295 }
296 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(int8_t)) != EOK) {
297 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
298 return false;
299 }
300 return true;
301 }
302
PutInt64(int64_t value)303 void ByteBuffer::PutInt64(int64_t value)
304 {
305 if ((limit - position) >= static_cast<int64_t>(sizeof(value))) {
306 if (memcpy_s(buffer.get() + position, limit - position, &value, sizeof(value)) != EOK) {
307 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
308 } else {
309 position += sizeof(value);
310 }
311 }
312 }
313
PutInt32(int32_t offset,int32_t value)314 void ByteBuffer::PutInt32(int32_t offset, int32_t value)
315 {
316 if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int32_t>(sizeof(value))) {
317 if (memcpy_s((buffer.get() + offset), (limit - offset), &value, sizeof(value)) != EOK) {
318 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
319 }
320 }
321 }
322
PutInt16(int32_t offset,int16_t value)323 void ByteBuffer::PutInt16(int32_t offset, int16_t value)
324 {
325 if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int16_t>(sizeof(value))) {
326 if (memcpy_s((buffer.get() + offset), (limit - offset), &value, sizeof(value)) != EOK) {
327 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
328 }
329 }
330 }
331
PutByte(int32_t offset,char value)332 void ByteBuffer::PutByte(int32_t offset, char value)
333 {
334 if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int32_t>(sizeof(value))) {
335 if (memcpy_s((buffer.get() + offset), (limit - offset), (&value), sizeof(value)) != EOK) {
336 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
337 }
338 }
339 }
340
PutData(int32_t offset,const char data[],int32_t len)341 void ByteBuffer::PutData(int32_t offset, const char data[], int32_t len)
342 {
343 if (buffer != nullptr && data != nullptr && offset >= 0 && len > 0 && (limit - offset) >= len) {
344 if (memcpy_s((buffer.get() + offset), (limit - offset), data, len) != EOK) {
345 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
346 }
347 }
348 }
349
PutData(int32_t offset,const int8_t data[],int32_t len)350 void ByteBuffer::PutData(int32_t offset, const int8_t data[], int32_t len)
351 {
352 if (buffer != nullptr && data != nullptr && offset >= 0 && len > 0 && (limit - offset) >= len) {
353 if (memcpy_s((buffer.get() + offset), (limit - offset), data, len) != EOK) {
354 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
355 }
356 }
357 }
358
PutData(int32_t offset,const char data[],int32_t len,int32_t type)359 void ByteBuffer::PutData(int32_t offset, const char data[], int32_t len, int32_t type)
360 {
361 static int offsetAdd = 0;
362 if (buffer != nullptr && data != nullptr && offset >= 0 && len > 0 && (limit - offset) >= len) {
363 if (memcpy_s((buffer.get() + offsetAdd), (limit - offsetAdd), data, len) != EOK) {
364 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
365 }
366 offsetAdd += offset;
367 }
368 }
369
PutInt32(int32_t value)370 void ByteBuffer::PutInt32(int32_t value)
371 {
372 if (limit - position >= static_cast<int32_t>(sizeof(value))) {
373 if (memcpy_s(buffer.get() + position, limit - position, &value, sizeof(value)) != EOK) {
374 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
375 } else {
376 position += sizeof(value);
377 }
378 }
379 }
380
PutInt16(int16_t value)381 void ByteBuffer::PutInt16(int16_t value)
382 {
383 if (limit - position >= static_cast<int16_t>(sizeof(value))) {
384 if (memcpy_s(buffer.get() + position, limit - position, &value, sizeof(value)) != EOK) {
385 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
386 } else {
387 position += sizeof(value);
388 }
389 }
390 }
391
PutUInt8(uint8_t value)392 void ByteBuffer::PutUInt8(uint8_t value)
393 {
394 if (limit - position >= static_cast<int8_t>(sizeof(value))) {
395 if (memcpy_s(buffer.get() + position, limit - position, &value, sizeof(value)) != EOK) {
396 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
397 } else {
398 position += sizeof(value);
399 }
400 }
401 }
402
PutUInt16(uint16_t value)403 void ByteBuffer::PutUInt16(uint16_t value)
404 {
405 if (limit - position >= static_cast<uint16_t>(sizeof(value))) {
406 if (memcpy_s(buffer.get() + position, limit - position, &value, sizeof(value)) != EOK) {
407 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
408 } else {
409 position += sizeof(value);
410 }
411 }
412 }
413
PutUInt32(uint32_t value)414 void ByteBuffer::PutUInt32(uint32_t value)
415 {
416 if (limit - position >= static_cast<uint32_t>(sizeof(value))) {
417 if (memcpy_s(buffer.get() + position, limit - position, &value, sizeof(value)) != EOK) {
418 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
419 } else {
420 position += sizeof(value);
421 }
422 }
423 }
424
ClearData()425 void ByteBuffer::ClearData()
426 {
427 if (buffer != nullptr && position < capacity) {
428 if (memset_s(buffer.get() + position, capacity - position, 0, capacity - position) != EOK) {
429 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
430 }
431 }
432 }
433
PutByte(char value)434 void ByteBuffer::PutByte(char value)
435 {
436 if (buffer != nullptr && limit - position >= static_cast<char>(sizeof(value))) {
437 if (memcpy_s(buffer.get() + position, limit - position, &value, sizeof(value)) != EOK) {
438 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
439 } else {
440 position += sizeof(value);
441 }
442 }
443 }
444
Put(const ByteBuffer & byteBuffer)445 void ByteBuffer::Put(const ByteBuffer& byteBuffer)
446 {
447 PutData(byteBuffer.GetBufferPtr(), byteBuffer.Remaining());
448 }
449
PutData(const char data[],int32_t len)450 void ByteBuffer::PutData(const char data[], int32_t len)
451 {
452 if (buffer != nullptr && data != nullptr && len > 0 && (limit - position) >= len) {
453 if (memcpy_s((buffer.get() + position), (limit - position), data, len) != EOK) {
454 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
455 } else {
456 position += len;
457 }
458 }
459 }
460
PutData(int8_t data[],int32_t len)461 void ByteBuffer::PutData(int8_t data[], int32_t len)
462 {
463 if (buffer != nullptr && data != nullptr && len > 0 && (limit - position) >= len) {
464 if (memcpy_s((buffer.get() + position), (limit - position), data, len) != EOK) {
465 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
466 } else {
467 position += len;
468 }
469 }
470 }
471
GetByte(int8_t data[],int32_t len)472 void ByteBuffer::GetByte(int8_t data[], int32_t len)
473 {
474 if (0 == memcpy_s(data, len, buffer.get() + position, len)) {
475 position = position + len;
476 }
477 }
478
GetData(char data[],uint32_t len)479 void ByteBuffer::GetData(char data[], uint32_t len)
480 {
481 if (0 == memcpy_s(data, len, buffer.get() + position, len)) {
482 position = position + len;
483 }
484 }
485
GetData(int32_t offset,int8_t data[],uint32_t len)486 void ByteBuffer::GetData(int32_t offset, int8_t data[], uint32_t len)
487 {
488 if (0 == memcpy_s(data, len, buffer.get() + offset, len)) {
489 position = position + len;
490 }
491 }
492
SetPosition(int32_t pos)493 void ByteBuffer::SetPosition(int32_t pos)
494 {
495 if (pos >= 0 && pos <= limit) {
496 position = pos;
497 }
498 }
499
slice_for_codesigning()500 ByteBuffer& ByteBuffer::slice_for_codesigning()
501 {
502 if (position >= capacity || limit > capacity || position >= limit || buffer == nullptr) {
503 SIGNATURE_TOOLS_LOGE("position %d capacity %d limit %d error", position, capacity, limit);
504 return *this;
505 }
506 int32_t rem = (position <= limit ? limit - position : 0);
507
508 position = 0;
509 capacity = rem;
510 limit = rem;
511 return *this;
512 }
513
Slice()514 ByteBuffer& ByteBuffer::Slice()
515 {
516 if (position >= capacity || limit > capacity || position >= limit || buffer == nullptr) {
517 SIGNATURE_TOOLS_LOGE("position %d capacity %d limit %d error",
518 position, capacity, limit);
519 return *this;
520 }
521 int32_t newCapacity = limit - position;
522 auto newBuffer = make_shared_array<char>(newCapacity);
523 if (newBuffer == nullptr) {
524 SIGNATURE_TOOLS_LOGE("make_shared_array failed");
525 return *this;
526 }
527 if (memcpy_s(newBuffer.get(), newCapacity, buffer.get() + position, newCapacity) != RET_OK) {
528 SIGNATURE_TOOLS_LOGE("memcpy_s failed");
529 return *this;
530 }
531 buffer = std::move(newBuffer);
532 position = 0;
533 capacity = newCapacity;
534 limit = capacity;
535
536 return *this;
537 }
538
Duplicate()539 ByteBuffer* ByteBuffer::Duplicate()
540 {
541 ByteBuffer* newBuffer = new ByteBuffer();
542 newBuffer->buffer = buffer;
543 newBuffer->limit = limit;
544 newBuffer->capacity = capacity;
545 newBuffer->position = position;
546 return newBuffer;
547 }
548
GetPosition() const549 int32_t ByteBuffer::GetPosition() const
550 {
551 return position;
552 }
553
GetLimit() const554 int32_t ByteBuffer::GetLimit() const
555 {
556 return limit;
557 }
558
SetLimit(int32_t lim)559 void ByteBuffer::SetLimit(int32_t lim)
560 {
561 if (lim <= capacity && lim >= position) {
562 limit = lim;
563 }
564 }
565
Remaining() const566 int32_t ByteBuffer::Remaining() const
567 {
568 return position < limit ? limit - position : 0;
569 }
570
HasRemaining() const571 bool ByteBuffer::HasRemaining() const
572 {
573 return position < limit;
574 }
575
Clear()576 void ByteBuffer::Clear()
577 {
578 position = 0;
579 limit = capacity;
580 }
581
Flip()582 ByteBuffer& ByteBuffer::Flip()
583 {
584 limit = position;
585 position = 0;
586 return *this;
587 }
588
IsEqual(const ByteBuffer & other)589 bool ByteBuffer::IsEqual(const ByteBuffer& other)
590 {
591 if (&other == this) {
592 return true;
593 }
594 if (capacity != other.GetCapacity() || other.GetBufferPtr() == nullptr || buffer == nullptr) {
595 SIGNATURE_TOOLS_LOGE("invalid input");
596 return false;
597 }
598 const char* otherBuffer = other.GetBufferPtr();
599 for (int32_t i = 0; i < capacity; i++) {
600 if (buffer.get()[i] != otherBuffer[i]) {
601 SIGNATURE_TOOLS_LOGE("diff value[%d]: %x %x",
602 i, buffer.get()[i], otherBuffer[i]);
603 return false;
604 }
605 }
606 return true;
607 }
608
IsEqual(const std::string & other)609 bool ByteBuffer::IsEqual(const std::string& other)
610 {
611 if (capacity != static_cast<int32_t>(other.size()) || buffer == nullptr) {
612 SIGNATURE_TOOLS_LOGE("invalid input");
613 return false;
614 }
615 for (int32_t i = 0; i < capacity; i++) {
616 if (buffer.get()[i] != other[i]) {
617 SIGNATURE_TOOLS_LOGE("diff value[%d]: %x %x",
618 i, buffer.get()[i], other[i]);
619 return false;
620 }
621 }
622 return true;
623 }
624
SetCapacity(int32_t cap)625 void ByteBuffer::SetCapacity(int32_t cap)
626 {
627 if (buffer != nullptr) {
628 buffer = nullptr;
629 position = 0;
630 limit = 0;
631 capacity = 0;
632 }
633 Init(cap);
634 }
635
ToString()636 std::string ByteBuffer::ToString()
637 {
638 return std::string(GetBufferPtr(), GetCapacity());
639 }
640
641 } // namespace SignatureTools
642 } // namespace OHOS