* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DIFF_PATCH_H
#define DIFF_PATCH_H
#ifdef __WIN32
#include "pkg_utils.h"
#else
#include <sys/mman.h>
#endif
#include <cstdlib>
#include <unistd.h>
#include <vector>
#include "log/log.h"
#include "patch/update_patch.h"
namespace UpdatePatch {
#ifdef __WIN32
#undef ERROR
#endif
#define PATCH_LOGE(format, ...) Logger(Updater::ERROR, (UPDATER_LOG_FILE_NAME), (__LINE__), format, ##__VA_ARGS__)
#define PATCH_DEBUG(format, ...) Logger(Updater::DEBUG, (UPDATER_LOG_FILE_NAME), (__LINE__), format, ##__VA_ARGS__)
#define PATCH_LOGI(format, ...) Logger(Updater::INFO, (UPDATER_LOG_FILE_NAME), (__LINE__), format, ##__VA_ARGS__)
#define PATCH_LOGW(format, ...) Logger(Updater::WARNING, (UPDATER_LOG_FILE_NAME), (__LINE__), format, ##__VA_ARGS__)
enum {
PATCH_SUCCESS = 0,
PATCH_INVALID_PARAM,
PATCH_NEW_FILE,
PATCH_EXCEED_LIMIT,
PATCH_INVALID_PATCH,
};
* The pkgdiff patch header looks like this:
*
* "pkgdiff0" (8) [magic number and version]
* block count (4)
* for each block:
* block type (4) [BLOCK_{NORMAL, DEFLATE, RAW, Lz4}]
* if block type == BLOCK_NORMAL:
* source start (8)
* source len (8)
* bsdiff patch offset (8) [from start of patch file]
* if block type == BLOCK_DEFLATE:
* source start (8)
* source len (8)
* bsdiff patch offset (8) [from start of patch file]
* source expanded len (8) [size of uncompressed source]
* target expected len (8) [size of uncompressed target]
* zip level (4)
* method (4)
* windowBits (4)
* memLevel (4)
* strategy (4)
* if block type == BLOCK_LZ4:
* source start (8)
* source len (8)
* bsdiff patch offset (8) [from start of patch file]
* source expanded len (8) [size of uncompressed source]
* target expected len (8) [size of uncompressed target]
* lz4 level (4)
* method (4)
* blockIndependence (4)
* contentChecksumFlag (4)
* blockSizeID (4)
* autoFlush (4)
* if block type == RAW:
* target len (4)
* data (target len)
*
*/
0 8 "BSDIFF40"
8 8 length of bzip2ed ctrl block
16 8 length of bzip2ed diff block
24 8 length of new file
*/
0 32 Header
32 40 Bzip2ed ctrl block
40 48 Bzip2ed diff block
48 56 Bzip2ed extra block
*/
#define BLOCK_NORMAL 0
#define BLOCK_GZIP 1
#define BLOCK_DEFLATE 2
#define BLOCK_RAW 3
#define BLOCK_LZ4 4
static constexpr size_t GZIP_HEADER_LEN = 10;
static constexpr size_t VERSION = 2;
static constexpr unsigned short HEADER_CRC = 0x02;
static constexpr unsigned short EXTRA_FIELD = 0x04;
static constexpr unsigned short ORIG_NAME = 0x08;
static constexpr unsigned short COMMENT = 0x10;
static constexpr unsigned short ENCRYPTED = 0x20;
static constexpr uint8_t SHIFT_RIGHT_FOUR_BITS = 4;
static constexpr size_t GZIP_FOOTER_LEN = 8;
static constexpr size_t LZ4_HEADER_LEN = 4;
static constexpr size_t IGMDIFF_LIMIT_UNIT = 10240;
static constexpr int LZ4S_MAGIC = 0x184D2204;
static constexpr int LZ4B_MAGIC = 0x184C2102;
static constexpr int GZIP_MAGIC = 0x00088b1f;
static constexpr int PATCH_NORMAL_MIN_HEADER_LEN = 24;
static constexpr int PATCH_DEFLATE_MIN_HEADER_LEN = 60;
static constexpr int PATCH_LZ4_MIN_HEADER_LEN = 64;
constexpr const char *BSDIFF_MAGIC = "BSDIFF40";
constexpr const char *PKGDIFF_MAGIC = "PKGDIFF0";
struct PatchHeader {
size_t srcStart = 0;
size_t srcLength = 0;
size_t patchOffset = 0;
size_t expandedLen = 0;
size_t targetSize = 0;
};
struct ControlData {
int64_t diffLength;
int64_t extraLength;
int64_t offsetIncrement;
uint8_t *diffNewStart;
uint8_t *diffOldStart;
uint8_t *extraNewStart;
};
struct MemMapInfo {
uint8_t *memory {};
size_t length {};
int fd {-1};
~MemMapInfo();
};
int32_t WriteDataToFile(const std::string &fileName, const std::vector<uint8_t> &data, size_t dataSize);
int32_t PatchMapFile(const std::string &fileName, MemMapInfo &info);
std::string GeneraterBufferHash(const BlockBuffer &buffer);
std::string ConvertSha256Hex(const BlockBuffer &buffer);
}
#endif