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#include "pkg_gzipfile.h" 16fb299fa2Sopenharmony_ci#include "dump.h" 17fb299fa2Sopenharmony_ci 18fb299fa2Sopenharmony_ciusing namespace std; 19fb299fa2Sopenharmony_ci 20fb299fa2Sopenharmony_cinamespace Hpackage { 21fb299fa2Sopenharmony_ci/* gzip flag byte */ 22fb299fa2Sopenharmony_ciconstexpr uint16_t HEADER_CRC = 0x02; /* bit 1 set: CRC16 for the gzip header */ 23fb299fa2Sopenharmony_ciconstexpr uint16_t EXTRA_FIELD = 0x04; /* bit 2 set: extra field present */ 24fb299fa2Sopenharmony_ciconstexpr uint16_t ORIG_NAME = 0x08; /* bit 3 set: original file name present */ 25fb299fa2Sopenharmony_ciconstexpr uint16_t COMMENT = 0x10; /* bit 4 set: file comment present */ 26fb299fa2Sopenharmony_ciconstexpr uint16_t ENCRYPTED = 0x20; /* bit 5 set: file is encrypted */ 27fb299fa2Sopenharmony_ciconstexpr int32_t DEF_MEM_LEVEL = 8; 28fb299fa2Sopenharmony_ciconstexpr uint16_t GZIP_MAGIC = 0x8b1f; 29fb299fa2Sopenharmony_ciconstexpr int32_t BUFFER_SIZE = 1024; 30fb299fa2Sopenharmony_ci#ifdef SUPPORT_EXTRA_FIELD 31fb299fa2Sopenharmony_ciconstexpr int32_t EXTRA_FIELD_LEN = 20; 32fb299fa2Sopenharmony_ci#endif 33fb299fa2Sopenharmony_ciconstexpr int32_t BLOCK_SIZE = 8; 34fb299fa2Sopenharmony_ci 35fb299fa2Sopenharmony_ci/* 36fb299fa2Sopenharmony_ci Each member has the following structure: 37fb299fa2Sopenharmony_ci +---+---+---+---+---+---+---+---+---+---+ 38fb299fa2Sopenharmony_ci |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) 39fb299fa2Sopenharmony_ci +---+---+---+---+---+---+---+---+---+---+ 40fb299fa2Sopenharmony_ci 41fb299fa2Sopenharmony_ci (if FLG.FEXTRA set) 42fb299fa2Sopenharmony_ci 43fb299fa2Sopenharmony_ci +---+---+=================================+ 44fb299fa2Sopenharmony_ci | XLEN |...XLEN bytes of "extra field"...| (more-->) 45fb299fa2Sopenharmony_ci +---+---+=================================+ 46fb299fa2Sopenharmony_ci 47fb299fa2Sopenharmony_ci (if FLG.FNAME set) 48fb299fa2Sopenharmony_ci 49fb299fa2Sopenharmony_ci +=========================================+ 50fb299fa2Sopenharmony_ci |...original file name, zero-terminated...| (more-->) 51fb299fa2Sopenharmony_ci +=========================================+ 52fb299fa2Sopenharmony_ci 53fb299fa2Sopenharmony_ci (if FLG.FCOMMENT set) 54fb299fa2Sopenharmony_ci 55fb299fa2Sopenharmony_ci +===================================+ 56fb299fa2Sopenharmony_ci |...file comment, zero-terminated...| (more-->) 57fb299fa2Sopenharmony_ci +===================================+ 58fb299fa2Sopenharmony_ci 59fb299fa2Sopenharmony_ci (if FLG.FHCRC set) 60fb299fa2Sopenharmony_ci 61fb299fa2Sopenharmony_ci +---+---+ 62fb299fa2Sopenharmony_ci | CRC16 | 63fb299fa2Sopenharmony_ci +---+---+ 64fb299fa2Sopenharmony_ci */ 65fb299fa2Sopenharmony_civoid GZipFileEntry::GetUpGradeCompInfo(size_t &offset, PkgBuffer &buffer) 66fb299fa2Sopenharmony_ci{ 67fb299fa2Sopenharmony_ci GZipHeader *header = (GZipHeader *)buffer.buffer; 68fb299fa2Sopenharmony_ci header->magic = GZIP_MAGIC; 69fb299fa2Sopenharmony_ci header->method = Z_DEFLATED; 70fb299fa2Sopenharmony_ci header->flags = 0; 71fb299fa2Sopenharmony_ci header->mtime = fileInfo_.fileInfo.modifiedTime; 72fb299fa2Sopenharmony_ci offset += sizeof(GZipHeader); 73fb299fa2Sopenharmony_ci#ifdef SUPPORT_EXTRA_FIELD 74fb299fa2Sopenharmony_ci header->flags |= EXTRA_FIELD; 75fb299fa2Sopenharmony_ci { 76fb299fa2Sopenharmony_ci WriteLE16(buffer.buffer + offset, EXTRA_FIELD_LEN); 77fb299fa2Sopenharmony_ci offset += sizeof(uint16_t) + EXTRA_FIELD_LEN; 78fb299fa2Sopenharmony_ci } 79fb299fa2Sopenharmony_ci#endif 80fb299fa2Sopenharmony_ci header->flags |= ORIG_NAME; 81fb299fa2Sopenharmony_ci { 82fb299fa2Sopenharmony_ci size_t fileNameLen = 0; 83fb299fa2Sopenharmony_ci PkgFileImpl::ConvertStringToBuffer( 84fb299fa2Sopenharmony_ci fileInfo_.fileInfo.identity, {buffer.buffer + offset, buffer.length - offset}, fileNameLen); 85fb299fa2Sopenharmony_ci offset += fileNameLen; 86fb299fa2Sopenharmony_ci buffer.buffer[offset] = 0; 87fb299fa2Sopenharmony_ci offset += 1; 88fb299fa2Sopenharmony_ci } 89fb299fa2Sopenharmony_ci#ifdef SUPPORT_EXTRA_FIELD 90fb299fa2Sopenharmony_ci header->flags |= COMMENT; 91fb299fa2Sopenharmony_ci { 92fb299fa2Sopenharmony_ci size_t fileNameLen = 0; 93fb299fa2Sopenharmony_ci PkgFileImpl::ConvertStringToBuffer( 94fb299fa2Sopenharmony_ci fileInfo_.fileInfo.identity, {buffer.buffer + offset, buffer.length - offset}, fileNameLen); 95fb299fa2Sopenharmony_ci offset += fileNameLen; 96fb299fa2Sopenharmony_ci buffer.buffer[offset] = 0; 97fb299fa2Sopenharmony_ci offset += 1; 98fb299fa2Sopenharmony_ci } 99fb299fa2Sopenharmony_ci#endif 100fb299fa2Sopenharmony_ci return ; 101fb299fa2Sopenharmony_ci} 102fb299fa2Sopenharmony_ci 103fb299fa2Sopenharmony_ciint32_t GZipFileEntry::EncodeHeader(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) 104fb299fa2Sopenharmony_ci{ 105fb299fa2Sopenharmony_ci PkgStreamPtr outStream = pkgFile_->GetPkgStream(); 106fb299fa2Sopenharmony_ci if (outStream == nullptr) { 107fb299fa2Sopenharmony_ci PKG_LOGE("Check outstream fail %s", fileInfo_.fileInfo.identity.c_str()); 108fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 109fb299fa2Sopenharmony_ci } 110fb299fa2Sopenharmony_ci size_t offset = 0; 111fb299fa2Sopenharmony_ci PkgBuffer buffer(BUFFER_SIZE); 112fb299fa2Sopenharmony_ci 113fb299fa2Sopenharmony_ci GetUpGradeCompInfo(offset, buffer); 114fb299fa2Sopenharmony_ci 115fb299fa2Sopenharmony_ci fileInfo_.fileInfo.headerOffset = startOffset; 116fb299fa2Sopenharmony_ci fileInfo_.fileInfo.dataOffset = startOffset + offset; 117fb299fa2Sopenharmony_ci int32_t ret = outStream->Write(buffer, offset, startOffset); 118fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 119fb299fa2Sopenharmony_ci PKG_LOGE("Fail write header for %s", fileInfo_.fileInfo.identity.c_str()); 120fb299fa2Sopenharmony_ci return ret; 121fb299fa2Sopenharmony_ci } 122fb299fa2Sopenharmony_ci encodeLen = offset; 123fb299fa2Sopenharmony_ci return PKG_SUCCESS; 124fb299fa2Sopenharmony_ci} 125fb299fa2Sopenharmony_ci 126fb299fa2Sopenharmony_ciint32_t GZipFileEntry::Pack(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) 127fb299fa2Sopenharmony_ci{ 128fb299fa2Sopenharmony_ci PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo); 129fb299fa2Sopenharmony_ci PkgStreamPtr outStream = pkgFile_->GetPkgStream(); 130fb299fa2Sopenharmony_ci if (fileInfo_.fileInfo.dataOffset != startOffset) { 131fb299fa2Sopenharmony_ci PKG_LOGE("start offset error for %s", fileInfo_.fileInfo.identity.c_str()); 132fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 133fb299fa2Sopenharmony_ci } 134fb299fa2Sopenharmony_ci if (algorithm == nullptr || outStream == nullptr || inStream == nullptr) { 135fb299fa2Sopenharmony_ci PKG_LOGE("outStream or inStream null for %s", fileInfo_.fileInfo.identity.c_str()); 136fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 137fb299fa2Sopenharmony_ci } 138fb299fa2Sopenharmony_ci fileInfo_.fileInfo.dataOffset = startOffset; 139fb299fa2Sopenharmony_ci PkgAlgorithmContext context = { 140fb299fa2Sopenharmony_ci {0, startOffset}, 141fb299fa2Sopenharmony_ci {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize}, 142fb299fa2Sopenharmony_ci 0, fileInfo_.fileInfo.digestMethod 143fb299fa2Sopenharmony_ci }; 144fb299fa2Sopenharmony_ci int32_t ret = algorithm->Pack(inStream, outStream, context); 145fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 146fb299fa2Sopenharmony_ci PKG_LOGE("Fail Compress for %s", fileInfo_.fileInfo.identity.c_str()); 147fb299fa2Sopenharmony_ci return ret; 148fb299fa2Sopenharmony_ci } 149fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packedSize = context.packedSize; 150fb299fa2Sopenharmony_ci 151fb299fa2Sopenharmony_ci /* 152fb299fa2Sopenharmony_ci 0 1 2 3 4 5 6 7 153fb299fa2Sopenharmony_ci +---+---+---+---+---+---+---+---+ 154fb299fa2Sopenharmony_ci | CRC32 | ISIZE | 155fb299fa2Sopenharmony_ci +---+---+---+---+---+---+---+---+ 156fb299fa2Sopenharmony_ci */ 157fb299fa2Sopenharmony_ci PkgBuffer buffer(BLOCK_SIZE); 158fb299fa2Sopenharmony_ci WriteLE32(buffer.buffer, context.crc); 159fb299fa2Sopenharmony_ci WriteLE32(buffer.buffer + sizeof(uint32_t), fileInfo_.fileInfo.unpackedSize); 160fb299fa2Sopenharmony_ci ret = outStream->Write(buffer, BLOCK_SIZE, fileInfo_.fileInfo.dataOffset + fileInfo_.fileInfo.packedSize); 161fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 162fb299fa2Sopenharmony_ci PKG_LOGE("Fail write header for %s", fileInfo_.fileInfo.identity.c_str()); 163fb299fa2Sopenharmony_ci return ret; 164fb299fa2Sopenharmony_ci } 165fb299fa2Sopenharmony_ci encodeLen = fileInfo_.fileInfo.packedSize + BLOCK_SIZE; 166fb299fa2Sopenharmony_ci PKG_LOGI("Pack packedSize:%zu unpackedSize: %zu offset: %zu %zu", fileInfo_.fileInfo.packedSize, 167fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize, fileInfo_.fileInfo.headerOffset, fileInfo_.fileInfo.dataOffset); 168fb299fa2Sopenharmony_ci return PKG_SUCCESS; 169fb299fa2Sopenharmony_ci} 170fb299fa2Sopenharmony_ci 171fb299fa2Sopenharmony_ciint32_t GZipFileEntry::CheckFileInfo(PkgAlgorithmContext context, PkgStreamPtr inStream) 172fb299fa2Sopenharmony_ci{ 173fb299fa2Sopenharmony_ci size_t readLen = 0; 174fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packedSize = context.packedSize; 175fb299fa2Sopenharmony_ci PkgBuffer buffer(BLOCK_SIZE); // Read last 8 bytes at the end of package 176fb299fa2Sopenharmony_ci int32_t ret = inStream->Read(buffer, context.packedSize + fileInfo_.fileInfo.dataOffset, BLOCK_SIZE, readLen); 177fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 178fb299fa2Sopenharmony_ci PKG_LOGE("Fail to read file %s", inStream->GetFileName().c_str()); 179fb299fa2Sopenharmony_ci return ret; 180fb299fa2Sopenharmony_ci } 181fb299fa2Sopenharmony_ci crc32_ = ReadLE32(buffer.buffer); 182fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize = ReadLE32(buffer.buffer + sizeof(uint32_t)); 183fb299fa2Sopenharmony_ci if (crc32_ != context.crc) { 184fb299fa2Sopenharmony_ci PKG_LOGE("Crc error %u %u", crc32_, context.crc); 185fb299fa2Sopenharmony_ci return PKG_VERIFY_FAIL; 186fb299fa2Sopenharmony_ci } 187fb299fa2Sopenharmony_ci 188fb299fa2Sopenharmony_ci if (fileInfo_.fileInfo.unpackedSize != context.unpackedSize) { 189fb299fa2Sopenharmony_ci PKG_LOGE("Crc error %u %u", crc32_, context.crc); 190fb299fa2Sopenharmony_ci return PKG_VERIFY_FAIL; 191fb299fa2Sopenharmony_ci } 192fb299fa2Sopenharmony_ci return PKG_SUCCESS; 193fb299fa2Sopenharmony_ci} 194fb299fa2Sopenharmony_ci 195fb299fa2Sopenharmony_ciint32_t GZipFileEntry::Unpack(PkgStreamPtr outStream) 196fb299fa2Sopenharmony_ci{ 197fb299fa2Sopenharmony_ci PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo); 198fb299fa2Sopenharmony_ci if (algorithm == nullptr) { 199fb299fa2Sopenharmony_ci PKG_LOGE("can not algorithm for %s", fileInfo_.fileInfo.identity.c_str()); 200fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 201fb299fa2Sopenharmony_ci } 202fb299fa2Sopenharmony_ci 203fb299fa2Sopenharmony_ci PKG_LOGI("packedSize: %zu unpackedSize: %zu offset header: %zu data: %zu", fileInfo_.fileInfo.packedSize, 204fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize, fileInfo_.fileInfo.headerOffset, fileInfo_.fileInfo.dataOffset); 205fb299fa2Sopenharmony_ci 206fb299fa2Sopenharmony_ci PkgStreamPtr inStream = pkgFile_->GetPkgStream(); 207fb299fa2Sopenharmony_ci if (outStream == nullptr || inStream == nullptr) { 208fb299fa2Sopenharmony_ci PKG_LOGE("outStream or inStream null for %s", fileInfo_.fileInfo.identity.c_str()); 209fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 210fb299fa2Sopenharmony_ci } 211fb299fa2Sopenharmony_ci 212fb299fa2Sopenharmony_ci PkgAlgorithmContext context = { 213fb299fa2Sopenharmony_ci {fileInfo_.fileInfo.dataOffset, 0}, 214fb299fa2Sopenharmony_ci {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize}, 215fb299fa2Sopenharmony_ci 0, fileInfo_.fileInfo.digestMethod 216fb299fa2Sopenharmony_ci }; 217fb299fa2Sopenharmony_ci int32_t ret = algorithm->Unpack(inStream, outStream, context); 218fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 219fb299fa2Sopenharmony_ci PKG_LOGE("Fail Decompress for %s", fileInfo_.fileInfo.identity.c_str()); 220fb299fa2Sopenharmony_ci return ret; 221fb299fa2Sopenharmony_ci } 222fb299fa2Sopenharmony_ci 223fb299fa2Sopenharmony_ci ret = CheckFileInfo(context, inStream); 224fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 225fb299fa2Sopenharmony_ci PKG_LOGE("unpack failed ret is %d", ret); 226fb299fa2Sopenharmony_ci return ret; 227fb299fa2Sopenharmony_ci } 228fb299fa2Sopenharmony_ci 229fb299fa2Sopenharmony_ci PKG_LOGI("packedSize: %zu unpackedSize: %zu offset header: %zu data: %zu", fileInfo_.fileInfo.packedSize, 230fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize, fileInfo_.fileInfo.headerOffset, fileInfo_.fileInfo.dataOffset); 231fb299fa2Sopenharmony_ci outStream->Flush(fileInfo_.fileInfo.unpackedSize); 232fb299fa2Sopenharmony_ci algorithm->UpdateFileInfo(&fileInfo_.fileInfo); 233fb299fa2Sopenharmony_ci return PKG_SUCCESS; 234fb299fa2Sopenharmony_ci} 235fb299fa2Sopenharmony_ci 236fb299fa2Sopenharmony_civoid GZipFileEntry::DecodeHeaderCalOffset(uint8_t flags, const PkgBuffer &buffer, size_t &offset, 237fb299fa2Sopenharmony_ci std::string &fileName) const 238fb299fa2Sopenharmony_ci{ 239fb299fa2Sopenharmony_ci if (flags & EXTRA_FIELD) { 240fb299fa2Sopenharmony_ci uint16_t extLen = ReadLE16(buffer.buffer + offset); 241fb299fa2Sopenharmony_ci offset += sizeof(uint16_t) + extLen; 242fb299fa2Sopenharmony_ci } 243fb299fa2Sopenharmony_ci if ((buffer.length > offset) && (flags & ORIG_NAME)) { 244fb299fa2Sopenharmony_ci PkgFileImpl::ConvertBufferToString(fileName, {buffer.buffer + offset, buffer.length - offset}); 245fb299fa2Sopenharmony_ci offset += fileName.size() + 1; 246fb299fa2Sopenharmony_ci } 247fb299fa2Sopenharmony_ci if ((buffer.length > offset) && (flags & COMMENT)) { 248fb299fa2Sopenharmony_ci std::string comment; 249fb299fa2Sopenharmony_ci PkgFileImpl::ConvertBufferToString(comment, {buffer.buffer + offset, buffer.length - offset}); 250fb299fa2Sopenharmony_ci offset += comment.size() + 1; 251fb299fa2Sopenharmony_ci } 252fb299fa2Sopenharmony_ci if (flags & HEADER_CRC) { // Skip CRC 253fb299fa2Sopenharmony_ci offset += sizeof(uint16_t); 254fb299fa2Sopenharmony_ci } 255fb299fa2Sopenharmony_ci return; 256fb299fa2Sopenharmony_ci} 257fb299fa2Sopenharmony_ci 258fb299fa2Sopenharmony_ciint32_t GZipFileEntry::DecodeHeader(PkgBuffer &buffer, size_t headerOffset, size_t dataOffset, 259fb299fa2Sopenharmony_ci size_t &decodeLen) 260fb299fa2Sopenharmony_ci{ 261fb299fa2Sopenharmony_ci Updater::UPDATER_INIT_RECORD; 262fb299fa2Sopenharmony_ci PkgStreamPtr inStream = pkgFile_->GetPkgStream(); 263fb299fa2Sopenharmony_ci if (inStream == nullptr || buffer.buffer == nullptr) { 264fb299fa2Sopenharmony_ci PKG_LOGE("outStream or inStream null for %s", fileInfo_.fileInfo.identity.c_str()); 265fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(PKG_INVALID_PARAM); 266fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 267fb299fa2Sopenharmony_ci } 268fb299fa2Sopenharmony_ci size_t offset = sizeof(GZipHeader); 269fb299fa2Sopenharmony_ci 270fb299fa2Sopenharmony_ci uint8_t flags = *(buffer.buffer + offsetof(GZipHeader, flags)); 271fb299fa2Sopenharmony_ci 272fb299fa2Sopenharmony_ci DecodeHeaderCalOffset(flags, buffer, offset, fileName_); 273fb299fa2Sopenharmony_ci if (fileName_.empty()) { 274fb299fa2Sopenharmony_ci fileInfo_.fileInfo.identity = "gzip_"; 275fb299fa2Sopenharmony_ci fileInfo_.fileInfo.identity.append(std::to_string(nodeId_)); 276fb299fa2Sopenharmony_ci fileName_ = fileInfo_.fileInfo.identity; 277fb299fa2Sopenharmony_ci } else { 278fb299fa2Sopenharmony_ci fileInfo_.fileInfo.identity = fileName_; 279fb299fa2Sopenharmony_ci } 280fb299fa2Sopenharmony_ci fileInfo_.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC; 281fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packMethod = PKG_COMPRESS_METHOD_GZIP; 282fb299fa2Sopenharmony_ci fileInfo_.level = Z_BEST_COMPRESSION; 283fb299fa2Sopenharmony_ci fileInfo_.method = Z_DEFLATED; 284fb299fa2Sopenharmony_ci fileInfo_.windowBits = -MAX_WBITS; 285fb299fa2Sopenharmony_ci fileInfo_.memLevel = DEF_MEM_LEVEL; 286fb299fa2Sopenharmony_ci fileInfo_.strategy = Z_DEFAULT_STRATEGY; 287fb299fa2Sopenharmony_ci 288fb299fa2Sopenharmony_ci fileInfo_.fileInfo.headerOffset = headerOffset; 289fb299fa2Sopenharmony_ci fileInfo_.fileInfo.dataOffset = headerOffset + offset; 290fb299fa2Sopenharmony_ci // Read data length here. 291fb299fa2Sopenharmony_ci // The length read here maybe incorrect, so should adjust it 292fb299fa2Sopenharmony_ci // when unpack. 293fb299fa2Sopenharmony_ci size_t readLen = 0; 294fb299fa2Sopenharmony_ci size_t blockOffset = inStream->GetFileLength() - BLOCK_SIZE; 295fb299fa2Sopenharmony_ci int32_t ret = inStream->Read(buffer, blockOffset, buffer.length, readLen); 296fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 297fb299fa2Sopenharmony_ci PKG_LOGE("Fail to read file %s", inStream->GetFileName().c_str()); 298fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(ret); 299fb299fa2Sopenharmony_ci return ret; 300fb299fa2Sopenharmony_ci } 301fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize = ReadLE32(buffer.buffer + sizeof(uint32_t)); 302fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packedSize = blockOffset - fileInfo_.fileInfo.dataOffset; 303fb299fa2Sopenharmony_ci PKG_LOGI("GZipFileEntry::DecodeHeader dataOffset %zu, packedSize: %zu %zu", fileInfo_.fileInfo.dataOffset, 304fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize); 305fb299fa2Sopenharmony_ci decodeLen = offset; 306fb299fa2Sopenharmony_ci return PKG_SUCCESS; 307fb299fa2Sopenharmony_ci} 308fb299fa2Sopenharmony_ci 309fb299fa2Sopenharmony_ciint32_t GZipPkgFile::AddEntry(const PkgManager::FileInfoPtr file, const PkgStreamPtr inStream) 310fb299fa2Sopenharmony_ci{ 311fb299fa2Sopenharmony_ci if (file == nullptr || inStream == nullptr) { 312fb299fa2Sopenharmony_ci PKG_LOGE("Fail to check input param"); 313fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 314fb299fa2Sopenharmony_ci } 315fb299fa2Sopenharmony_ci if (!CheckState({PKG_FILE_STATE_IDLE, PKG_FILE_STATE_WORKING}, PKG_FILE_STATE_CLOSE)) { 316fb299fa2Sopenharmony_ci PKG_LOGE("error state curr %d ", state_); 317fb299fa2Sopenharmony_ci return PKG_INVALID_STATE; 318fb299fa2Sopenharmony_ci } 319fb299fa2Sopenharmony_ci PKG_LOGI("Add file %s to package", file->identity.c_str()); 320fb299fa2Sopenharmony_ci 321fb299fa2Sopenharmony_ci GZipFileEntry *entry = static_cast<GZipFileEntry *>(AddPkgEntry(file->identity)); 322fb299fa2Sopenharmony_ci if (entry == nullptr) { 323fb299fa2Sopenharmony_ci PKG_LOGE("Fail create pkg node for %s", file->identity.c_str()); 324fb299fa2Sopenharmony_ci return PKG_NONE_MEMORY; 325fb299fa2Sopenharmony_ci } 326fb299fa2Sopenharmony_ci int32_t ret = entry->Init(file, inStream); 327fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 328fb299fa2Sopenharmony_ci PKG_LOGE("Fail init entry for %s", file->identity.c_str()); 329fb299fa2Sopenharmony_ci return ret; 330fb299fa2Sopenharmony_ci } 331fb299fa2Sopenharmony_ci 332fb299fa2Sopenharmony_ci size_t encodeLen = 0; 333fb299fa2Sopenharmony_ci ret = entry->EncodeHeader(inStream, currentOffset_, encodeLen); 334fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 335fb299fa2Sopenharmony_ci PKG_LOGE("Fail encode header for %s", file->identity.c_str()); 336fb299fa2Sopenharmony_ci return ret; 337fb299fa2Sopenharmony_ci } 338fb299fa2Sopenharmony_ci currentOffset_ += encodeLen; 339fb299fa2Sopenharmony_ci ret = entry->Pack(inStream, currentOffset_, encodeLen); 340fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 341fb299fa2Sopenharmony_ci PKG_LOGE("Fail Pack for %s", file->identity.c_str()); 342fb299fa2Sopenharmony_ci return ret; 343fb299fa2Sopenharmony_ci } 344fb299fa2Sopenharmony_ci currentOffset_ += encodeLen; 345fb299fa2Sopenharmony_ci pkgStream_->Flush(currentOffset_); 346fb299fa2Sopenharmony_ci return PKG_SUCCESS; 347fb299fa2Sopenharmony_ci} 348fb299fa2Sopenharmony_ci 349fb299fa2Sopenharmony_ciint32_t GZipPkgFile::SavePackage(size_t &offset) 350fb299fa2Sopenharmony_ci{ 351fb299fa2Sopenharmony_ci AddSignData(pkgInfo_.digestMethod, currentOffset_, offset); 352fb299fa2Sopenharmony_ci return PKG_SUCCESS; 353fb299fa2Sopenharmony_ci} 354fb299fa2Sopenharmony_ci 355fb299fa2Sopenharmony_ciint32_t GZipPkgFile::LoadPackage(std::vector<std::string> &fileNames, VerifyFunction verifier) 356fb299fa2Sopenharmony_ci{ 357fb299fa2Sopenharmony_ci UNUSED(verifier); 358fb299fa2Sopenharmony_ci if (!CheckState({ PKG_FILE_STATE_IDLE }, PKG_FILE_STATE_WORKING)) { 359fb299fa2Sopenharmony_ci PKG_LOGE("error state curr %d ", state_); 360fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(PKG_INVALID_STATE); 361fb299fa2Sopenharmony_ci return PKG_INVALID_STATE; 362fb299fa2Sopenharmony_ci } 363fb299fa2Sopenharmony_ci PKG_LOGI("LoadPackage %s ", pkgStream_->GetFileName().c_str()); 364fb299fa2Sopenharmony_ci size_t srcOffset = 0; 365fb299fa2Sopenharmony_ci size_t readLen = 0; 366fb299fa2Sopenharmony_ci PkgBuffer buffer(nullptr, BUFFER_SIZE); 367fb299fa2Sopenharmony_ci int32_t ret = pkgStream_->Read(buffer, srcOffset, buffer.length, readLen); 368fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 369fb299fa2Sopenharmony_ci PKG_LOGE("Fail to read file %s", pkgStream_->GetFileName().c_str()); 370fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(ret); 371fb299fa2Sopenharmony_ci return ret; 372fb299fa2Sopenharmony_ci } 373fb299fa2Sopenharmony_ci 374fb299fa2Sopenharmony_ci GZipHeader *header = (GZipHeader *)buffer.buffer; 375fb299fa2Sopenharmony_ci // Check magic number 376fb299fa2Sopenharmony_ci if (header->magic != GZIP_MAGIC) { 377fb299fa2Sopenharmony_ci PKG_LOGE("Invalid gzip file %s", pkgStream_->GetFileName().c_str()); 378fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(PKG_INVALID_STATE); 379fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 380fb299fa2Sopenharmony_ci } 381fb299fa2Sopenharmony_ci // Does not support encryption 382fb299fa2Sopenharmony_ci if ((header->flags & ENCRYPTED) != 0) { 383fb299fa2Sopenharmony_ci PKG_LOGE("Not support encrypted "); 384fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(PKG_INVALID_STATE); 385fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 386fb299fa2Sopenharmony_ci } 387fb299fa2Sopenharmony_ci 388fb299fa2Sopenharmony_ci GZipFileEntry *entry = new GZipFileEntry(this, nodeId_++); 389fb299fa2Sopenharmony_ci if (entry == nullptr) { 390fb299fa2Sopenharmony_ci PKG_LOGE("Fail create gzip node for %s", pkgStream_->GetFileName().c_str()); 391fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(PKG_INVALID_STATE); 392fb299fa2Sopenharmony_ci return PKG_LZ4_FINISH; 393fb299fa2Sopenharmony_ci } 394fb299fa2Sopenharmony_ci ret = entry->DecodeHeader(buffer, srcOffset, srcOffset, readLen); 395fb299fa2Sopenharmony_ci srcOffset += readLen; 396fb299fa2Sopenharmony_ci 397fb299fa2Sopenharmony_ci // Save entry 398fb299fa2Sopenharmony_ci pkgEntryMapId_.insert(std::pair<uint32_t, PkgEntryPtr>(entry->GetNodeId(), entry)); 399fb299fa2Sopenharmony_ci pkgEntryMapFileName_.insert(std::pair<std::string, PkgEntryPtr>(entry->GetFileName(), entry)); 400fb299fa2Sopenharmony_ci fileNames.push_back(entry->GetFileName()); 401fb299fa2Sopenharmony_ci return ret; 402fb299fa2Sopenharmony_ci} 403fb299fa2Sopenharmony_ci} // namespace Hpackage 404