1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at 6fb299fa2Sopenharmony_ci * 7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb299fa2Sopenharmony_ci * 9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and 13fb299fa2Sopenharmony_ci * limitations under the License. 14fb299fa2Sopenharmony_ci */ 15fb299fa2Sopenharmony_ci 16fb299fa2Sopenharmony_ci#include "image_patch.h" 17fb299fa2Sopenharmony_ci#include <memory> 18fb299fa2Sopenharmony_ci#include <string> 19fb299fa2Sopenharmony_ci#include <vector> 20fb299fa2Sopenharmony_ci#include "diffpatch.h" 21fb299fa2Sopenharmony_ci#include "lz4_adapter.h" 22fb299fa2Sopenharmony_ci#include "openssl/sha.h" 23fb299fa2Sopenharmony_ci#include "securec.h" 24fb299fa2Sopenharmony_ci#include "zip_adapter.h" 25fb299fa2Sopenharmony_ci#include "scope_guard.h" 26fb299fa2Sopenharmony_ci 27fb299fa2Sopenharmony_ciusing namespace Hpackage; 28fb299fa2Sopenharmony_ciusing namespace Updater; 29fb299fa2Sopenharmony_ci 30fb299fa2Sopenharmony_cinamespace UpdatePatch { 31fb299fa2Sopenharmony_ciuint32_t g_tmpFileId = 0; 32fb299fa2Sopenharmony_ci 33fb299fa2Sopenharmony_ciint32_t NormalImagePatch::ApplyImagePatch(const PatchParam ¶m, size_t &startOffset) 34fb299fa2Sopenharmony_ci{ 35fb299fa2Sopenharmony_ci size_t offset = startOffset; 36fb299fa2Sopenharmony_ci if (offset + PATCH_NORMAL_MIN_HEADER_LEN > param.patchSize) { 37fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to check datalen"); 38fb299fa2Sopenharmony_ci return -1; 39fb299fa2Sopenharmony_ci } 40fb299fa2Sopenharmony_ci 41fb299fa2Sopenharmony_ci size_t srcStart = static_cast<size_t>(ReadLE<int64_t>(param.patch + offset)); 42fb299fa2Sopenharmony_ci offset += sizeof(int64_t); 43fb299fa2Sopenharmony_ci size_t srcLen = static_cast<size_t>(ReadLE<int64_t>(param.patch + offset)); 44fb299fa2Sopenharmony_ci offset += sizeof(int64_t); 45fb299fa2Sopenharmony_ci size_t patchOffset = static_cast<size_t>(ReadLE<int64_t>(param.patch + offset)); 46fb299fa2Sopenharmony_ci offset += sizeof(int64_t); 47fb299fa2Sopenharmony_ci if (srcStart > param.oldSize || param.oldSize - srcStart < srcLen || 48fb299fa2Sopenharmony_ci patchOffset > param.patchSize) { 49fb299fa2Sopenharmony_ci PATCH_LOGE("error, srcStart: %zu srcLen: %zu , param.oldSize: %zu, patchOffset: %zu", 50fb299fa2Sopenharmony_ci srcStart, srcLen, param.oldSize, patchOffset); 51fb299fa2Sopenharmony_ci return -1; 52fb299fa2Sopenharmony_ci } 53fb299fa2Sopenharmony_ci 54fb299fa2Sopenharmony_ci PatchBuffer patchInfo = {param.patch, patchOffset, param.patchSize}; 55fb299fa2Sopenharmony_ci BlockBuffer oldInfo = {param.oldBuff + srcStart, srcLen}; 56fb299fa2Sopenharmony_ci int32_t ret = UpdateApplyPatch::ApplyBlockPatch(patchInfo, oldInfo, writer_); 57fb299fa2Sopenharmony_ci if (ret != 0) { 58fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to apply bsdiff patch"); 59fb299fa2Sopenharmony_ci return -1; 60fb299fa2Sopenharmony_ci } 61fb299fa2Sopenharmony_ci startOffset = offset; 62fb299fa2Sopenharmony_ci return 0; 63fb299fa2Sopenharmony_ci} 64fb299fa2Sopenharmony_ci 65fb299fa2Sopenharmony_ciint32_t RowImagePatch::ApplyImagePatch(const PatchParam ¶m, size_t &startOffset) 66fb299fa2Sopenharmony_ci{ 67fb299fa2Sopenharmony_ci size_t offset = startOffset; 68fb299fa2Sopenharmony_ci if (offset + sizeof(int32_t) > param.patchSize) { 69fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to check datalen"); 70fb299fa2Sopenharmony_ci return -1; 71fb299fa2Sopenharmony_ci } 72fb299fa2Sopenharmony_ci size_t dataLen = static_cast<size_t>(ReadLE<uint32_t>(param.patch + offset)); 73fb299fa2Sopenharmony_ci if (offset + dataLen > param.patchSize) { 74fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to check datalen"); 75fb299fa2Sopenharmony_ci return -1; 76fb299fa2Sopenharmony_ci } 77fb299fa2Sopenharmony_ci offset += sizeof(uint32_t); 78fb299fa2Sopenharmony_ci 79fb299fa2Sopenharmony_ci BlockBuffer data = {param.patch + offset, dataLen}; 80fb299fa2Sopenharmony_ci int32_t ret = writer_->Write(0, data, dataLen); 81fb299fa2Sopenharmony_ci if (ret != 0) { 82fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to write chunk"); 83fb299fa2Sopenharmony_ci return -1; 84fb299fa2Sopenharmony_ci } 85fb299fa2Sopenharmony_ci PATCH_LOGI("RowImagePatch startOffset %zu dataLen %zu", startOffset, dataLen); 86fb299fa2Sopenharmony_ci PATCH_DEBUG("ApplyImagePatch hash %zu %s", dataLen, GeneraterBufferHash(data).c_str()); 87fb299fa2Sopenharmony_ci startOffset = offset + dataLen; 88fb299fa2Sopenharmony_ci return 0; 89fb299fa2Sopenharmony_ci} 90fb299fa2Sopenharmony_ci 91fb299fa2Sopenharmony_ciint32_t CompressedImagePatch::StartReadHeader(const PatchParam ¶m, PatchHeader &header, size_t &offset) 92fb299fa2Sopenharmony_ci{ 93fb299fa2Sopenharmony_ci int32_t ret = ReadHeader(param, header, offset); 94fb299fa2Sopenharmony_ci if (ret != 0) { 95fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to read header"); 96fb299fa2Sopenharmony_ci return -1; 97fb299fa2Sopenharmony_ci } 98fb299fa2Sopenharmony_ci PATCH_LOGI("ApplyImagePatch srcStart %zu srcLen %zu patchOffset: %zu expandedLen:%zu %zu", 99fb299fa2Sopenharmony_ci header.srcStart, header.srcLength, header.patchOffset, header.expandedLen, header.targetSize); 100fb299fa2Sopenharmony_ci if (header.srcStart > param.oldSize || param.oldSize - header.srcStart < header.srcLength || 101fb299fa2Sopenharmony_ci header.patchOffset > param.patchSize) { 102fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to check patch"); 103fb299fa2Sopenharmony_ci return -1; 104fb299fa2Sopenharmony_ci } 105fb299fa2Sopenharmony_ci return 0; 106fb299fa2Sopenharmony_ci} 107fb299fa2Sopenharmony_ci 108fb299fa2Sopenharmony_ciint32_t CompressedImagePatch::ApplyImagePatch(const PatchParam ¶m, size_t &startOffset) 109fb299fa2Sopenharmony_ci{ 110fb299fa2Sopenharmony_ci size_t offset = startOffset; 111fb299fa2Sopenharmony_ci // read header 112fb299fa2Sopenharmony_ci PatchHeader header {}; 113fb299fa2Sopenharmony_ci if (StartReadHeader(param, header, offset) != 0) { 114fb299fa2Sopenharmony_ci return -1; 115fb299fa2Sopenharmony_ci } 116fb299fa2Sopenharmony_ci // decompress old data 117fb299fa2Sopenharmony_ci Hpackage::PkgManager::PkgManagerPtr pkgManager = Hpackage::PkgManager::CreatePackageInstance(); 118fb299fa2Sopenharmony_ci if (pkgManager == nullptr) { 119fb299fa2Sopenharmony_ci PATCH_LOGE("CreatePackageInstance fail"); 120fb299fa2Sopenharmony_ci return -1; 121fb299fa2Sopenharmony_ci } 122fb299fa2Sopenharmony_ci ON_SCOPE_EXIT(releaseManager) { 123fb299fa2Sopenharmony_ci Hpackage::PkgManager::ReleasePackageInstance(pkgManager); 124fb299fa2Sopenharmony_ci }; 125fb299fa2Sopenharmony_ci Hpackage::PkgManager::StreamPtr stream = nullptr; 126fb299fa2Sopenharmony_ci BlockBuffer oldData = { param.oldBuff + header.srcStart, header.srcLength }; 127fb299fa2Sopenharmony_ci if (DecompressData(pkgManager, oldData, stream, true, header.expandedLen) != 0) { 128fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to decompress data"); 129fb299fa2Sopenharmony_ci return -1; 130fb299fa2Sopenharmony_ci } 131fb299fa2Sopenharmony_ci // prepare new data 132fb299fa2Sopenharmony_ci std::unique_ptr<Hpackage::FileInfo> info = GetFileInfo(); 133fb299fa2Sopenharmony_ci if (info == nullptr) { 134fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to get file info"); 135fb299fa2Sopenharmony_ci return -1; 136fb299fa2Sopenharmony_ci } 137fb299fa2Sopenharmony_ci info->packedSize = header.targetSize; 138fb299fa2Sopenharmony_ci info->unpackedSize = header.expandedLen; 139fb299fa2Sopenharmony_ci std::unique_ptr<CompressedFileRestore> zipWriter = std::make_unique<CompressedFileRestore>(info.get(), writer_); 140fb299fa2Sopenharmony_ci if (zipWriter == nullptr || zipWriter->Init() != 0) { 141fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to create zip writer"); 142fb299fa2Sopenharmony_ci return -1; 143fb299fa2Sopenharmony_ci } 144fb299fa2Sopenharmony_ci // apply patch 145fb299fa2Sopenharmony_ci PatchBuffer patchInfo = {param.patch, header.patchOffset, param.patchSize}; 146fb299fa2Sopenharmony_ci if (UpdateApplyPatch::ApplyBlockPatch(patchInfo, stream, zipWriter.get()) != 0) { 147fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to apply bsdiff patch"); 148fb299fa2Sopenharmony_ci return -1; 149fb299fa2Sopenharmony_ci } 150fb299fa2Sopenharmony_ci // compress new data 151fb299fa2Sopenharmony_ci size_t originalSize = 0; 152fb299fa2Sopenharmony_ci size_t compressSize = 0; 153fb299fa2Sopenharmony_ci zipWriter->CompressData(originalSize, compressSize); 154fb299fa2Sopenharmony_ci PATCH_LOGI("ApplyImagePatch unpackedSize %zu %zu", originalSize, compressSize); 155fb299fa2Sopenharmony_ci if (originalSize != header.targetSize) { 156fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to apply bsdiff patch"); 157fb299fa2Sopenharmony_ci return -1; 158fb299fa2Sopenharmony_ci } 159fb299fa2Sopenharmony_ci startOffset = offset; 160fb299fa2Sopenharmony_ci return 0; 161fb299fa2Sopenharmony_ci} 162fb299fa2Sopenharmony_ci 163fb299fa2Sopenharmony_ciint32_t CompressedImagePatch::DecompressData(Hpackage::PkgManager::PkgManagerPtr &pkgManager, PkgBuffer buffer, 164fb299fa2Sopenharmony_ci Hpackage::PkgManager::StreamPtr &stream, bool memory, size_t expandedLen) const 165fb299fa2Sopenharmony_ci{ 166fb299fa2Sopenharmony_ci if (expandedLen == 0) { 167fb299fa2Sopenharmony_ci PATCH_LOGE("Decompress data is null"); 168fb299fa2Sopenharmony_ci return 0; 169fb299fa2Sopenharmony_ci } 170fb299fa2Sopenharmony_ci std::unique_ptr<Hpackage::FileInfo> info = GetFileInfo(); 171fb299fa2Sopenharmony_ci if (pkgManager == nullptr || info == nullptr) { 172fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to get pkg manager or file info"); 173fb299fa2Sopenharmony_ci return -1; 174fb299fa2Sopenharmony_ci } 175fb299fa2Sopenharmony_ci 176fb299fa2Sopenharmony_ci info->packedSize = buffer.length; 177fb299fa2Sopenharmony_ci info->unpackedSize = expandedLen; 178fb299fa2Sopenharmony_ci info->identity = std::to_string(g_tmpFileId++); 179fb299fa2Sopenharmony_ci 180fb299fa2Sopenharmony_ci // 申请内存stream,用于解压老文件 181fb299fa2Sopenharmony_ci int32_t ret = pkgManager->CreatePkgStream(stream, info->identity, 182fb299fa2Sopenharmony_ci expandedLen, memory ? PkgStream::PkgStreamType_MemoryMap : PkgStream::PkgStreamType_Write); 183fb299fa2Sopenharmony_ci if (stream == nullptr) { 184fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to create stream"); 185fb299fa2Sopenharmony_ci return -1; 186fb299fa2Sopenharmony_ci } 187fb299fa2Sopenharmony_ci 188fb299fa2Sopenharmony_ci ret = pkgManager->DecompressBuffer(info.get(), buffer, stream); 189fb299fa2Sopenharmony_ci if (ret != 0) { 190fb299fa2Sopenharmony_ci pkgManager->ClosePkgStream(stream); 191fb299fa2Sopenharmony_ci PATCH_LOGE("Can not decompress buff"); 192fb299fa2Sopenharmony_ci return -1; 193fb299fa2Sopenharmony_ci } 194fb299fa2Sopenharmony_ci 195fb299fa2Sopenharmony_ci if (bonusData_.size() == 0) { 196fb299fa2Sopenharmony_ci return 0; 197fb299fa2Sopenharmony_ci } 198fb299fa2Sopenharmony_ci if (info->unpackedSize > (expandedLen - bonusData_.size())) { 199fb299fa2Sopenharmony_ci PATCH_LOGE("Source inflation short"); 200fb299fa2Sopenharmony_ci return -1; 201fb299fa2Sopenharmony_ci } 202fb299fa2Sopenharmony_ci if (memory) { // not support for none memory 203fb299fa2Sopenharmony_ci PkgBuffer memBuffer; 204fb299fa2Sopenharmony_ci if (stream->GetBuffer(memBuffer) != 0) { 205fb299fa2Sopenharmony_ci pkgManager->ClosePkgStream(stream); 206fb299fa2Sopenharmony_ci PATCH_LOGE("Can not get memory buff"); 207fb299fa2Sopenharmony_ci return -1; 208fb299fa2Sopenharmony_ci } 209fb299fa2Sopenharmony_ci ret = memcpy_s(memBuffer.buffer + info->unpackedSize, 210fb299fa2Sopenharmony_ci expandedLen - info->unpackedSize, bonusData_.data(), bonusData_.size()); 211fb299fa2Sopenharmony_ci } 212fb299fa2Sopenharmony_ci return ret; 213fb299fa2Sopenharmony_ci} 214fb299fa2Sopenharmony_ci 215fb299fa2Sopenharmony_ciint32_t ZipImagePatch::ReadHeader(const PatchParam ¶m, PatchHeader &header, size_t &offset) 216fb299fa2Sopenharmony_ci{ 217fb299fa2Sopenharmony_ci if (offset + PATCH_DEFLATE_MIN_HEADER_LEN > param.patchSize) { 218fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to check datalen"); 219fb299fa2Sopenharmony_ci return -1; 220fb299fa2Sopenharmony_ci } 221fb299fa2Sopenharmony_ci header.srcStart = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 222fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 223fb299fa2Sopenharmony_ci header.srcLength = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 224fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 225fb299fa2Sopenharmony_ci header.patchOffset = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 226fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 227fb299fa2Sopenharmony_ci header.expandedLen = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 228fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 229fb299fa2Sopenharmony_ci header.targetSize = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 230fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 231fb299fa2Sopenharmony_ci 232fb299fa2Sopenharmony_ci level_ = ReadLE<int32_t>(param.patch + offset); 233fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 234fb299fa2Sopenharmony_ci method_ = ReadLE<int32_t>(param.patch + offset); 235fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 236fb299fa2Sopenharmony_ci windowBits_ = ReadLE<int32_t>(param.patch + offset); 237fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 238fb299fa2Sopenharmony_ci memLevel_ = ReadLE<int32_t>(param.patch + offset); 239fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 240fb299fa2Sopenharmony_ci strategy_ = ReadLE<int32_t>(param.patch + offset); 241fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 242fb299fa2Sopenharmony_ci 243fb299fa2Sopenharmony_ci PATCH_LOGI("ZipImagePatch::ReadHeader level_:%d method_:%d windowBits_:%d memLevel_:%d strategy_:%d", 244fb299fa2Sopenharmony_ci level_, method_, windowBits_, memLevel_, strategy_); 245fb299fa2Sopenharmony_ci return 0; 246fb299fa2Sopenharmony_ci} 247fb299fa2Sopenharmony_ci 248fb299fa2Sopenharmony_cistd::unique_ptr<Hpackage::FileInfo> ZipImagePatch::GetFileInfo() const 249fb299fa2Sopenharmony_ci{ 250fb299fa2Sopenharmony_ci Hpackage::ZipFileInfo *fileInfo = new(std::nothrow) ZipFileInfo; 251fb299fa2Sopenharmony_ci if (fileInfo == nullptr) { 252fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to new file info"); 253fb299fa2Sopenharmony_ci return nullptr; 254fb299fa2Sopenharmony_ci } 255fb299fa2Sopenharmony_ci fileInfo->fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP; 256fb299fa2Sopenharmony_ci fileInfo->fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE; 257fb299fa2Sopenharmony_ci fileInfo->fileInfo.packedSize = 0; 258fb299fa2Sopenharmony_ci fileInfo->fileInfo.unpackedSize = 0; 259fb299fa2Sopenharmony_ci fileInfo->fileInfo.identity = std::to_string(g_tmpFileId++); 260fb299fa2Sopenharmony_ci fileInfo->level = level_; 261fb299fa2Sopenharmony_ci fileInfo->method = method_; 262fb299fa2Sopenharmony_ci fileInfo->windowBits = windowBits_; 263fb299fa2Sopenharmony_ci fileInfo->memLevel = memLevel_; 264fb299fa2Sopenharmony_ci fileInfo->strategy = strategy_; 265fb299fa2Sopenharmony_ci return std::unique_ptr<Hpackage::FileInfo>((FileInfo *)fileInfo); 266fb299fa2Sopenharmony_ci} 267fb299fa2Sopenharmony_ci 268fb299fa2Sopenharmony_ciint32_t Lz4ImagePatch::ReadHeader(const PatchParam ¶m, PatchHeader &header, size_t &offset) 269fb299fa2Sopenharmony_ci{ 270fb299fa2Sopenharmony_ci if (offset + PATCH_LZ4_MIN_HEADER_LEN > param.patchSize) { 271fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to check datalen"); 272fb299fa2Sopenharmony_ci return -1; 273fb299fa2Sopenharmony_ci } 274fb299fa2Sopenharmony_ci header.srcStart = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 275fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 276fb299fa2Sopenharmony_ci header.srcLength = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 277fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 278fb299fa2Sopenharmony_ci header.patchOffset = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 279fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 280fb299fa2Sopenharmony_ci header.expandedLen = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 281fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 282fb299fa2Sopenharmony_ci header.targetSize = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset)); 283fb299fa2Sopenharmony_ci offset += sizeof(uint64_t); 284fb299fa2Sopenharmony_ci 285fb299fa2Sopenharmony_ci compressionLevel_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset)); 286fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 287fb299fa2Sopenharmony_ci method_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset)); 288fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 289fb299fa2Sopenharmony_ci blockIndependence_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset)); 290fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 291fb299fa2Sopenharmony_ci contentChecksumFlag_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset)); 292fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 293fb299fa2Sopenharmony_ci blockSizeID_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset)); 294fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 295fb299fa2Sopenharmony_ci autoFlush_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset)); 296fb299fa2Sopenharmony_ci offset += sizeof(int32_t); 297fb299fa2Sopenharmony_ci PATCH_LOGI("ReadHeader BLOCK_LZ4 level_:%d method_:%d %d contentChecksumFlag_:%d blockSizeID_:%d %d", 298fb299fa2Sopenharmony_ci compressionLevel_, method_, blockIndependence_, contentChecksumFlag_, blockSizeID_, autoFlush_); 299fb299fa2Sopenharmony_ci return 0; 300fb299fa2Sopenharmony_ci} 301fb299fa2Sopenharmony_ci 302fb299fa2Sopenharmony_cistd::unique_ptr<Hpackage::FileInfo> Lz4ImagePatch::GetFileInfo() const 303fb299fa2Sopenharmony_ci{ 304fb299fa2Sopenharmony_ci Hpackage::Lz4FileInfo *fileInfo = new(std::nothrow) Lz4FileInfo; 305fb299fa2Sopenharmony_ci if (fileInfo == nullptr) { 306fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to new file info"); 307fb299fa2Sopenharmony_ci return nullptr; 308fb299fa2Sopenharmony_ci } 309fb299fa2Sopenharmony_ci fileInfo->fileInfo.packMethod = (method_ == LZ4B_MAGIC) ? PKG_COMPRESS_METHOD_LZ4_BLOCK : PKG_COMPRESS_METHOD_LZ4; 310fb299fa2Sopenharmony_ci fileInfo->fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE; 311fb299fa2Sopenharmony_ci fileInfo->fileInfo.packedSize = 0; 312fb299fa2Sopenharmony_ci fileInfo->fileInfo.unpackedSize = 0; 313fb299fa2Sopenharmony_ci fileInfo->fileInfo.identity = std::to_string(g_tmpFileId++); 314fb299fa2Sopenharmony_ci fileInfo->compressionLevel = static_cast<int8_t>(compressionLevel_); 315fb299fa2Sopenharmony_ci fileInfo->blockIndependence = static_cast<int8_t>(blockIndependence_); 316fb299fa2Sopenharmony_ci fileInfo->contentChecksumFlag = static_cast<int8_t>(contentChecksumFlag_); 317fb299fa2Sopenharmony_ci fileInfo->blockSizeID = static_cast<int8_t>(blockSizeID_); 318fb299fa2Sopenharmony_ci fileInfo->autoFlush = static_cast<int8_t>(autoFlush_); 319fb299fa2Sopenharmony_ci return std::unique_ptr<Hpackage::FileInfo>((FileInfo *)fileInfo); 320fb299fa2Sopenharmony_ci} 321fb299fa2Sopenharmony_ci 322fb299fa2Sopenharmony_ciint32_t CompressedFileRestore::Init() 323fb299fa2Sopenharmony_ci{ 324fb299fa2Sopenharmony_ci SHA256_Init(&sha256Ctx_); 325fb299fa2Sopenharmony_ci if (fileInfo_->packMethod == PKG_COMPRESS_METHOD_ZIP) { 326fb299fa2Sopenharmony_ci deflateAdapter_.reset(new ZipAdapter(writer_, 0, fileInfo_)); 327fb299fa2Sopenharmony_ci } else if (fileInfo_->packMethod == PKG_COMPRESS_METHOD_LZ4) { 328fb299fa2Sopenharmony_ci deflateAdapter_.reset(new Lz4FrameAdapter(writer_, 0, fileInfo_)); 329fb299fa2Sopenharmony_ci } else if (fileInfo_->packMethod == PKG_COMPRESS_METHOD_LZ4_BLOCK) { 330fb299fa2Sopenharmony_ci deflateAdapter_.reset(new Lz4BlockAdapter(writer_, 0, fileInfo_)); 331fb299fa2Sopenharmony_ci } 332fb299fa2Sopenharmony_ci if (deflateAdapter_ == nullptr) { 333fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to create zip adapter"); 334fb299fa2Sopenharmony_ci return -1; 335fb299fa2Sopenharmony_ci } 336fb299fa2Sopenharmony_ci return deflateAdapter_->Open(); 337fb299fa2Sopenharmony_ci} 338fb299fa2Sopenharmony_ci 339fb299fa2Sopenharmony_ciint32_t CompressedFileRestore::Write(size_t start, const BlockBuffer &buffer, size_t size) 340fb299fa2Sopenharmony_ci{ 341fb299fa2Sopenharmony_ci if (size == 0) { 342fb299fa2Sopenharmony_ci return 0; 343fb299fa2Sopenharmony_ci } 344fb299fa2Sopenharmony_ci dataSize_ += size; 345fb299fa2Sopenharmony_ci SHA256_Update(&sha256Ctx_, buffer.buffer, size); 346fb299fa2Sopenharmony_ci BlockBuffer data = { buffer.buffer, size }; 347fb299fa2Sopenharmony_ci return deflateAdapter_->WriteData(data); 348fb299fa2Sopenharmony_ci} 349fb299fa2Sopenharmony_ci 350fb299fa2Sopenharmony_ciint32_t CompressedFileRestore::CompressData(size_t &originalSize, size_t &compressSize) 351fb299fa2Sopenharmony_ci{ 352fb299fa2Sopenharmony_ci int32_t ret = deflateAdapter_->FlushData(compressSize); 353fb299fa2Sopenharmony_ci if (ret != 0) { 354fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to flush data"); 355fb299fa2Sopenharmony_ci return -1; 356fb299fa2Sopenharmony_ci } 357fb299fa2Sopenharmony_ci originalSize = dataSize_; 358fb299fa2Sopenharmony_ci 359fb299fa2Sopenharmony_ci std::vector<uint8_t> digest(SHA256_DIGEST_LENGTH); 360fb299fa2Sopenharmony_ci SHA256_Final(digest.data(), &sha256Ctx_); 361fb299fa2Sopenharmony_ci BlockBuffer buffer = { digest.data(), digest.size() }; 362fb299fa2Sopenharmony_ci std::string hexDigest = ConvertSha256Hex(buffer); 363fb299fa2Sopenharmony_ci PATCH_LOGI("CompressedFileRestore hash %zu %s ", dataSize_, hexDigest.c_str()); 364fb299fa2Sopenharmony_ci return 0; 365fb299fa2Sopenharmony_ci} 366fb299fa2Sopenharmony_ci} // namespace UpdatePatch 367