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#ifndef DIFF_PATCH_H 17fb299fa2Sopenharmony_ci#define DIFF_PATCH_H 18fb299fa2Sopenharmony_ci 19fb299fa2Sopenharmony_ci#ifdef __WIN32 20fb299fa2Sopenharmony_ci#include "pkg_utils.h" 21fb299fa2Sopenharmony_ci#else 22fb299fa2Sopenharmony_ci#include <sys/mman.h> 23fb299fa2Sopenharmony_ci#endif 24fb299fa2Sopenharmony_ci#include <cstdlib> 25fb299fa2Sopenharmony_ci#include <unistd.h> 26fb299fa2Sopenharmony_ci#include <vector> 27fb299fa2Sopenharmony_ci#include "log/log.h" 28fb299fa2Sopenharmony_ci#include "patch/update_patch.h" 29fb299fa2Sopenharmony_ci 30fb299fa2Sopenharmony_cinamespace UpdatePatch { 31fb299fa2Sopenharmony_ci#ifdef __WIN32 32fb299fa2Sopenharmony_ci#undef ERROR 33fb299fa2Sopenharmony_ci#endif 34fb299fa2Sopenharmony_ci 35fb299fa2Sopenharmony_ci#define PATCH_LOGE(format, ...) Logger(Updater::ERROR, (UPDATER_LOG_FILE_NAME), (__LINE__), format, ##__VA_ARGS__) 36fb299fa2Sopenharmony_ci#define PATCH_DEBUG(format, ...) Logger(Updater::DEBUG, (UPDATER_LOG_FILE_NAME), (__LINE__), format, ##__VA_ARGS__) 37fb299fa2Sopenharmony_ci#define PATCH_LOGI(format, ...) Logger(Updater::INFO, (UPDATER_LOG_FILE_NAME), (__LINE__), format, ##__VA_ARGS__) 38fb299fa2Sopenharmony_ci#define PATCH_LOGW(format, ...) Logger(Updater::WARNING, (UPDATER_LOG_FILE_NAME), (__LINE__), format, ##__VA_ARGS__) 39fb299fa2Sopenharmony_ci 40fb299fa2Sopenharmony_cienum { 41fb299fa2Sopenharmony_ci PATCH_SUCCESS = 0, 42fb299fa2Sopenharmony_ci PATCH_INVALID_PARAM, 43fb299fa2Sopenharmony_ci PATCH_NEW_FILE, 44fb299fa2Sopenharmony_ci PATCH_EXCEED_LIMIT, 45fb299fa2Sopenharmony_ci PATCH_INVALID_PATCH, 46fb299fa2Sopenharmony_ci}; 47fb299fa2Sopenharmony_ci 48fb299fa2Sopenharmony_ci/* 49fb299fa2Sopenharmony_ci * The pkgdiff patch header looks like this: 50fb299fa2Sopenharmony_ci * 51fb299fa2Sopenharmony_ci * "pkgdiff0" (8) [magic number and version] 52fb299fa2Sopenharmony_ci * block count (4) 53fb299fa2Sopenharmony_ci * for each block: 54fb299fa2Sopenharmony_ci * block type (4) [BLOCK_{NORMAL, DEFLATE, RAW, Lz4}] 55fb299fa2Sopenharmony_ci * if block type == BLOCK_NORMAL: 56fb299fa2Sopenharmony_ci * source start (8) 57fb299fa2Sopenharmony_ci * source len (8) 58fb299fa2Sopenharmony_ci * bsdiff patch offset (8) [from start of patch file] 59fb299fa2Sopenharmony_ci * if block type == BLOCK_DEFLATE: 60fb299fa2Sopenharmony_ci * source start (8) 61fb299fa2Sopenharmony_ci * source len (8) 62fb299fa2Sopenharmony_ci * bsdiff patch offset (8) [from start of patch file] 63fb299fa2Sopenharmony_ci * source expanded len (8) [size of uncompressed source] 64fb299fa2Sopenharmony_ci * target expected len (8) [size of uncompressed target] 65fb299fa2Sopenharmony_ci * zip level (4) 66fb299fa2Sopenharmony_ci * method (4) 67fb299fa2Sopenharmony_ci * windowBits (4) 68fb299fa2Sopenharmony_ci * memLevel (4) 69fb299fa2Sopenharmony_ci * strategy (4) 70fb299fa2Sopenharmony_ci * if block type == BLOCK_LZ4: 71fb299fa2Sopenharmony_ci * source start (8) 72fb299fa2Sopenharmony_ci * source len (8) 73fb299fa2Sopenharmony_ci * bsdiff patch offset (8) [from start of patch file] 74fb299fa2Sopenharmony_ci * source expanded len (8) [size of uncompressed source] 75fb299fa2Sopenharmony_ci * target expected len (8) [size of uncompressed target] 76fb299fa2Sopenharmony_ci * lz4 level (4) 77fb299fa2Sopenharmony_ci * method (4) 78fb299fa2Sopenharmony_ci * blockIndependence (4) 79fb299fa2Sopenharmony_ci * contentChecksumFlag (4) 80fb299fa2Sopenharmony_ci * blockSizeID (4) 81fb299fa2Sopenharmony_ci * autoFlush (4) 82fb299fa2Sopenharmony_ci * if block type == RAW: 83fb299fa2Sopenharmony_ci * target len (4) 84fb299fa2Sopenharmony_ci * data (target len) 85fb299fa2Sopenharmony_ci * 86fb299fa2Sopenharmony_ci */ 87fb299fa2Sopenharmony_ci 88fb299fa2Sopenharmony_ci/* Header is 89fb299fa2Sopenharmony_ci 0 8 "BSDIFF40" 90fb299fa2Sopenharmony_ci 8 8 length of bzip2ed ctrl block 91fb299fa2Sopenharmony_ci 16 8 length of bzip2ed diff block 92fb299fa2Sopenharmony_ci 24 8 length of new file 93fb299fa2Sopenharmony_ci*/ 94fb299fa2Sopenharmony_ci/* File is 95fb299fa2Sopenharmony_ci 0 32 Header 96fb299fa2Sopenharmony_ci 32 40 Bzip2ed ctrl block 97fb299fa2Sopenharmony_ci 40 48 Bzip2ed diff block 98fb299fa2Sopenharmony_ci 48 56 Bzip2ed extra block 99fb299fa2Sopenharmony_ci*/ 100fb299fa2Sopenharmony_ci 101fb299fa2Sopenharmony_ci// patch block types 102fb299fa2Sopenharmony_ci#define BLOCK_NORMAL 0 103fb299fa2Sopenharmony_ci#define BLOCK_GZIP 1 104fb299fa2Sopenharmony_ci#define BLOCK_DEFLATE 2 105fb299fa2Sopenharmony_ci#define BLOCK_RAW 3 106fb299fa2Sopenharmony_ci#define BLOCK_LZ4 4 107fb299fa2Sopenharmony_ci 108fb299fa2Sopenharmony_cistatic constexpr size_t GZIP_HEADER_LEN = 10; 109fb299fa2Sopenharmony_cistatic constexpr size_t VERSION = 2; 110fb299fa2Sopenharmony_cistatic constexpr unsigned short HEADER_CRC = 0x02; /* bit 1 set: CRC16 for the gzip header */ 111fb299fa2Sopenharmony_cistatic constexpr unsigned short EXTRA_FIELD = 0x04; /* bit 2 set: extra field present */ 112fb299fa2Sopenharmony_cistatic constexpr unsigned short ORIG_NAME = 0x08; /* bit 3 set: original file name present */ 113fb299fa2Sopenharmony_cistatic constexpr unsigned short COMMENT = 0x10; /* bit 4 set: file comment present */ 114fb299fa2Sopenharmony_cistatic constexpr unsigned short ENCRYPTED = 0x20; /* bit 5 set: file is encrypted */ 115fb299fa2Sopenharmony_cistatic constexpr uint8_t SHIFT_RIGHT_FOUR_BITS = 4; 116fb299fa2Sopenharmony_ci 117fb299fa2Sopenharmony_ci// The gzip footer size really is fixed. 118fb299fa2Sopenharmony_cistatic constexpr size_t GZIP_FOOTER_LEN = 8; 119fb299fa2Sopenharmony_cistatic constexpr size_t LZ4_HEADER_LEN = 4; 120fb299fa2Sopenharmony_cistatic constexpr size_t IGMDIFF_LIMIT_UNIT = 10240; 121fb299fa2Sopenharmony_ci 122fb299fa2Sopenharmony_cistatic constexpr int LZ4S_MAGIC = 0x184D2204; 123fb299fa2Sopenharmony_cistatic constexpr int LZ4B_MAGIC = 0x184C2102; 124fb299fa2Sopenharmony_cistatic constexpr int GZIP_MAGIC = 0x00088b1f; 125fb299fa2Sopenharmony_ci 126fb299fa2Sopenharmony_cistatic constexpr int PATCH_NORMAL_MIN_HEADER_LEN = 24; 127fb299fa2Sopenharmony_cistatic constexpr int PATCH_DEFLATE_MIN_HEADER_LEN = 60; 128fb299fa2Sopenharmony_cistatic constexpr int PATCH_LZ4_MIN_HEADER_LEN = 64; 129fb299fa2Sopenharmony_ci 130fb299fa2Sopenharmony_ciconstexpr const char *BSDIFF_MAGIC = "BSDIFF40"; 131fb299fa2Sopenharmony_ciconstexpr const char *PKGDIFF_MAGIC = "PKGDIFF0"; 132fb299fa2Sopenharmony_ci 133fb299fa2Sopenharmony_cistruct PatchHeader { 134fb299fa2Sopenharmony_ci size_t srcStart = 0; 135fb299fa2Sopenharmony_ci size_t srcLength = 0; 136fb299fa2Sopenharmony_ci size_t patchOffset = 0; 137fb299fa2Sopenharmony_ci size_t expandedLen = 0; 138fb299fa2Sopenharmony_ci size_t targetSize = 0; 139fb299fa2Sopenharmony_ci}; 140fb299fa2Sopenharmony_ci 141fb299fa2Sopenharmony_cistruct ControlData { 142fb299fa2Sopenharmony_ci int64_t diffLength; 143fb299fa2Sopenharmony_ci int64_t extraLength; 144fb299fa2Sopenharmony_ci int64_t offsetIncrement; 145fb299fa2Sopenharmony_ci uint8_t *diffNewStart; 146fb299fa2Sopenharmony_ci uint8_t *diffOldStart; 147fb299fa2Sopenharmony_ci uint8_t *extraNewStart; 148fb299fa2Sopenharmony_ci}; 149fb299fa2Sopenharmony_ci 150fb299fa2Sopenharmony_cistruct MemMapInfo { 151fb299fa2Sopenharmony_ci uint8_t *memory {}; 152fb299fa2Sopenharmony_ci size_t length {}; 153fb299fa2Sopenharmony_ci int fd {-1}; 154fb299fa2Sopenharmony_ci ~MemMapInfo() 155fb299fa2Sopenharmony_ci { 156fb299fa2Sopenharmony_ci if (memory != nullptr) { 157fb299fa2Sopenharmony_ci munmap(memory, length); 158fb299fa2Sopenharmony_ci } 159fb299fa2Sopenharmony_ci memory = nullptr; 160fb299fa2Sopenharmony_ci if (fd != -1) { 161fb299fa2Sopenharmony_ci close(fd); 162fb299fa2Sopenharmony_ci fd = -1; 163fb299fa2Sopenharmony_ci } 164fb299fa2Sopenharmony_ci } 165fb299fa2Sopenharmony_ci}; 166fb299fa2Sopenharmony_ci 167fb299fa2Sopenharmony_ciint32_t WriteDataToFile(const std::string &fileName, const std::vector<uint8_t> &data, size_t dataSize); 168fb299fa2Sopenharmony_ciint32_t PatchMapFile(const std::string &fileName, MemMapInfo &info); 169fb299fa2Sopenharmony_cistd::string GeneraterBufferHash(const BlockBuffer &buffer); 170fb299fa2Sopenharmony_cistd::string ConvertSha256Hex(const BlockBuffer &buffer); 171fb299fa2Sopenharmony_ci} // namespace UpdatePatch 172fb299fa2Sopenharmony_ci#endif // DIFF_PATCH_H