Remove dependencies to LZMA 08/285808/1
authorMateusz Moscicki <m.moscicki2@partner.samsung.com>
Fri, 9 Dec 2022 14:20:04 +0000 (15:20 +0100)
committerMateusz Moscicki <m.moscicki2@partner.samsung.com>
Tue, 20 Dec 2022 12:31:16 +0000 (13:31 +0100)
Change-Id: If86e7acaac441600e916b561c24f6f28d88700e9

17 files changed:
packaging/upgrade.spec
src/upgrade-apply-deltafs/CMakeLists.txt
src/upgrade-apply-deltafs/engine/SS_ApplyPatch.c [deleted file]
src/upgrade-apply-deltafs/engine/SS_PatchDelta.c
src/upgrade-apply-deltafs/engine/SS_UPI.c
src/upgrade-apply-deltafs/engine/SS_UPI.h
src/upgrade-apply-deltafs/engine/fota_common.h
src/upgrade-apply-deltafs/engine/fota_tar.c
src/upgrade-apply-deltafs/engine/fota_tar.h
src/upgrade-apply-deltafs/engine/ss_bspatch_common.c [deleted file]
src/upgrade-apply-deltafs/engine/ss_bspatch_common.h [deleted file]
src/upgrade-apply/CMakeLists.txt
src/upgrade-apply/main.c
src/upgrade-apply/patch/lzma.c [deleted file]
src/upgrade-apply/patch/patch.c
src/upgrade-apply/patch/patch_helper.c [new file with mode: 0644]
src/upgrade-apply/patch/patch_helper.h [moved from src/upgrade-apply/patch/lzma.h with 79% similarity]

index 3fd5f9c..a1ffb39 100644 (file)
@@ -11,7 +11,6 @@ Source0:      %{name}-%{version}.tar.gz
 
 BuildRequires: cmake
 BuildRequires:  ca-certificates-devel
-BuildRequires:  pkgconfig(liblzma-tool)
 BuildRequires:  libbrotli-devel
 BuildRequires:  pkgconfig(openssl1.1)
 BuildRequires:  pkgconfig(libtzplatform-config)
index b53d7f8..aa7a321 100644 (file)
@@ -6,19 +6,21 @@ SET(SRCS
        ua.c
        engine/SS_Common.c
        ../upgrade-apply/sha1/sha1.c
+       ../upgrade-apply/patch/patch_helper.c
+       ../upgrade-apply/patch/patch.c
+       ../upgrade-apply/patch/brotli.c
        engine/SS_UPI.c
        engine/SS_FSUpdate.c
-       engine/SS_ApplyPatch.c
        engine/SS_PatchDelta.c
        engine/fota_log.c
        engine/fota_tar.c
-       engine/ss_bspatch_common.c
 )
 
 INCLUDE_DIRECTORIES(../upgrade-apply/sha1)
+INCLUDE_DIRECTORIES(../upgrade-apply/patch)
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED liblzma-tool libbrotlienc hal-api-device zlib)
+pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED libbrotlienc hal-api-device zlib)
 
 FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -32,5 +34,5 @@ SET(BINDIR "/usr/bin")
 ADD_EXECUTABLE(${EXECNAME} ${SRCS})
 
 TARGET_LINK_LIBRARIES(${EXECNAME} PRIVATE ${${PROJECT_NAME}_pkgs_LDFLAGS} "-g" "-pthread")
-TARGET_LINK_LIBRARIES(${EXECNAME} PRIVATE libtar.a)
+TARGET_LINK_LIBRARIES(${EXECNAME} PRIVATE libtar.a libbrotlidec-static.a libbrotlicommon-static.a)
 INSTALL(TARGETS ${EXECNAME} DESTINATION ${BINDIR})
diff --git a/src/upgrade-apply-deltafs/engine/SS_ApplyPatch.c b/src/upgrade-apply-deltafs/engine/SS_ApplyPatch.c
deleted file mode 100755 (executable)
index bc9e86b..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*-
- * Copyright 2003-2005 Colin Percival
- * Copyright 2012 Matthew Endsley
- * All rights reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted providing that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Modifications are made in reimplementing suffix sort array generation
- * and how the data is read and written to.Iterative part replaced the
- * recursive implementation to avoid buffer overflow problems
- */
-#include <string.h>
-#include <err.h>
-#include "SS_PatchDelta.h"
-#include "fota_common.h"
-#include "sha1.h"
-#include "SS_Engine_Errors.h"
-#include "SS_FSUpdate.h"
-
-#include "ss_bspatch_common.h"
-#include <Alloc.h>
-#include <7zFile.h>
-#include <7zVersion.h>
-#include <LzmaDec.h>
-#include <LzmaEnc.h>
-
-
-int SS_ApplyBsdiff(char *oldfile, char *newfile, char *patch, SinkFn sink, void *token, SHA1_CTX * ctx1)
-{
-       UInt64 unpackSize = 0;
-       CFileSeqInStream inStream;
-       ISeqOutStream outStream;
-       unsigned char *buf_res = NULL;
-       unsigned char *new_data = NULL;
-       char buf[256];
-       ssize_t new_size = 0;
-       int result = E_SS_FAILURE;
-
-       FileSeqInStream_CreateVTable(&inStream);
-       File_Construct(&inStream.file);
-       FileOutStream_CreateVTable((CFileOutStream *) & outStream);
-
-       if (InFile_Open(&inStream.file, patch) != 0)
-               return E_SS_FAILURE;
-
-       UInt64 i;
-       CLzmaDec state;
-       unsigned char header[LZMA_PROPS_SIZE + 8];
-
-       RINOK(SeqInStream_Read(&inStream.s, header, sizeof(header)));
-
-       unpackSize = 0;
-       for (i = 0; i < 8; i++)
-               unpackSize += (UInt64) header[LZMA_PROPS_SIZE + i] << (i * 8);
-
-       LzmaDec_Construct(&state);
-       RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc));
-
-       //decompress the patch file into buf_res
-       buf_res = (unsigned char *)SS_Malloc(unpackSize);
-       if (!buf_res) {
-               LOGE("Bad memory allocation\n");
-               goto Cleanup;
-       }
-       result = Decode2(&state, &outStream, &inStream.s, &unpackSize, buf_res);
-
-       LzmaDec_Free(&state, &g_Alloc);
-       File_Close(&inStream.file);
-
-       if (result != S_SS_SUCCESS) {
-               LOGE("Error decompression failed with code : [%d]\n", result);
-               goto Cleanup;
-       }
-       //apply patch using buffer decoded by Decode2
-       result = apply_patch(oldfile, buf_res, &new_data, &new_size);
-       if (result != S_SS_SUCCESS)
-               goto Cleanup;
-
-       result = (sink(new_data, new_size, token) < new_size) ? E_SS_FAILURE : S_SS_SUCCESS;
-       if (result != S_SS_SUCCESS) {
-               strerror_r(errno, buf, sizeof(buf));
-               LOGE("short write of output: %d (%s)\n", errno, buf);
-               goto Cleanup;
-       }
-
-       if (ctx1)
-               SHA1Update(ctx1, new_data, new_size);
-Cleanup:
-       if (new_data)
-               SS_Free(new_data);
-       if (buf_res)
-               SS_Free(buf_res);
-       File_Close(&inStream.file);//wgid: 27007
-       return result;
-
-}
index 32c49f5..b2801a3 100755 (executable)
@@ -31,6 +31,7 @@
 #include "fota_common.h"
 #include "SS_Engine_Errors.h"
 #include "SS_Common.h"
+#include "patch_helper.h"
 
 extern void *SS_Malloc(unsigned int size);
 
@@ -182,10 +183,8 @@ static void create_dir(char *pathname, int mode)
  */
 
 int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
-                                        const char *source_sha1_str, const char *target_sha1_str, int patch_data_size, char *delta_folder)
+                                        const char *source_sha1_str, const char *target_sha1_str, int patch_data_size, TAR* tar_file)
 {
-       char patchfile_source_path[MAX_FILE_PATH];
-       snprintf(patchfile_source_path, MAX_FILE_PATH, "%s/%s", delta_folder, SS_PATCHFILE_SOURCE);
        uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, };
        SHA1_CTX ctx1;
        int output;
@@ -255,8 +254,7 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                        sink = ss_fileSink;
                        token = &output;
                }
-               SHA1Init(&ctx1);
-               result = SS_ApplyBsdiff((char *)source_filename, outname, patchfile_source_path, sink, token, &ctx1);
+               result = apply_patch_brotli((char *)source_filename, outname, tar_file, -1);
                if (output >= 0) {
                        fsync(output);
                        close(output);
@@ -279,6 +277,27 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
        } while (retry-- > 0);
 
        unsigned char current_target_sha1[SHA_DIGEST_SIZE] = { 0, };
+       SHA1Init(&ctx1);
+       int fd = open(outname, O_RDONLY);
+       if (fd == -1) {
+               LOGE("cannot open %s to verify SHA1\n", outname);
+               return E_SS_FAILURE;
+       }
+       char buff[4096];
+       for (;;) {
+               int res = read(fd, buff, 4096);
+               if (res == -1) {
+                       LOGE("cannot read %s to verify SHA1\n", outname);
+                       close(fd);
+                       return E_SS_FAILURE;
+               }
+               if (res == 0)
+                       break;
+
+               SHA1Update(&ctx1, buff, res);
+       }
+       close(fd);
+
        SHA1Final(current_target_sha1, &ctx1);
        if (memcmp(current_target_sha1, target_sha1, SHA_DIGEST_SIZE) != 0) {
                LOGE("patch did not produce expected sha1\n");
@@ -311,8 +330,7 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
        if (strcmp(source_filename, target_filename) != 0)
                unlink(source_filename);
 #endif
-       SS_PatchSourceClear(patchfile_source_path);
        SS_Free(outname);
 
        return result;
-}
\ No newline at end of file
+}
index ba6747f..b001407 100755 (executable)
@@ -29,11 +29,13 @@ Function Prototypes Mandatory
 #include<stdlib.h>
 #include<string.h>
 #include<inttypes.h>
+#include <assert.h>
 #include <stdbool.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <sys/statfs.h>
 #include <mntent.h>
+#include <brotli/decode.h>
 #include "ua_types.h"
 #include "SS_Common.h"
 #include "fota_common.h"
@@ -1127,7 +1129,7 @@ int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, f
                                case 0:
                                        ulResult =
                                                SS_UpdateDeltaFS(temp_param->file_old_path, temp_param->file_new_path, temp_param->sha1src,
-                                                                                temp_param->sha1trg, temp_param->data_size, ua_dataSS->update_data->ua_delta_folder);
+                                                                                temp_param->sha1trg, temp_param->data_size, ua_dataSS->tar_data->tar);
                                        if (ulResult != S_SS_SUCCESS) {
                                                LOGE("FS update Failed Result : [%d], [Item - %s]and size is[%d] Read Count[%d], index = [%d]\n", ulResult,
                                                 ubPatch, temp_param->data_size, ulReadCnt, ulFileIndex);
@@ -1288,13 +1290,13 @@ int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, f
                        LOGL(LOG_SSENGINE, "NEWFILES mode start\n");
                        LOGL(LOG_SSENGINE, "Starting New file upgrade for   [%s]\n", patch_path);
                        if (ua_dataSS->tar_data->new_files_info.offset >= 0) {
-                               if (tar_extract_7z_file(ua_dataSS->tar_data) < 0) {
+                               if (tar_extract_newfiles_archive(ua_dataSS->tar_data) < 0) {
                                        LOGE("newfiles extraction error!\n");
                                        SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
                                        ulResult = E_SS_FAILURE;
                                }
 
-                               if (_7zdecompress(ua_dataSS->tar_data->new_files_info.extracted_name) == 0) {
+                               if (decompress_tar_brotli(ua_dataSS->tar_data->new_files_info.extracted_name) == 0) {
                                        LOGL(LOG_SSENGINE, "7zip extracted  successfully %s\n", ua_dataSS->parti_info->ua_parti_name);
                                } else {
                                        LOGL(LOG_SSENGINE, "7zip extraction error for %s\n", ua_dataSS->parti_info->ua_parti_name);
@@ -1698,4 +1700,132 @@ long SS_GetUPIVersion(unsigned char *ver_str)
                return S_SS_SUCCESS;//wgid: 2456
        } else
                return E_SS_FAILURE;
-}
\ No newline at end of file
+}
+
+struct BrotliFile {
+       BrotliDecoderState *state;
+       int fd;
+       size_t available_in;
+       size_t available_out;
+       size_t total_size;
+       const uint8_t *compressed_pos;
+       unsigned char buff_in[T_BLOCKSIZE];
+};
+
+struct BrotliFile *brotli_file = NULL;
+
+int brotli_open(const char *path, __attribute__((unused)) int oflat, ...)
+{
+       assert(path);
+       if (brotli_file != NULL) {
+               LOGE("Cannot open another brotli file.");
+               return -1;
+       }
+       brotli_file = (struct BrotliFile*)malloc(sizeof(struct BrotliFile));
+       if (brotli_file == NULL) {
+               LOGE("Memory allocation error: %m (%d)", errno);
+               return -1;
+       }
+       brotli_file->fd = open(path, O_RDONLY);
+       if (brotli_file->fd == -1) {
+               free(brotli_file);
+               brotli_file = NULL;
+               LOGE("Failed to open compressed file %s: %m (%d)", path, errno);
+               return -1;
+       }
+       brotli_file->available_in = 0;
+       brotli_file->compressed_pos = brotli_file->buff_in;
+       brotli_file->total_size = 0;
+       brotli_file->state = BrotliDecoderCreateInstance(NULL, NULL, NULL);
+       return 0;
+}
+
+ssize_t brotli_read(__attribute__((unused)) int fd, void *buff, size_t len)
+{
+       assert(buff);
+       assert(brotli_file);
+       uint8_t *out_pos = buff;
+       size_t available_out = len;
+       while (available_out > 0) {
+               int result = BrotliDecoderDecompressStream(brotli_file->state,
+                                                          &brotli_file->available_in,
+                                                          &brotli_file->compressed_pos,
+                                                          &available_out,
+                                                          &out_pos,
+                                                          &brotli_file->total_size);
+               switch (result) {
+                       case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
+                               {
+                                       if (brotli_file->available_in > 0) {
+                                               // If there is anything left in the buffer we move it to the beginning.
+                                               // Altough usually such a situation does not occur.
+                                               memmove(brotli_file->buff_in,
+                                                       brotli_file->compressed_pos,
+                                                       brotli_file->available_in);
+                                       }
+                                       ssize_t r_read = read(brotli_file->fd,
+                                                             brotli_file->buff_in + brotli_file->available_in,
+                                                             T_BLOCKSIZE - brotli_file->available_in);
+                                       brotli_file->compressed_pos = brotli_file->buff_in;
+                                       if (r_read < 0) {
+                                               LOGE("Error reading compressed file: %m (%d)", errno);
+                                               return -1;
+                                       }
+
+                                       brotli_file->available_in += r_read;
+                                       break;
+                       }
+                       case BROTLI_DECODER_RESULT_ERROR:
+                               {
+                                       BrotliDecoderErrorCode code = BrotliDecoderGetErrorCode(brotli_file->state);
+                                       const char *err_str = BrotliDecoderErrorString(code);
+                                       LOGE("Brotli decoder error: %d %s", code, err_str);
+                                       return -1;
+                       }
+               }
+       }
+       return len - available_out;
+}
+
+int brotli_close(__attribute__((unused)) int fd)
+{
+       if (brotli_file != NULL) {
+               if (brotli_file->fd > 0)
+                       close(brotli_file->fd);
+               BrotliDecoderDestroyInstance(brotli_file->state);
+               free(brotli_file);
+               brotli_file = NULL;
+       }
+}
+
+ssize_t brotli_write(__attribute__((unused)) int fd,
+                     __attribute__((unused)) const void *buff,
+                     __attribute__((unused)) size_t len)
+{
+       return ENOTSUP;
+}
+
+int decompress_tar_brotli(const char *path)
+{
+       TAR *tar = NULL;
+       tartype_t type = {
+               .openfunc = brotli_open,
+               .closefunc = brotli_close,
+               .readfunc = brotli_read,
+               .writefunc = brotli_write
+       };
+
+       if (tar_open(&tar, path, &type, O_RDONLY, 0, 0) != 0) {
+               LOGL(LOG_SSENGINE, "Cannot open %s file: %m (%d)", path, errno);
+               return E_SS_FAILURE;
+       }
+       if (tar_extract_all(tar, ".") == -1) {
+               LOGL(LOG_SSENGINE, "Tar %s extract error: %m (%d)", path, errno);
+               return E_SS_FAILURE;
+       }
+       if (tar_close(tar) == -1) {
+               LOGL(LOG_SSENGINE, "Tar %s close error: %m (%d)", path, errno);
+       }
+
+       return S_SS_SUCCESS;
+}
index 0005a79..f001bf4 100755 (executable)
@@ -65,6 +65,7 @@ int SS_AppendNode(const char *ubDeltaPath, fs_params ** headparam, fs_params **
                                  const char *new_path, const char *patchname, const char *sha1src, const char *sha1trg, int type,
                                  char *patchpath_name);
 long SS_GetUPIVersion(unsigned char *ver_str);
+int decompress_tar_brotli(const char *path);
 extern int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS);
 extern int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS);
 
@@ -72,8 +73,7 @@ extern int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS);
 extern void *SS_Malloc(unsigned int size);
 extern void SS_Free(void *pMemBlock);
 extern int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
-                                                       const char *source_sha1_str, const char *target_sha1_str, int patch_data_size, char *delta_folder);
-extern int _7zdecompress(char *path);
+                                                       const char *source_sha1_str, const char *target_sha1_str, int patch_data_size, TAR* tar_file);
 extern long SS_GetFileType(char *pLinkName, enumFileType * fileType);
 
 #endif                                           //_SS_UPI_H_
index 5164da2..4dcb2a3 100755 (executable)
@@ -41,7 +41,7 @@ typedef u32 size_t;
 #define SS_BACKUP_SOURCE                "saved.file"       //How to make sure there is SPACE
 #define SS_PATCHFILE_SOURCE             "patchfile.file"   //define in common place
 #define SS_PATCHLIST_BKUPLOC            "patchlist.txt"
-#define SS_NEW_COMPRESSED_FILE          "system.7z"
+#define SS_NEW_COMPRESSED_FILE          "system.tar.br"
 
 #define SS_PATCHLISTFORMAT             ".txt"
 #define SS_PATCH_ATTR_FORMAT           "_attr.txt"
@@ -59,7 +59,7 @@ typedef u32 size_t;
 #define SS_MAX_NAMELENSUPPORTED                (200)   //(Tar supports 256, But extra space is used for PartitionName, .delta, /p, so restricting filename max to 200)
 #define SS_MAX_FILE_PATH               (512)
 #define SS_TOKEN_MAXLINE_LEN           (1024)
-#define SS_COMPRESSED_FILE             "system.7z"
+#define SS_COMPRESSED_FILE             "system.tar.br"
 
 #define SS_STRING_DIFF                 "DIFF"
 #define SS_STRING_MOVE                 "MOVE"
index 148f638..30c3e5b 100755 (executable)
@@ -274,7 +274,7 @@ int tar_get_cfg_data(tar_info *tar_data)
        return 0;
 }
 
-int tar_extract_7z_file(tar_info *tar_data)
+int tar_extract_newfiles_archive(tar_info *tar_data)
 {
        if (tar_seek(tar_data->tar, tar_data->new_files_info.offset, SEEK_SET) < 0) {
                LOGE("seeking error!\n");
@@ -369,10 +369,7 @@ int tar_diff_iter_next_extract(tar_info *tar_data, diff_iterator *diff_iter, cha
                        }
                        *params = tmp;
                        (*params)->data_size = th_get_size(tar_data->tar);
-                       if (tar_extract_file(tar_data->tar, target) < 0) {
-                               LOGE("File extraction error!\n");
-                               return -1;
-                       }
+                       // We found it!
                        return 0;
                }
                if (TH_ISREG(tar_data->tar) && (tar_skip_regfile(tar_data->tar) < 0)) {
@@ -380,4 +377,4 @@ int tar_diff_iter_next_extract(tar_info *tar_data, diff_iterator *diff_iter, cha
                        return -1;
                }
        }
-}
\ No newline at end of file
+}
index debbfe9..895b41f 100755 (executable)
@@ -33,7 +33,7 @@ typedef struct _diff_iterator {
 int tar_get_tartype(char *tar_path, tartype_t **type);
 int tar_init_with_type(TAR **tar, char *tar_path, tartype_t *type);
 int tar_get_cfg_data(tar_info *tar_data);
-int tar_extract_7z_file(tar_info *tar_data);
+int tar_extract_newfiles_archive(tar_info *tar_data);
 int tar_init_diff_iterations(tar_info *tar_data, diff_iterator *diff_iter, fs_params *head);
 int tar_diff_iter_next_extract(tar_info *tar_data, diff_iterator *diff_iter, char *target, fs_params **params);
 
diff --git a/src/upgrade-apply-deltafs/engine/ss_bspatch_common.c b/src/upgrade-apply-deltafs/engine/ss_bspatch_common.c
deleted file mode 100755 (executable)
index e7bd45e..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*-
- * Copyright 2003-2005 Colin Percival
- * Copyright 2012 Matthew Endsley
- * All rights reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted providing that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Modifications are made in reimplementing suffix sort array generation
- * and how the data is read and written to.Iterative part replaced the
- * recursive implementation to avoid buffer overflow problems
- */
-//#define ZLIB_MOD                                                                       //not stable yet.
-//#define MAX_MATCH_SIZE                  // define ( MAX_MATCH_SIZE or CONST_MEMORY_USAGE ) or ( none of them )
-#define CONST_MEMORY_USAGE (64*1024)   //tests show smallest time when using 64 kb
-#define PATCH_FILE_FORMAT_MOD
-#define BSDIFF_HEADER "BSDIFF40"
-#define SSDIFF_HEADER "SSDIFF40"
-//#define MULTI_THREADING
-#include <stdbool.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <Alloc.h>
-#include <7zFile.h>
-#include <7zVersion.h>
-#include <LzmaDec.h>
-#include <LzmaEnc.h>
-
-static void *SzAlloc(void *p, size_t size)
-{
-       p = p;
-       return MyAlloc(size);
-}
-
-static void SzFree(void *p, void *address)
-{
-       p = p;
-       MyFree(address);
-}
-ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
-static off_t offtin(u_char *buf)
-{
-       off_t y;
-
-       y = buf[7] & 0x7F;
-       y = y * 256;
-       y += buf[6];
-       y = y * 256;
-       y += buf[5];
-       y = y * 256;
-       y += buf[4];
-       y = y * 256;
-       y += buf[3];
-       y = y * 256;
-       y += buf[2];
-       y = y * 256;
-       y += buf[1];
-       y = y * 256;
-       y += buf[0];
-
-       if (buf[7] & 0x80)
-               y = -y;
-
-       return y;
-}
-
-#define IN_BUF_SIZE (1 << 16)
-#define OUT_BUF_SIZE (1 << 16)
-
-SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
-               UInt64 *unpackSize, unsigned char *dec_data)
-{
-       int thereIsSize = (*unpackSize != (UInt64)(Int64) - 1);
-       UInt64 offset = 0;
-       Byte inBuf[IN_BUF_SIZE];
-       Byte outBuf[OUT_BUF_SIZE];
-       size_t inPos = 0, inSize = 0, outPos = 0;
-
-       LzmaDec_Init(state);
-
-       offset = 0;
-
-       for (;;) {
-               if (inPos == inSize) {
-                       inSize = IN_BUF_SIZE;
-                       RINOK(inStream->Read(inStream, inBuf, &inSize));
-                       inPos = 0;
-               }
-
-               SRes res;
-               SizeT inProcessed = inSize - inPos;
-               SizeT outProcessed = OUT_BUF_SIZE - outPos;
-               ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
-               ELzmaStatus status;
-
-               if (thereIsSize && outProcessed > *unpackSize) {
-                       outProcessed = (SizeT) * unpackSize;
-                       finishMode = LZMA_FINISH_END;
-               }
-
-               res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,
-                               inBuf + inPos, &inProcessed, finishMode, &status);
-               inPos += inProcessed;
-               outPos += outProcessed;
-               *unpackSize -= outProcessed;
-               memcpy(dec_data + offset, outBuf, outProcessed);
-               offset += outProcessed;
-
-               outPos = 0;
-
-               if ((res != SZ_OK) || (thereIsSize && *unpackSize == 0))
-                       return res;
-
-               if (inProcessed == 0 && outProcessed == 0) {
-                       if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
-                               return SZ_ERROR_DATA;
-                       return res;
-               }
-       }
-}
-
-int apply_patch(const char *oldfile, unsigned char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size)
-{
-       int fd = -1, result = 0;
-       off_t oldsize, newsize;
-       u_char header[16], buf[8];
-       u_char *old = NULL;
-       off_t oldpos, newpos;
-       off_t ctrl[4];          /////////////////////////////////////THREAD
-       off_t total_write;      /////////////////////////////////////////THREAD
-       off_t j;
-       off_t memory_usage = CONST_MEMORY_USAGE;
-       off_t match_size;
-       off_t patch_buffer_offset = 0;
-       bool flag;
-
-       /*
-          File format:
-          0    8          "BSDIFF40"
-          8    8          X
-          16   8          Y
-          24   8          sizeof(newfile)
-          32   X          bzip2(control block)
-          32+X Y          bzip2(diff block)
-          32+X+Y          ???   bzip2(extra block)
-          with control block a set of triples (x,y,z) meaning "add x bytes
-          from oldfile to x bytes from the diff block; copy y bytes from the
-          extra block; seek forwards in oldfile by z bytes".
-        */
-       // Read header
-       if (patch_buffer)
-               memcpy(header, patch_buffer, 16);
-       else {
-               printf("%s().%d Corrupt decoded patch buffer\n", __FUNCTION__, __LINE__);
-               return 1;
-       }
-
-       /* Check for appropriate magic */
-       if (memcmp(header, BSDIFF_HEADER, 8) != 0 && memcmp(header, SSDIFF_HEADER, 8) != 0) {
-               printf("%s().%d Patch buffer header corrupt\n", __FUNCTION__, __LINE__);
-               return 1;
-       }
-
-       /* Read lengths from header */
-       newsize = offtin(header + 8);
-
-       if ((newsize < 0)) {
-               printf("%s().%d Patch buffer corrupt\n", __FUNCTION__, __LINE__);
-               return 1;
-       }
-
-       /* Cset patch_buffer_offset at the right place */
-       patch_buffer_offset += 16;
-
-       if (((fd = open(oldfile, O_RDONLY, 0)) < 0) ||
-                       ((oldsize = lseek(fd, 0, SEEK_END)) == -1) ||
-                       ((old = malloc(memory_usage + 1)) == NULL) ||
-                       (lseek(fd, 0, SEEK_SET) != 0)) {
-               printf("Corruption in old file %s\n", oldfile);
-               result = 1;
-               goto Cleanup;
-       }
-
-       if ((*dest_buf = malloc(newsize + 1)) == NULL) {
-               printf("Corruption in old file %s\n", oldfile);
-               result = 1;
-               goto Cleanup;
-       }
-       oldpos = 0;
-       newpos = 0;
-
-       total_write = 0;
-
-       while (total_write != newsize) {
-               /* Read control data */
-               for (j = 0; j <= 3; j++) {
-                       memcpy(buf, patch_buffer + patch_buffer_offset, 8);
-                       patch_buffer_offset += 8;
-                       ctrl[j] = offtin(buf);
-               };
-
-               total_write += (ctrl[0] + ctrl[1]);
-               newpos = ctrl[3];
-               oldpos = ctrl[2];
-
-               //////////////////////////////////////////////////////////////////////////////////
-               flag = true;
-               match_size = ctrl[0];
-               while (flag == true) {
-                       if (match_size <= memory_usage) {
-                               if (pread(fd, old, match_size, oldpos) != match_size) {
-                                       printf("Corruption in old file %s\n", oldfile);
-                                       result = 1;
-                                       goto Cleanup;
-                               }
-                               if (newpos + match_size > newsize) {
-                                       printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__);
-                                       result = 1;
-                                       goto Cleanup;
-                               }
-                               memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, match_size);
-                               patch_buffer_offset += match_size;
-                               for (j = 0; j < match_size; j++)
-                                       (*dest_buf)[newpos + j] += old[j];
-                               newpos += match_size;
-                               flag = false;
-                       } else {
-                               if (pread(fd, old, memory_usage, oldpos) != memory_usage) {
-                                       printf("%s().%d Corruption in old file %s\n", __FUNCTION__, __LINE__ , oldfile);
-                                       result = 1;
-                                       goto Cleanup;
-                               }
-                               if (newpos + memory_usage > newsize) {
-                                       printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__);
-                                       result = 1;
-                                       goto Cleanup;
-                               }
-                               memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, memory_usage);
-                               patch_buffer_offset += memory_usage;
-                               for (j = 0; j < memory_usage; j++)
-                                       (*dest_buf)[newpos + j] += old[j];
-                               match_size -= memory_usage;
-                               oldpos += memory_usage;
-                               newpos += memory_usage;
-                       }
-               }
-
-               ////////////////////////////////////////////////////////////////////////////////////////
-               /* Sanity-check */
-               if (newpos + ctrl[1] > newsize) {
-                       printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__);
-                       result = 1;
-                       goto Cleanup;
-               }
-               /* Read extra string */
-               memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, ctrl[1]);
-               patch_buffer_offset += ctrl[1];
-       };
-       *dest_size = newsize;
-Cleanup:
-       //close old file
-       if (fd >= 0)
-               close(fd);
-       if (old)
-               free(old);
-       return result;
-}
diff --git a/src/upgrade-apply-deltafs/engine/ss_bspatch_common.h b/src/upgrade-apply-deltafs/engine/ss_bspatch_common.h
deleted file mode 100644 (file)
index 3075ea2..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _SS_BSPATCH_COMMON_H
-#define _SS_BSPATCH_COMMON_H 1
-
-#include <Alloc.h>
-#include <7zFile.h>
-#include <7zVersion.h>
-#include <LzmaDec.h>
-#include <LzmaEnc.h>
-
-extern ISzAlloc g_Alloc;
-
-SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
-               UInt64 *unpackSize, unsigned char *dec_data);
-
-int apply_patch(const char *oldfile, unsigned char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size);
-
-#endif /* _SS_BSPATCH_COMMON_H */
index 4fd1111..3e269ba 100644 (file)
@@ -1,5 +1,5 @@
 find_package(PkgConfig)
-pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET zlib liblzma-tool)
+pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET zlib)
 
 ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64")
 
@@ -8,7 +8,6 @@ set(
        main.c
        patch/patch.c
        patch/brotli.c
-       patch/lzma.c
        sha1/sha1.c
 )
 add_executable(upgrade-apply ${upgrade-apply_SRCS})
index 080a1cb..51e1761 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "patch/patch.h"
 #include "patch/brotli.h"
-#include "patch/lzma.h"
 #include "sha1/sha1.h"
 
 void fd_cleanup(int *fd)
@@ -127,8 +126,6 @@ struct parse_result parse_args(int argc, char **argv)
                                kind = KIND_RAW;
                        else if (strcmp(optarg, "ss_brotli_patch") == 0)
                                kind = KIND_BROTLI_PATCH;
-                       else if (strcmp(optarg, "ss_lzma_patch") == 0)
-                               kind = KIND_LZMA_PATCH;
                        else
                                return (struct parse_result) { .result = PARSE_BAD_KIND };
                        break;
@@ -266,12 +263,11 @@ void help(char *name)
                "The KIND parameter specifies how the file will be treated:\n"
                " - raw means that the file should be treated as an image to be written,\n"
                " - ss_brotli_patch means that the file should be treated as a delta in the (Tizen-specific) ss_brotli_patch\n"
-               " - ss_lzma_patch means that the file should be treated as a delta in the (Tizen-specific) ss_lzma_patch\n"
                "   format. In this case, ORIGIN is needed and specifies the partition that a delta is based on.\n"
                "The results will be written to the DESTINATION partition.\n"
                "If SHA1 is provided (lowercase hexadecimal), it is compared to the one calculated on DESTINATION after writing.\n"
                "Additionally, if SIZE is provided, it is used as the destination size; this matters for SHA1 comparision,\n"
-               "and also if ss_brotli_patch or ss_lzma_patch is used.\n",
+               "and also if ss_brotli_patch.\n",
        name);
 }
 
@@ -487,12 +483,6 @@ int main(int argc, char **argv)
                                r = apply_patch(parsed.patch_orig, parsed.dest, tar, parsed.dest_size, &funcs);
                                break;
                        }
-               case KIND_LZMA_PATCH:
-                       {
-                               struct dec_funcs funcs = { init_lzma, decompress_lzma, clean_lzma };
-                               r = apply_patch(parsed.patch_orig, parsed.dest, tar, parsed.dest_size, &funcs);
-                               break;
-                       }
                }
 
                if (r != 0) {
diff --git a/src/upgrade-apply/patch/lzma.c b/src/upgrade-apply/patch/lzma.c
deleted file mode 100644 (file)
index 60ea3bd..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * tota-ua (previously libtota)
- *
- * Copyright (c) 2022 Samsung Electronics 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.
- */
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <assert.h>
-#include "patch.h"
-#include <LzmaDec.h>
-#include <Alloc.h>
-
-#define HEADER_PLUS_SIZE_LEN LZMA_PROPS_SIZE+8
-
-struct lzma_data {
-    bool initialized;
-    CLzmaDec *state;
-};
-
-static void *SzAlloc(void *p, size_t size)
-{
-    return MyAlloc(size);
-}
-
-
-static void SzFree(void *p, void *address)
-{
-    MyFree(address);
-}
-
-ISzAlloc g_alloc = { SzAlloc, SzFree };
-
-int init_lzma(struct bs_data *data)
-{
-    assert(data);
-    struct lzma_data *internal_data = (struct lzma_data*)malloc(sizeof(struct lzma_data));
-    if (!internal_data)
-        return PF_ERROR_DECOMPRESSION;
-
-    CLzmaDec *state = (CLzmaDec*)malloc(sizeof(CLzmaDec));
-    if (!state) {
-        free(internal_data);
-        return PF_ERROR_DECOMPRESSION;
-    }
-
-    data->state = internal_data;
-    internal_data->state = state;
-    internal_data->initialized = false;
-
-    LzmaDec_Construct(state);
-
-    return PF_OK;
-}
-
-void clean_lzma(struct bs_data *data)
-{
-    assert(data);
-    if (!data->state)
-        return;
-
-    struct lzma_data *internal_data = data->state;
-    LzmaDec_Free(internal_data->state, &g_alloc);
-    free(internal_data->state);
-    free(internal_data);
-    data->state = NULL;
-}
-
-static int init_lzma_internal(struct bs_data *data)
-{
-    assert(data);
-    if (data->available_in < HEADER_PLUS_SIZE_LEN)
-        return PF_NEED_MORE_DATA;
-    struct lzma_data *internal_data = data->state;
-
-    int res = LzmaDec_Allocate(internal_data->state,
-                          data->compressed_pos,
-                          LZMA_PROPS_SIZE,
-                          &g_alloc);
-    if (res != SZ_OK)
-        return PF_ERROR_DECOMPRESSION;
-
-    data->available_in -= HEADER_PLUS_SIZE_LEN;
-    data->compressed_pos += HEADER_PLUS_SIZE_LEN;
-
-    LzmaDec_Init(internal_data->state);
-    internal_data->initialized = true;
-    return PF_OK;
-}
-
-int decompress_lzma(struct bs_data *data)
-{
-    assert(data);
-    int res;
-    struct lzma_data *internal_data = data->state;
-
-
-    if (!internal_data->initialized) {
-        res = init_lzma_internal(data);
-        if (res != PF_OK)
-            return res;
-    }
-
-    ELzmaStatus status;
-    size_t out_processed = data->available_out;
-    size_t in_processed = data->available_in;
-
-    res = LzmaDec_DecodeToBuf(internal_data->state,
-                        data->decompressed_pos,
-                        &out_processed,
-                        data->compressed_pos,
-                        &in_processed,
-                        LZMA_FINISH_ANY,
-                        &status);
-
-    data->available_out -= out_processed;
-    data->available_in -= in_processed;
-    data->decompressed_pos += out_processed;
-    data->compressed_pos += in_processed;
-
-    if (res != SZ_OK)
-        return PF_ERROR_DECOMPRESSION;
-
-    if (status == LZMA_STATUS_NEEDS_MORE_INPUT && data->available_in == 0) {
-        if (data->patch_remaining == 0)
-            return PF_OK; // Since we don't have anything to read, we're done.
-        return PF_NEED_MORE_DATA;
-    }
-
-    return PF_OK;
-}
index 1c7724a..be5f92f 100644 (file)
@@ -219,14 +219,6 @@ static int open_files(struct bs_data *data, const char *source_file, const char
     data->src.len = get_file_len(data->src.fd);
     data->patch_len = th_get_size(data->patch_tar);
     data->dest.len = dest_size == 0 ? get_file_len(data->dest.fd) : dest_size;
-
-    int res;
-    if ((res = remmap(&data->src, 0)) != PF_OK)
-        return res;
-
-    if ((res = remmap(&data->dest, 0)) != PF_OK)
-        return res;
-
     data->patch_remaining = data->patch_len;
 
     return PF_OK;
@@ -322,7 +314,13 @@ int read_header(struct dec_funcs *funcs, struct bs_data *data, uint8_t **buff_ou
     size_t target_size = parse_ssint(*buff_out_pos);
     fprintf(stderr, "target_size: 0x%zx (%zu)\n", target_size, target_size);
 
-    if (target_size != data->dest.len) {
+    if (data->dest.len == -1) {
+        data->dest.len = target_size;
+        if (ftruncate(data->dest.fd, data->dest.len) == -1) {
+            fprintf(stderr, "Cannot change size of the destination file: %m (%d)\n", errno);
+            return PF_ERROR_OPEN_FILE;
+        }
+    } else if (target_size != data->dest.len) {
         fprintf(stderr, "Declared target size differs from that read from the patch\n");
         return PF_ERROR_INVALID_PATCH_FILE;
     }
@@ -357,6 +355,13 @@ int apply_patch(const char *source_file, const char *dest_file, TAR *patch_tar,
     if ((result = read_header(funcs, &data, &buff_out_pos)) != PF_OK)
         goto exit;
 
+    int res;
+    if ((res = remmap(&data.src, 0)) != PF_OK)
+        return res;
+
+    if ((res = remmap(&data.dest, 0)) != PF_OK)
+        return res;
+
     uint64_t total_write = 0;
 
     while (total_write < data.dest.len) {
diff --git a/src/upgrade-apply/patch/patch_helper.c b/src/upgrade-apply/patch/patch_helper.c
new file mode 100644 (file)
index 0000000..c85c9e6
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * tota-ua (previously libtota)
+ *
+ * Copyright (c) 2022 Samsung Electronics 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.
+ */
+
+#include "brotli.h"
+
+int apply_patch_brotli(const char *source_file, const char *dest_file, TAR *patch_tar, size_t dest_size)
+{
+    struct dec_funcs funcs = { init_brotli, decompress_brotli };
+    return apply_patch(source_file, dest_file, patch_tar, dest_size, &funcs);
+}
similarity index 79%
rename from src/upgrade-apply/patch/lzma.h
rename to src/upgrade-apply/patch/patch_helper.h
index d527354..b214cd4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * tota-ua
+ * tota-ua (previously libtota)
  *
  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
@@ -15,9 +15,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #pragma once
-#include "patch.h"
+#include <libtar.h>
 
-int init_lzma(struct bs_data *data);
-int decompress_lzma(struct bs_data *data);
-void clean_lzma(struct bs_data *data);
+int apply_patch_brotli(const char *source_file, const char *dest_file, TAR *patch_tar, size_t dest_size);