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