1/*
2 * Copyright (c) 2021 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
16#ifndef IMAGE_PATCH_H
17#define IMAGE_PATCH_H
18
19#include <sys/types.h>
20#include "deflate_adapter.h"
21#include "diffpatch.h"
22#include "openssl/sha.h"
23#include "package/pkg_manager.h"
24#include "securec.h"
25
26namespace UpdatePatch {
27class ImagePatch {
28public:
29    explicit ImagePatch(UpdatePatchWriterPtr writer) : writer_(writer) {}
30    virtual ~ImagePatch() = default;
31
32    virtual int32_t ApplyImagePatch(const PatchParam &param, size_t &startOffset) = 0;
33
34    template<typename T>
35    static T ReadLE(const uint8_t *address)
36    {
37        T result;
38        errno_t ret = memcpy_s(&result, sizeof(result), address, sizeof(T));
39        if (ret != EOK) {
40            // only warning no need to return invalid value
41            PATCH_LOGE("Failed to memcpy");
42        }
43        return result;
44    }
45protected:
46    UpdatePatchWriterPtr writer_ {nullptr};
47};
48
49class RowImagePatch : public ImagePatch {
50public:
51    explicit RowImagePatch(UpdatePatchWriterPtr writer) : ImagePatch(writer) {}
52    ~RowImagePatch() override {}
53
54    int32_t ApplyImagePatch(const PatchParam &param, size_t &startOffset) override;
55};
56
57class NormalImagePatch : public ImagePatch {
58public:
59    explicit NormalImagePatch(UpdatePatchWriterPtr writer) : ImagePatch(writer) {}
60    ~NormalImagePatch() override {}
61
62    int32_t ApplyImagePatch(const PatchParam &param, size_t &startOffset)  override;
63};
64
65class CompressedImagePatch : public ImagePatch {
66public:
67    CompressedImagePatch(UpdatePatchWriterPtr writer, const std::vector<uint8_t> &bonusData)
68        : ImagePatch(writer), bonusData_(bonusData) {}
69    ~CompressedImagePatch() override {}
70
71    int32_t ApplyImagePatch(const PatchParam &param, size_t &startOffset) override;
72protected:
73    virtual int32_t ReadHeader(const PatchParam &param, PatchHeader &header, size_t &offset) = 0;
74    virtual std::unique_ptr<Hpackage::FileInfo> GetFileInfo() const = 0;
75    int32_t StartReadHeader(const PatchParam &param, PatchHeader &header, size_t &offset);
76    int32_t DecompressData(Hpackage::PkgManager::PkgManagerPtr &pkgManager, Hpackage::PkgBuffer buffer,
77        Hpackage::PkgManager::StreamPtr &stream, bool memory, size_t expandedLen) const;
78
79    std::vector<uint8_t> bonusData_ {};
80};
81
82class ZipImagePatch : public CompressedImagePatch {
83public:
84    ZipImagePatch(UpdatePatchWriterPtr writer, const std::vector<uint8_t> &bonusData)
85        : CompressedImagePatch(writer, bonusData) {}
86    ~ZipImagePatch() override {}
87
88protected:
89    int32_t ReadHeader(const PatchParam &param, PatchHeader &header, size_t &offset) override;
90    std::unique_ptr<Hpackage::FileInfo> GetFileInfo() const override;
91
92    int32_t method_ {0};
93    int32_t level_ {0};
94    int32_t windowBits_ {0};
95    int32_t memLevel_ {0};
96    int32_t strategy_ {0};
97};
98
99class Lz4ImagePatch : public CompressedImagePatch {
100public:
101    Lz4ImagePatch(UpdatePatchWriterPtr writer, const std::vector<uint8_t> &bonusData)
102        : CompressedImagePatch(writer, bonusData) {}
103    ~Lz4ImagePatch() override {}
104
105protected:
106    int32_t ReadHeader(const PatchParam &param, PatchHeader &header, size_t &offset) override;
107    std::unique_ptr<Hpackage::FileInfo> GetFileInfo() const override;
108
109    int32_t compressionLevel_ {0};
110    int32_t blockIndependence_ {0};
111    int32_t contentChecksumFlag_ {0};
112    int32_t blockSizeID_ {0};
113    int32_t method_ {0};
114    int32_t autoFlush_ {1};
115};
116
117class CompressedFileRestore : public UpdatePatchWriter {
118public:
119    CompressedFileRestore(Hpackage::PkgManager::FileInfoPtr fileInfo, UpdatePatchWriterPtr writer)
120        : UpdatePatchWriter(), fileInfo_(fileInfo), writer_(writer) {}
121    ~CompressedFileRestore() override {}
122
123    int32_t Init() override;
124    int32_t Write(size_t start, const BlockBuffer &buffer, size_t len) override;
125    int32_t Finish() override
126    {
127        return 0;
128    }
129    int32_t CompressData(size_t &originalSize, size_t &compressSize);
130private:
131    std::vector<uint8_t> data_ {};
132    size_t dataSize_ {0};
133    Hpackage::PkgManager::FileInfoPtr fileInfo_ { nullptr };
134    UpdatePatchWriterPtr writer_ { nullptr };
135    std::unique_ptr<DeflateAdapter> deflateAdapter_ { nullptr };
136    SHA256_CTX sha256Ctx_ {};
137};
138} // namespace UpdatePatch
139#endif  // IMAGE_PATCH_H
140