From cac9e18ae33a614af9694523f972c0d29c5cb7d8 Mon Sep 17 00:00:00 2001 From: yaohua Date: Thu, 17 Apr 2025 09:01:49 +0800 Subject: [PATCH 01/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- frameworks/native/backup_ext/BUILD.gn | 1 + .../backup_ext/include/InstalldTarUtils.h | 105 +++ .../backup_ext/include/InstalldUnTarFile.h | 64 ++ .../native/backup_ext/include/TarUtil.h | 70 ++ .../native/backup_ext/include/ext_extension.h | 5 + .../backup_ext/src/InstalldUnTarFile.cpp | 744 ++++++++++++++++++ .../native/backup_ext/src/ext_extension.cpp | 112 ++- 7 files changed, 1089 insertions(+), 12 deletions(-) create mode 100644 frameworks/native/backup_ext/include/InstalldTarUtils.h create mode 100644 frameworks/native/backup_ext/include/InstalldUnTarFile.h create mode 100644 frameworks/native/backup_ext/include/TarUtil.h create mode 100644 frameworks/native/backup_ext/src/InstalldUnTarFile.cpp diff --git a/frameworks/native/backup_ext/BUILD.gn b/frameworks/native/backup_ext/BUILD.gn index 2fe333fc3..35f7fbf65 100644 --- a/frameworks/native/backup_ext/BUILD.gn +++ b/frameworks/native/backup_ext/BUILD.gn @@ -37,6 +37,7 @@ ohos_shared_library("backup_extension_ability_native") { "src/sub_ext_extension.cpp", "src/tar_file.cpp", "src/untar_file.cpp", + "src/InstalldUnTarFile.cpp", ] defines = [ diff --git a/frameworks/native/backup_ext/include/InstalldTarUtils.h b/frameworks/native/backup_ext/include/InstalldTarUtils.h new file mode 100644 index 000000000..f25221607 --- /dev/null +++ b/frameworks/native/backup_ext/include/InstalldTarUtils.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2025 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 PHONECLONE_INSTALLDTARUTILS_H +#define PHONECLONE_INSTALLDTARUTILS_H +#include +#include +#include "securec.h" +#include "log.h" + +namespace installd { +#define UID_GID_OFFSET 10000 +#define APP_ID_START 10000 +#define EOVERLAP_AND_RESET 182 +#define TMAGIC "ustar" /* ustar and a null */ +#define TMAGIC_LEN 6 + +#define TMODE_BASE 100 +#define TMODE_LEN 8 +#define TUID_BASE 108 +#define TUID_LEN 8 +#define TGID_BASE 116 +#define TGID_LEN 8 +#define TSIZE_BASE 124 +#define TSIZE_LEN 12 + +#define CHKSUM_BASE 148 + +#define BLOCK_SIZE 512 +#define BLANK_SPACE 0x20 + +#define PATH_MAX_LEN 2048 +#define READ_BUFF_SIZE (512 * 1024) +const int MB_TO_BYTE = (1024 * 1024); + +#define ERR_PARAM (-1) +#define ERR_NOEXIST (-2) +#define ERR_FORMAT (-3) +#define ERR_MALLOC (-4) +#define ERR_IO (-5) + +#define REGTYPE '0' /* regular file */ +#define AREGTYPE '\0' /* regular file */ +#define SYMTYPE '2' /* reserved */ +#define DIRTYPE '5' /* directory */ +#define SPLIT_START_TYPE '8' +#define SPLIT_CONTINUE_TYPE '9' +#define SPLIT_END_TYPE 'A' + +#define GNUTYPE_LONGLINK 'K' + +#define PERMISSION_MASK 07777 +#define MAX_FILESIZE 0777777777777LL +const int SIZE_OF_LONG_IN_32_SYSTEM = 4; + +#define OCTSTRING_LENGTH (sizeof(off_t) * 3 + 1) + +#define LONG_LINK_SYMBOL "././@LongLink" +#define VERSION "00" +#define SPACE ' ' +#define SLASH '/' + +#define DO_ERROR (-1) +#define DO_CONTINUE 0 +#define DO_IGNORETHIS 1 +#define DO_TRAVERSAL 2 +#define DO_EXIT 3 +#define SPLIT_SIZE (1024 * 1024 * 500) // 500M +#define FILTER_SIZE (1024 * 1024 * 100) // 100M + +// callback +class TarCallBack { +public: + virtual ~TarCallBack() {} + +public: + virtual bool IsAborted() = 0; + virtual void OnTaskProgress(size_t szProcessed) = 0; + virtual void OnPackagedUseBriefGenTar(long szProcessed) = 0; + virtual void OnPackagedOneSplitTar(const char *name) = 0; + virtual void WaitTaskLocked() = 0; +}; + +const int PATH_LENTH = 2048; +struct File_info { + char path[PATH_LENTH]; + int mode; + int type; + long size; + time_t modified_time; +}; +} // namespace installd +#endif // PHONECLONE_INSTALLDTARUTILS_H \ No newline at end of file diff --git a/frameworks/native/backup_ext/include/InstalldUnTarFile.h b/frameworks/native/backup_ext/include/InstalldUnTarFile.h new file mode 100644 index 000000000..e51ed8b58 --- /dev/null +++ b/frameworks/native/backup_ext/include/InstalldUnTarFile.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 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 PHONECLONE_INSTALLDUNTARFILE_H +#define PHONECLONE_INSTALLDUNTARFILE_H +#include +#include +#include "InstalldTarUtils.h" +#include "TarUtil.h" + +namespace installd { +// helper function. +off_t ParseOctalStr(const char *p, size_t n); + +class UnTarFile { +public: + UnTarFile(const char *TarPath); + virtual ~UnTarFile(void); + +public: + std::vector GetFileNames(); + int UnSplitPack(const char *path, uid_t owner = 0); + int UnPack(const char *path, uid_t owner = 0); + void Reset(); + bool CheckIsSplitTar(const std::string &tarFile, const std::string &rootpath); + int UnSplitTar(const std::string &tarFile, const std::string &rootpath); + +public: + typedef enum { eList = 0, eUnpack = 1, eCheckSplit = 2 } EParseType; + +private: + int ParseTarFile(const char *rootPath = "", UnTarFile::EParseType type = eList); + bool IsEmptyBlock(const char *p); + bool IsValidTarBlock(const TarHeader *tarHeader); + bool VerifyChecksum(const TarHeader *tarHeader); + bool CheckSliceTar(const char *tarInfo, const char *dstPathName, std::vector &fileNameVector); + bool HandleCheckFile(const char *tarBaseName, std::vector &fileNameVector, int &num); + void FreePointer(char *longName, char *longLink, char *fullPath); + bool CreateDirWithRecursive(const std::string &filePath, mode_t mode = (mode_t)448); + +private: + FILE *FilePtr; + off_t tarSize; + uid_t newOwner; + std::string m_srcPath; + bool isSplit = false; + std::vector file_names; + std::vector file_sizes; + std::vector file_data_addrs; +}; +} // namespace installd +#endif // PHONECLONE_INSTALLDUNTARFILE_H \ No newline at end of file diff --git a/frameworks/native/backup_ext/include/TarUtil.h b/frameworks/native/backup_ext/include/TarUtil.h new file mode 100644 index 000000000..e253e4728 --- /dev/null +++ b/frameworks/native/backup_ext/include/TarUtil.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025 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 TAR_UTIL_H +#define TAR_UTIL_H + +#include + +class TarUtil { +public: + static const int32_t MODE_MASK = 07777; + static const int32_t NAME_LEN = 100; + static const int32_t MODE_LEN = 8; + static const int32_t SIZE_LEN = 12; + static const int32_t CHKSUM_LEN = 8; + static const int32_t BLOCK_LEN = 512; + static const int32_t MAX_PATH_LEN = 4096; // Linux系统中的文件路径长度上限为4096个字符 + static const int32_t RENAME_START_CNT = 1; + static const int32_t CHKSUM_ASCII_VALUE = 256; + static const char GNUTYPE_LONGNAME = 'L'; +}; + +enum RESULT { + OK = 0, + ERROR = -1, + NULL_POINTER = -2, + LIST_EMPTY = -3, + PATH_EMPTY = -4, + OPEN_FILE_FAIL = -5, + FILE_NOT_EXIST = -6, + FILE_UNREADABLE = -7, + READ_INCOMPLETE = -8, + WRITE_INCOMPLETE = -9, + FILE_REMOVE_FAIL = -10, + MAKE_DIR_FAIL = -11, +}; + +typedef struct { /* byte offset */ + char name[100]; /* 0 */ + char mode[8]; /* 100 */ + char uid[8]; /* 108 */ + char gid[8]; /* 116 */ + char size[12]; /* 124 */ + char mtime[12]; /* 136 */ + char chksum[8]; /* 148 */ + char typeflag; /* 156 */ + char linkname[100]; /* 157 */ + char magic[6]; /* 257 */ + char version[2]; /* 263 */ + char uname[32]; /* 265 */ + char gname[32]; /* 297 */ + char devmajor[8]; /* 329 */ + char devminor[8]; /* 337 */ + char prefix[155]; /* 345 */ + char paddings[12]; /* 500 */ +} TarHeader; + +#endif // TAR_UTIL_H \ No newline at end of file diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index ca5611f4a..9cfa8bd7a 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -341,6 +341,11 @@ private: ErrCode CloudSpecialRestore(std::string tarName, std::string untarPath, off_t tarFileSize); void GetTarIncludes(const string &tarName, unordered_map &infos); void DeleteIndexAndRpFile(); + ErrCode RestoreTarListForSpecialCloneCloud(const std::vector &tarList); + bool CheckIsSplitTarList(const std::vector &tarList); + ErrCode RestoreUnSplitTarListForSpecialCloneCloud(const std::vector &tarList); + ErrCode RestoreSplitTarListForSpecialCloneCloud(const std::vector &tarList); + private: std::shared_mutex lock_; std::shared_ptr extension_; diff --git a/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp b/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp new file mode 100644 index 000000000..96759236c --- /dev/null +++ b/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp @@ -0,0 +1,744 @@ +/* + * Copyright (c) 2025 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. + */ + +#include "InstalldUnTarFile.h" + +#include +#include +#include +#include +#include +#include + +#include "securec.h" + +#include + +namespace installd { +const uid_t OCTAL = 8; + +uid_t FixUpOwnerDirFile(const uid_t uid, const gid_t gid, const uid_t owner, gid_t& newGid) +{ + uid_t newUid = owner; + if (0 == owner || uid < APP_ID_START) { + newUid = uid; + newGid = gid; + + return newUid; + } + + if (uid == gid) { + newGid = newUid; + } else if (0 == ((gid - uid) % UID_GID_OFFSET)) { + newGid = (gid - uid) + newUid; + } else { + newGid = gid; + } + + return newUid; +} + +off_t ParseOctalStr(const char* p, size_t n) +{ + off_t ret = 0; + std::string octalStr(p); + auto it = octalStr.begin(); + + while (it != octalStr.end() && (*it < '0' || *it > '7') && n > 0) { + ++it; + --n; + } + + while (it != octalStr.end() && *it >= '0' && *it <= '7' && n > 0) { + ret *= OCTAL; + ret += *it - '0'; + ++it; + --n; + } + + return ret; +} + +static int GenRealPath(const char *rootPath, const char *pathName, char* &realPath) +{ + if (rootPath == nullptr || pathName == nullptr || realPath == nullptr) { + return ERR_PARAM; + } + size_t allLen = strlen(rootPath); + if (rootPath[allLen - 1] != '/') { + allLen += 1; + } + allLen += strlen(pathName); + if (0 == allLen || allLen >= PATH_MAX_LEN) { + LOGE("ERR_PARAM"); + return ERR_PARAM; + } + + size_t curLen = strlen(rootPath); + if (strncpy_s(realPath, PATH_MAX_LEN, rootPath, curLen) != 0) { + LOGE("GenRealPath get realPath error"); + return ERR_PARAM; + } + + if (rootPath[curLen - 1] != '/') { + realPath[curLen] = '/'; + curLen += 1; + } + + if (strncpy_s(realPath + curLen, PATH_MAX_LEN - curLen, pathName, strlen(pathName)) != 0) { + LOGE("GenRealPath get realPath by curLen error"); + return ERR_PARAM; + } + realPath[allLen] = '\0'; + return 0; +} + +static int CreateDir(char *path, mode_t mode) +{ + if (path == nullptr) { + return ERR_PARAM; + } + + size_t len = strlen(path); + if (path[len - 1] == '/') { + path[len - 1] = '\0'; + } + + int ret = access(path, F_OK); + if (ret == -1) { + ret = mkdir(path, mode); + } + return ret; +} + +static FILE *CreateFile(char* path, mode_t mode, char fileType) +{ + if (path == nullptr) { + return nullptr; + } + + std::string appendStr = "wb+"; + if (fileType == SPLIT_END_TYPE || fileType == SPLIT_CONTINUE_TYPE) { + appendStr = "ab+"; + } + FILE *f = fopen(path, appendStr.c_str()); + if (f == nullptr) { + char *p = strrchr(path, '/'); + if (p != nullptr) { + *p = '\0'; + if (CreateDir(path, mode) == 0) { + *p = '/'; + f = fopen(path, "wb+"); + } + } + } + if (f == nullptr) { + return f; + } + if (fchmod(fileno(f), S_IRUSR | S_IWUSR) == -1) { + LOGE("fail to change file permission"); + return nullptr; + } + + return f; +} + +static int CreateSoftlink(const char* oldPath, const char* newPath) +{ + if (oldPath == nullptr || newPath == nullptr) { + return ERR_PARAM; + } + + unlink(newPath); + int ret = symlink(oldPath, newPath); + return ret; +} + +UnTarFile::UnTarFile(const char *tarPath): FilePtr(nullptr), tarSize(0), newOwner(0) +{ + file_names.clear(); + file_sizes.clear(); + file_data_addrs.clear(); + + if (tarPath != nullptr) { + LOGI("untarfile begin.."); + m_srcPath = tarPath; + FilePtr = fopen(tarPath, "rb"); + if (FilePtr == nullptr) { + LOGE("open file fail"); + } + } +} + +UnTarFile::~UnTarFile(void) +{ + if (FilePtr != nullptr) { + (void)fclose(FilePtr); + FilePtr = nullptr; + } + + file_names.clear(); + file_sizes.clear(); + file_data_addrs.clear(); +} + +void UnTarFile::Reset() +{ + if (FilePtr != nullptr) { + (void)fclose(FilePtr); + FilePtr = nullptr; + } + + isSplit = false; + file_names.clear(); + file_sizes.clear(); + file_data_addrs.clear(); +} + +int UnTarFile::UnSplitTar(const std::string &tarFile, const std::string &rootpath) +{ + FilePtr = fopen(tarFile.c_str(), "rb"); + if (FilePtr == nullptr) { + LOGE("UnTarFile::UnSplitPack, untar split failed!"); + } + isSplit = true; + std::string destPath(rootpath); + + CreateDirWithRecursive(destPath); + + int parseRet = ParseTarFile(destPath.c_str(), eUnpack); + if (parseRet != 0) { + LOGE("UnTarFile::UnSplitPack, untar split failed!"); + } else { + LOGI("UnTarFile::UnSplitPack, untar split suc!"); + } + (void)fclose(FilePtr); + FilePtr = nullptr; + return parseRet; +} + +bool UnTarFile::CheckIsSplitTar(const std::string &tarFile, const std::string &rootpath) +{ + FilePtr = fopen(tarFile.c_str(), "rb"); + if (FilePtr == nullptr) { + LOGE("UnTarFile::CheckIsSplitTar, open split failed!"); + } + std::string destPath(rootpath); + int parseRet = ParseTarFile(destPath.c_str(), eCheckSplit); + if (parseRet != 0) { + LOGE("UnTarFile::CheckIsSplitTar, check is split failed!"); + } else { + LOGI("UnTarFile::CheckIsSplitTar, check is split, %{public}d", isSplit); + } + (void)fclose(FilePtr); + FilePtr = nullptr; + if (isSplit) { + return true; + } + return false; +} + +bool UnTarFile::VerifyChecksum(const TarHeader *tarHeader) +{ + if (tarHeader == nullptr) { + return false; + } + + char *headerBuff = (char *)tarHeader; + + int u = 0; + for (int n = 0; n < BLOCK_SIZE; ++n) { + if (n < CHKSUM_BASE || n > CHKSUM_BASE + TarUtil::CHKSUM_LEN - 1) { + /* Standard tar checksum adds unsigned bytes. */ + u += (*(headerBuff + n) & 0xFF); + } else { + u += BLANK_SPACE; + } + } + + return (u == static_cast(ParseOctalStr(headerBuff + CHKSUM_BASE, TarUtil::CHKSUM_LEN))); +} + +bool UnTarFile::IsValidTarBlock(const TarHeader *tarHeader) +{ + if (tarHeader == nullptr) { + return false; + } + + // check magic && checksum + if (0 == strncmp(tarHeader->magic, TMAGIC, TMAGIC_LEN - 1) && VerifyChecksum(tarHeader)) { + return true; + } + + LOGD("Invalid tar format."); + return false; +} + +bool UnTarFile::IsEmptyBlock(const char *p) +{ + return ('\0' == p[0]); +} + +int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) +{ + if (FilePtr == nullptr) { + LOGE("read tar happened error!\n"); + return ERR_PARAM; + } + + if (rootPath == nullptr) { + LOGE("rootPath is nullptr!\n"); + return ERR_NOEXIST; + } + LOGI("ParseTarFile"); + + // re-parse tar header + char buff[BLOCK_SIZE] = {0}; + size_t readCnt = 0; + off_t pos = 0; + char *longName = nullptr; + char *longLink = nullptr; + char *fullPath = nullptr; + bool isSkip = false; + bool isSoftlink = false; + int ret = 0; + + // tarSize + fseeko(FilePtr, 0L, SEEK_END); + tarSize = ftello(FilePtr); + + // reback file to begin + fseeko(FilePtr, 0L, SEEK_SET); + if (tarSize % BLOCK_SIZE != 0) { + LOGE("tarfile size should be a multiple of 512 bytes"); + return ERR_FORMAT; + } + + fullPath = (char *)malloc(PATH_MAX_LEN * sizeof(char)); + if (fullPath == nullptr) { + return ERR_MALLOC; + } + + memset_s(fullPath, PATH_MAX_LEN * sizeof(char), 0, PATH_MAX_LEN * sizeof(char)); + + while (1) { + readCnt = fread(buff, 1, BLOCK_SIZE, FilePtr); + if (readCnt < BLOCK_SIZE) { + LOGE("read short than 512 expected, got %{public}zu, tarSize", readCnt); + + // when split unpack, ftell size is over than file really size [0,READ_BUFF_SIZE] + if (!isSplit || readCnt != 0 || ftello(FilePtr) > (tarSize + READ_BUFF_SIZE)) { + ret = ERR_IO; + } + FreePointer(longName, longLink, fullPath); + return ret; + } + + // two empty continuous block indicate end of file + if (IsEmptyBlock(buff)) { + char tailBuff[BLOCK_SIZE] = {0}; + size_t tailRead = 0; + tailRead = fread(tailBuff, 1, BLOCK_SIZE, FilePtr); + if ((tailRead == BLOCK_SIZE) && IsEmptyBlock(tailBuff)) { + LOGI("untarfile is end.Success!"); + FreePointer(longName, longLink, fullPath); + return ret; + } + } + + // check header + TarHeader *tarHeader = (TarHeader *)buff; + if (!IsValidTarBlock(tarHeader)) { + LOGE("isSplit cur size %{public}jd, tarSize %{public}jd", ftello(FilePtr), tarSize); + + // when split unpack, ftell size is over than file really size [0,READ_BUFF_SIZE] + if (!isSplit || ftello(FilePtr) > (tarSize + READ_BUFF_SIZE) || !IsEmptyBlock(buff)) { + ret = ERR_FORMAT; + } + FreePointer(longName, longLink, fullPath); + return ret; + } + + // mode + mode_t mode = (mode_t) 448; + + // uid & gid + gid_t newGid = 0; + uid_t uid = (uid_t)ParseOctalStr(buff + TUID_BASE, TUID_LEN); + gid_t gid = (gid_t)ParseOctalStr(buff + TGID_BASE, TGID_LEN); + uid_t newUid = FixUpOwnerDirFile(uid, gid, newOwner, newGid); + + // file size & content offset + off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + pos = ftello(FilePtr); + + // longName & longLink + char *realName = tarHeader->name; + if (longName != nullptr) { + realName = longName; + } + + GenRealPath(rootPath, realName, fullPath); + char *realLink = tarHeader->linkname; + if (longLink != nullptr) { + realLink = longLink; + } + CreateDir(const_cast(rootPath), mode); + switch (tarHeader->typeflag) { + case SPLIT_START_TYPE: + case SPLIT_END_TYPE: + case SPLIT_CONTINUE_TYPE: + if (eCheckSplit == type) { + isSplit = true; + FreePointer(longName, longLink, fullPath); + return ret; + } + case REGTYPE: /* regular file */ + case AREGTYPE: { /* regular file */ + if (eList == type) { + file_names.push_back(std::string(realName)); + file_sizes.push_back(fileSize); + file_data_addrs.push_back(pos); + + fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + } else if (eUnpack == type) { + char *destBuff = (char *)malloc(READ_BUFF_SIZE * sizeof(char)); + if (destBuff != nullptr) { + FILE *destF = CreateFile(fullPath, mode, tarHeader->typeflag); + bool IsAbort = false; + bool IsInvalid = false; + if (destF != nullptr) { + off_t restSize = fileSize; + size_t readBuffSize = READ_BUFF_SIZE; + + memset_s(destBuff, READ_BUFF_SIZE * sizeof(char), 0, READ_BUFF_SIZE * sizeof(char)); + + while (restSize > 0) { + if (restSize < READ_BUFF_SIZE) { + readBuffSize = restSize; + } + if (readBuffSize != fread(destBuff, sizeof(char), readBuffSize, FilePtr)) { + LOGE("read file content shorter than expect!\n"); + IsInvalid = true; + break; + } + + if (readBuffSize != fwrite(destBuff, sizeof(char), readBuffSize, destF)) { + LOGE("write file content shorter than expect!\n"); + IsInvalid = true; + break; + } + restSize -= readBuffSize; + } + + if (destBuff != nullptr) { + free(destBuff); + destBuff = nullptr; + } + if (destF != nullptr) { + fflush(destF); + (void)fclose(destF); + destF = nullptr; + } + if (IsInvalid) { + unlink(fullPath); + isSkip = true; + } + if (IsAbort) { + FreePointer(longName, longLink, fullPath); + return ret; + } + + // anyway, go to correct pos + fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); + } else { + LOGE("destF is null!"); + fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + } + } else { + LOGE("malloc memory fail!skip!"); + } + isSkip = false; + } + break; + } + case SYMTYPE: { + CreateSoftlink(realLink, fullPath); + isSoftlink = true; + isSkip = false; + break; + } + case DIRTYPE: { + CreateDir(fullPath, mode); + isSkip = false; + break; + } + case TarUtil::GNUTYPE_LONGNAME: { + if (longName != nullptr) { + free(longName); + longName = nullptr; + } + + size_t nameLen = (size_t)fileSize; + if (nameLen < PATH_MAX_LEN) { + longName = (char *)malloc((nameLen + 1) * sizeof(char)); + } + if (longName != nullptr) { + memset_s(longName, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); + if (nameLen != fread(longName, sizeof(char), nameLen, FilePtr)) { + free(longName); + longName = nullptr; + } + } + + // anyway, go to correct pos + isSkip = true; + fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); + continue; + } + case GNUTYPE_LONGLINK: { + /* long link */ + if (longLink != nullptr) { + free(longLink); + longLink = nullptr; + } + + size_t nameLen = (size_t)fileSize; + if (nameLen < PATH_MAX_LEN) { + longLink = (char *)malloc((nameLen + 1) * sizeof(char)); + } + if (longLink != nullptr) { + memset_s(longLink, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); + if (nameLen != fread(longLink, sizeof(char), nameLen, FilePtr)) { + free(longLink); + longLink = nullptr; + } + } + + // anyway, go to correct pos + isSkip = true; + fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); + continue; + } + default: { + // Ignoring, skip + isSkip = true; + fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + break; + } + } + + if (!isSkip) { + if (!isSoftlink) { + chmod(fullPath, mode); + chown(fullPath, newUid, newGid); + } else { + lchown(fullPath, newUid, newGid); + isSoftlink = false; + } + } + isSkip = false; + + if (longName != nullptr) { + free(longName); + longName = nullptr; + } + if (longLink != nullptr) { + free(longLink); + longLink = nullptr; + } + } + return ret; +} + +void UnTarFile::FreePointer(char *longName, char *longLink, char *fullPath) +{ + if (fullPath != nullptr) { + free(fullPath); + fullPath = nullptr; + } + if (longName != nullptr) { + free(longName); + longName = nullptr; + } + if (longLink != nullptr) { + free(longLink); + longLink = nullptr; + } +} + +bool UnTarFile::CreateDirWithRecursive(const std::string &filePath, mode_t mode) +{ + if (filePath.empty()) { + LOGE("CreateDirWithRecursive filePath is empty"); + return false; + } + if (access(filePath.c_str(), F_OK) == 0) { + return true; + } + + LOGI("CreateDirWithRecursive filePath %{public}s is not exist, need create", filePath.c_str()); + std::string::size_type index = 0; + do { + index = filePath.find('/', index + 1); + std::string subPath = (index == std::string::npos) ? filePath : filePath.substr(0, index); + if (access(subPath.c_str(), F_OK) != 0) { + if (mkdir(subPath.c_str(), mode) != 0) { + return false; + } + } + } while (index != std::string::npos); + return access(filePath.c_str(), F_OK) == 0; +} + +std::vector UnTarFile::GetFileNames() +{ + if (file_names.empty()) { + ParseTarFile(); + } + + return file_names; +} + +int UnTarFile::UnPack(const char *path, uid_t owner) +{ + newOwner = owner; + int ret = ParseTarFile(path, eUnpack); + if (remove(m_srcPath.c_str()) != 0) { + LOGI("delete failed"); + } + return ret; +} + +int UnTarFile::UnSplitPack(const char *path, uid_t owner) +{ + LOGI("Start UnSplitPack"); + newOwner = owner; + isSplit = true; + int num = 0; + std::vector taskSrcPathName; + std::string pathDir(path); + pathDir = pathDir.substr(0, pathDir.find_last_of('/')); + + if (!HandleCheckFile(m_srcPath.c_str(), taskSrcPathName, num)) { + LOGE("UnTarFile::UnSplitPack, handleCheckFile failed!"); + return -1; + } + + int ret = 0; + if (FilePtr != nullptr) { + (void)fclose(FilePtr); + FilePtr = nullptr; + LOGE("FilePtr is not null!"); + } + for (int i = 0; i < num; i++) { + FilePtr = fopen(taskSrcPathName[i].c_str(), "rb"); + if (FilePtr != nullptr) { + int parseRet = ParseTarFile(pathDir.c_str(), eUnpack); + if (parseRet != 0) { + LOGE("UnTarFile::UnSplitPack, untar split failed!"); + (void)fclose(FilePtr); + FilePtr = nullptr; + return parseRet; + } else { + LOGI("UnTarFile::UnSplitPack, untar split suc!"); + (void)fclose(FilePtr); + FilePtr = nullptr; + } + } + if (remove(taskSrcPathName[i].c_str()) != 0) { + LOGI("delete failed"); + } + } + + LOGI("UnTarFile::UnSplitPack, untar split finish!"); + taskSrcPathName.clear(); + return ret; +} + +// check slice tar file according the tar info +bool UnTarFile::CheckSliceTar(const char *tarInfo, const char *dstPathName, std::vector &fileNameVector) +{ + if (tarInfo == nullptr) { + LOGE("error, tarInfo is NULL"); + return false; + } + std::string info(tarInfo); + size_t pos = info.find_last_of("|"); + std::string tarName(dstPathName); + tarName.append("/"); + tarName.append(info.substr(0, pos)); + + std::string subSize = info.substr(pos + 1); + if (subSize.empty()) { + LOGE("error subSize is empty"); + return false; + } + off_t size = strtol(subSize.c_str(), nullptr, 0); + + if (access(tarName.c_str(), F_OK)) { + LOGE("error, slice tar file don't exist, error:%{public}s", strerror(errno)); + return true; + } + + struct stat stSliceTar; + if (stat(tarName.c_str(), &stSliceTar) == -1) { + LOGE("error, failed to get stat of tar file, error: %{public}s", strerror(errno)); + return false; + } + + if (size != stSliceTar.st_size) { + LOGE("error, the size of the tar file is not equal to the size in the check file\n"); + return false; + } + fileNameVector.push_back(tarName); + return true; +} + +bool UnTarFile::HandleCheckFile(const char *tarBaseName, std::vector &fileNameVector, int &num) +{ + LOGI("HandleCheckFile"); + if (tarBaseName == nullptr) { + LOGE("tarBaseName is nullptr"); + return false; + } + + FILE *fd = fopen(tarBaseName, "rb"); + if (fd == nullptr) { + LOGE("open check file error, error:%{public}s", strerror(errno)); + return false; + } + + std::string taskSPath(tarBaseName); + std::string dirName = taskSPath.substr(0, taskSPath.find_last_of('/')); + + char tarInfo[PATH_MAX_LEN] = {0}; + bool ret = true; + while ((fgets(tarInfo, (sizeof(tarInfo) - 1), fd)) != nullptr) { + if (!CheckSliceTar(tarInfo, dirName.c_str(), fileNameVector)) { + LOGE("handleCheckFile: failed"); + ret = false; + break; + } + num++; + memset_s(tarInfo, PATH_MAX_LEN, 0, PATH_MAX_LEN); + } + LOGI("HandleCheckFile end"); + (void)fclose(fd); + fd = nullptr; + return ret; +} +} // namespace installd diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index cead8c887..f50db82de 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -58,6 +58,7 @@ #include "sandbox_helper.h" #include "service_client.h" #include "tar_file.h" +#include "InstalldUnTarFile.h" namespace OHOS::FileManagement::Backup { const string INDEX_FILE_BACKUP = string(BConstants::PATH_BUNDLE_BACKUP_HOME). @@ -1144,6 +1145,96 @@ ErrCode BackupExtExtension::RestoreTarForSpecialCloneCloud(const ExtManageInfo & return ERR_OK; } +ErrCode BackupExtExtension::RestoreTarListForSpecialCloneCloud(const std::vector &tarList) +{ + if (tarList.empty()) { + HILOGI("no tar files, bundle: %{public}s", bundleName_.c_str()); + return ERR_OK; + } + bool isSplit = CheckIsSplitTarList(tarList); + if (!isSplit) { + HILOGI("tar list unsplit, bundle: %{public}s", bundleName_.c_str()); + return RestoreUnSplitTarListForSpecialCloneCloud(tarList); + } + + HILOGI("tar list split, bundle: %{public}s", bundleName_.c_str()); + return RestoreSplitTarListForSpecialCloneCloud(tarList); +} + +bool BackupExtExtension::CheckIsSplitTarList(const std::vector &tarList) +{ + auto *unSplitTar = new installd::UnTarFile(nullptr); + bool isSplit = false; + for (const auto &item : tarList) { + // reset untar object + unSplitTar->Reset(); + + HILOGI("check if split tar, filename: %{public}s, path: %{public}s", GetAnonyPath(item.hashName).c_str(), + GetAnonyPath(item.fileName).c_str()); + // check if tar is split + isSplit = unSplitTar->CheckIsSplitTar(item.hashName, item.fileName); + if (isSplit) { + HILOGI("check is split tar, filename: %{public}s, path: %{public}s", GetAnonyPath(item.hashName).c_str(), + GetAnonyPath(item.fileName).c_str()); + break; + } + } + // destory untar object + delete unSplitTar; + return isSplit; +} + +ErrCode BackupExtExtension::RestoreUnSplitTarListForSpecialCloneCloud(const std::vector &tarList) +{ + for (const auto &item : tarList) { + // 待解压tar文件处理 + HILOGI("untar unsplit, filename: %{public}s, path: %{public}s", GetAnonyPath(item.hashName).c_str(), + GetAnonyPath(item.fileName).c_str()); + radarRestoreInfo_.tarFileNum++; + radarRestoreInfo_.tarFileSize += static_cast(item.sta.st_size); + int ret = RestoreTarForSpecialCloneCloud(item); + if (isDebug_ && ret != ERR_OK) { + errFileInfos_[item.hashName].emplace_back(ret); + endFileInfos_[item.hashName] = item.sta.st_size; + } + if (ret != ERR_OK) { + HILOGE("Failed to restore tar file %{public}s", item.hashName.c_str()); + return ERR_INVALID_VALUE; + } + } + return ERR_OK; +} + +ErrCode BackupExtExtension::RestoreSplitTarListForSpecialCloneCloud(const std::vector &tarList) +{ + auto *unSplitTar = new installd::UnTarFile(nullptr); + ErrCode errCode = ERR_OK; + for (const auto &item : tarList) { + radarRestoreInfo_.tarFileNum++; + radarRestoreInfo_.tarFileSize += static_cast(item.sta.st_size); + // reset untar object + unSplitTar->Reset(); + + // do untar with root path + int ret = unSplitTar->UnSplitTar(item.hashName, item.fileName); + if (isDebug_ && ret != ERR_OK) { + errFileInfos_[item.hashName].emplace_back(ret); + endFileInfos_[item.hashName] = item.sta.st_size; + } + if (ret != ERR_OK) { + HILOGE("Failed to restore tar file %{public}s", item.hashName.c_str()); + errCode = ERR_INVALID_VALUE; + break; + } + if (!RemoveFile(item.hashName)) { + HILOGE("Failed to delete the backup split tar %{public}s", item.hashName.c_str()); + } + } + // destory untar object + delete unSplitTar; + return errCode; +} + ErrCode BackupExtExtension::RestoreFilesForSpecialCloneCloud() { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); @@ -1158,6 +1249,7 @@ ErrCode BackupExtExtension::RestoreFilesForSpecialCloneCloud() auto info = cache.GetExtManageInfo(); HILOGI("Start do restore for SpecialCloneCloud."); auto startTime = std::chrono::system_clock::now(); + auto tarList = std::vector(); for (const auto &item : info) { if (item.hashName.empty()) { HILOGE("Hash name empty"); @@ -1169,20 +1261,16 @@ ErrCode BackupExtExtension::RestoreFilesForSpecialCloneCloud() radarRestoreInfo_.bigFileSize += static_cast(item.sta.st_size); RestoreBigFilesForSpecialCloneCloud(item); } else { - // 待解压tar文件处理 - radarRestoreInfo_.tarFileNum++; - radarRestoreInfo_.tarFileSize += static_cast(item.sta.st_size); - int ret = RestoreTarForSpecialCloneCloud(item); - if (isDebug_ && ret != ERR_OK) { - errFileInfos_[item.hashName].emplace_back(ret); - endFileInfos_[item.hashName] = item.sta.st_size; - } - if (ret != ERR_OK) { - HILOGE("Failed to restore tar file %{public}s", item.hashName.c_str()); - return ERR_INVALID_VALUE; - } + tarList.emplace_back(item); } } + + int ret = RestoreTarListForSpecialCloneCloud(tarList); + if (ret != ERR_OK) { + HILOGE("Failed to restore tar file %{public}s", bundleName_.c_str()); + return ERR_INVALID_VALUE; + } + DeleteIndexAndRpFile(); auto endTime = std::chrono::system_clock::now(); radarRestoreInfo_.totalFileSpendTime = -- Gitee From 0137494c680446e3a49d2af0b8371690acbcf71e Mon Sep 17 00:00:00 2001 From: yaohua Date: Thu, 17 Apr 2025 10:35:28 +0800 Subject: [PATCH 02/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- frameworks/native/backup_ext/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/native/backup_ext/BUILD.gn b/frameworks/native/backup_ext/BUILD.gn index 35f7fbf65..64695e117 100644 --- a/frameworks/native/backup_ext/BUILD.gn +++ b/frameworks/native/backup_ext/BUILD.gn @@ -34,10 +34,10 @@ ohos_shared_library("backup_extension_ability_native") { "src/ext_backup_loader.cpp", "src/ext_extension.cpp", "src/ext_extension_stub.cpp", + "src/InstalldUnTarFile.cpp", "src/sub_ext_extension.cpp", "src/tar_file.cpp", "src/untar_file.cpp", - "src/InstalldUnTarFile.cpp", ] defines = [ -- Gitee From 139d32ba727da4042a1a68a1f90beeb7ca4089da Mon Sep 17 00:00:00 2001 From: yaohua Date: Thu, 17 Apr 2025 17:37:46 +0800 Subject: [PATCH 03/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96-demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- .../backup_ext/include/InstalldUnTarFile.h | 5 + .../backup_ext/src/InstalldUnTarFile.cpp | 258 +++++++++++++++++- 2 files changed, 260 insertions(+), 3 deletions(-) diff --git a/frameworks/native/backup_ext/include/InstalldUnTarFile.h b/frameworks/native/backup_ext/include/InstalldUnTarFile.h index e51ed8b58..3357b6116 100644 --- a/frameworks/native/backup_ext/include/InstalldUnTarFile.h +++ b/frameworks/native/backup_ext/include/InstalldUnTarFile.h @@ -41,8 +41,13 @@ public: typedef enum { eList = 0, eUnpack = 1, eCheckSplit = 2 } EParseType; private: + bool IsProcessTarEnd(char * buff, int *ret); int ParseTarFile(const char *rootPath = "", UnTarFile::EParseType type = eList); bool IsEmptyBlock(const char *p); + bool CheckFileAndPath(const char *rootPath, int &ret); + void HandleRegularFile(EParseType type, char *buff, char *realName, char *fullPath, bool *isSkip); + void HandleRegularEUnpackFile(char *buff, char *fullPath, bool *isSkip); + bool ProcessTarBlock(char *buff, char *longName, char *longLink, char *fullPath, int &ret); bool IsValidTarBlock(const TarHeader *tarHeader); bool VerifyChecksum(const TarHeader *tarHeader); bool CheckSliceTar(const char *tarInfo, const char *dstPathName, std::vector &fileNameVector); diff --git a/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp b/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp index 96759236c..0ee86d281 100644 --- a/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp +++ b/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp @@ -28,6 +28,7 @@ namespace installd { const uid_t OCTAL = 8; +const mode_t FILE_MODE = (mode_t)448; uid_t FixUpOwnerDirFile(const uid_t uid, const gid_t gid, const uid_t owner, gid_t& newGid) { @@ -291,7 +292,261 @@ bool UnTarFile::IsEmptyBlock(const char *p) return ('\0' == p[0]); } +// 检查文件指针和路径 +bool UnTarFile::CheckFileAndPath(const char *rootPath, int &ret) +{ + if (FilePtr == nullptr) { + LOGE("read tar happened error!\n"); + ret = ERR_PARAM; + return false; + } + + if (rootPath == nullptr) { + LOGE("rootPath is nullptr!\n"); + ret = ERR_NOEXIST; + return false; + } + // tarSize + fseeko(FilePtr, 0L, SEEK_END); + tarSize = ftello(FilePtr); + // reback file to begin + fseeko(FilePtr, 0L, SEEK_SET); + if (tarSize % BLOCK_SIZE != 0) { + LOGE("tarfile size should be a multiple of 512 bytes"); + ret = ERR_FORMAT; + return false; + } + return true; +} + +// 处理 tar 文件块 +bool UnTarFile::ProcessTarBlock(char *buff, + const char *rootPath, + EParseType type, + char *longName, + char *longLink, + char *fullPath, + int *ret, + char * realName, + char * realLink) +{ + + off_t pos = ftello(FilePtr); + // uid & gid + gid_t newGid = 0; + uid_t uid = (uid_t)ParseOctalStr(buff + TUID_BASE, TUID_LEN); + gid_t gid = (gid_t)ParseOctalStr(buff + TGID_BASE, TGID_LEN); + uid_t newUid = FixUpOwnerDirFile(uid, gid, newOwner, newGid); + // file size & content offset + off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + bool isSoftlink = false; + TarHeader *tarHeader = (TarHeader *)buff; + switch (tarHeader->typeflag) { + case SPLIT_START_TYPE: + case SPLIT_END_TYPE: + case SPLIT_CONTINUE_TYPE: + if (eCheckSplit == type) { + isSplit = true; + return false; + } + case REGTYPE: + case AREGTYPE: + HandleRegularFile(type, buff, realName, fullPath, &isSkip); + break; + case SYMTYPE: + CreateSoftlink(realLink, fullPath); + isSoftlink = true; + isSkip = false; + break; + case DIRTYPE: + CreateDir(fullPath, FILE_MODE); + isSkip = false; + break; + case TarUtil::GNUTYPE_LONGNAME: { + HandleGnuLongName(); + return true; + } + default: + isSkip = true; + fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + break; + } + + if (!isSkip) { + if (!isSoftlink) { + chmod(fullPath, FILE_MODE); + chown(fullPath, newUid, newGid); + } else { + lchown(fullPath, newUid, newGid); + } + } + return true; +} + +// 处理常规文件 +void UnTarFile::HandleRegularFile(EParseType type, char *buff, char *realName, char *fullPath, bool *isSkip) +{ + off_t pos = ftello(FilePtr); + off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + if (eList == type) { + file_names.push_back(std::string(realName)); + file_sizes.push_back(fileSize); + file_data_addrs.push_back(pos); + + fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + return; + } + if (eUnpack == type) { + HandleRegularEUnpackFile(buff, fullPath, isSkip); + } +} + +void UnTarFile::HandleRegularEUnpackFile(char *buff, char *fullPath, bool *isSkip) +{ + TarHeader *tarHeader = (TarHeader *)buff; + off_t pos = ftello(FilePtr); + off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + char *destBuff = (char *)malloc(READ_BUFF_SIZE * sizeof(char)); + if (destBuff == nullptr) { + LOGE("malloc memory fail!skip!"); + *isSkip = false; + return; + } + memset_s(destBuff, READ_BUFF_SIZE * sizeof(char), 0, READ_BUFF_SIZE * sizeof(char)); + FILE *destF = CreateFile(fullPath, FILE_MODE, tarHeader->typeflag); + if (destF == nullptr) { + LOGE("destF is null!"); + fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + *isSkip = false; + return; + } + bool IsInvalid = false; + size_t readBuffSize = READ_BUFF_SIZE; + + while (fileSize > 0) { + if (fileSize < READ_BUFF_SIZE) { + readBuffSize = fileSize; + } + if (readBuffSize != fread(destBuff, sizeof(char), readBuffSize, FilePtr)) { + LOGE("read file content shorter than expect!\n"); + IsInvalid = true; + break; + } + + if (readBuffSize != fwrite(destBuff, sizeof(char), readBuffSize, destF)) { + LOGE("write file content shorter than expect!\n"); + IsInvalid = true; + break; + } + fileSize -= readBuffSize; + } + + if (destBuff != nullptr) { + free(destBuff); + } + if (destF != nullptr) { + fflush(destF); + (void)fclose(destF); + } + if (IsInvalid) { + unlink(fullPath); + *isSkip = true; + } + + // anyway, go to correct pos + fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); +} + +bool UnTarFile::IsProcessTarEnd(char *buff, int *ret) +{ + size_t readCnt = fread(buff, 1, BLOCK_SIZE, FilePtr); + if (readCnt < BLOCK_SIZE) { + LOGE("read short than 512 expected, got %{public}zu, tarSize", readCnt); + + // when split unpack, ftell size is over than file really size [0,READ_BUFF_SIZE] + if (!isSplit || readCnt != 0 || ftello(FilePtr) > (tarSize + READ_BUFF_SIZE)) { + *ret = ERR_IO; + } + return true; + } + + // two empty continuous block indicate end of file + if (IsEmptyBlock(buff)) { + char tailBuff[BLOCK_SIZE] = {0}; + size_t tailRead = 0; + tailRead = fread(tailBuff, 1, BLOCK_SIZE, FilePtr); + if ((tailRead == BLOCK_SIZE) && IsEmptyBlock(tailBuff)) { + LOGI("untarfile is end.Success!"); + return true; + } + } + + // check header + TarHeader *tarHeader = (TarHeader *)buff; + if (!IsValidTarBlock(tarHeader)) { + LOGE("isSplit cur size %{public}jd, tarSize %{public}jd", ftello(FilePtr), tarSize); + + // when split unpack, ftell size is over than file really size [0,READ_BUFF_SIZE] + if (!isSplit || ftello(FilePtr) > (tarSize + READ_BUFF_SIZE) || !IsEmptyBlock(buff)) { + *ret = ERR_FORMAT; + } + return true; + } + return false; +} + int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) +{ + int ret = 0; + + if (!CheckFileAndPath(rootPath, ret)) { + return ret; + } + LOGI("ParseTarFile"); + + char *longName = nullptr; + char *longLink = nullptr; + char *fullPath = (char *)malloc(PATH_MAX_LEN * sizeof(char)); + if (fullPath == nullptr) { + ret = ERR_MALLOC; + return false; + } + memset_s(fullPath, PATH_MAX_LEN * sizeof(char), 0, PATH_MAX_LEN * sizeof(char)); + // re-parse tar header + char buff[BLOCK_SIZE] = {}; + + bool isSkip = false; + while (true) { + if (IsProcessTarEnd(buff, &ret)) { + FreePointer(longName, longLink, fullPath); + return ret; + } + + TarHeader *tarHeader = (TarHeader *)buff; + char *realName = tarHeader->name; + if (longName != nullptr) { + realName = longName; + } + + GenRealPath(rootPath, realName, fullPath); + char *realLink = tarHeader->linkname; + if (longLink != nullptr) { + realLink = longLink; + } + + CreateDir(const_cast(rootPath), FILE_MODE); + + if (!ProcessTarBlock(buff, rootPath, type, longName, longLink, fullPath, &ret, realName)) { + FreePointer(longName, longLink, fullPath); + return ret; + } + } +} + +int UnTarFile::ParseTarFile_old(const char *rootPath, EParseType type) { if (FilePtr == nullptr) { LOGE("read tar happened error!\n"); @@ -371,9 +626,6 @@ int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) return ret; } - // mode - mode_t mode = (mode_t) 448; - // uid & gid gid_t newGid = 0; uid_t uid = (uid_t)ParseOctalStr(buff + TUID_BASE, TUID_LEN); -- Gitee From 9e08c542b87998880c3a098f1c3e78df9317e637 Mon Sep 17 00:00:00 2001 From: yaohua Date: Fri, 18 Apr 2025 15:08:10 +0800 Subject: [PATCH 04/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96-codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- .../backup_ext/include/InstalldUnTarFile.h | 13 +- .../backup_ext/src/InstalldUnTarFile.cpp | 482 +++++------------- 2 files changed, 149 insertions(+), 346 deletions(-) diff --git a/frameworks/native/backup_ext/include/InstalldUnTarFile.h b/frameworks/native/backup_ext/include/InstalldUnTarFile.h index 3357b6116..dee7f4f39 100644 --- a/frameworks/native/backup_ext/include/InstalldUnTarFile.h +++ b/frameworks/native/backup_ext/include/InstalldUnTarFile.h @@ -42,17 +42,20 @@ public: private: bool IsProcessTarEnd(char * buff, int *ret); - int ParseTarFile(const char *rootPath = "", UnTarFile::EParseType type = eList); + int ParseTarFile(const char *rootPath = "", EParseType type = eList); bool IsEmptyBlock(const char *p); bool CheckFileAndPath(const char *rootPath, int &ret); - void HandleRegularFile(EParseType type, char *buff, char *realName, char *fullPath, bool *isSkip); - void HandleRegularEUnpackFile(char *buff, char *fullPath, bool *isSkip); - bool ProcessTarBlock(char *buff, char *longName, char *longLink, char *fullPath, int &ret); + void SetFileChmodAndChown(char *buff, bool isSoftLink); + void HandleGnuLongLink(char *buff, bool *isSkip); + void HandleGnuLongName(char *buff, bool *isSkip); + void HandleRegularFile(EParseType type, char *buff, bool *isSkip); + void HandleRegularEUnpackFile(char *buff, bool *isSkip); + bool ProcessTarBlock(char *buff, EParseType type, bool *isSkip); bool IsValidTarBlock(const TarHeader *tarHeader); bool VerifyChecksum(const TarHeader *tarHeader); bool CheckSliceTar(const char *tarInfo, const char *dstPathName, std::vector &fileNameVector); bool HandleCheckFile(const char *tarBaseName, std::vector &fileNameVector, int &num); - void FreePointer(char *longName, char *longLink, char *fullPath); + void FreeGlobalPointer(); bool CreateDirWithRecursive(const std::string &filePath, mode_t mode = (mode_t)448); private: diff --git a/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp b/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp index 0ee86d281..38f6663f8 100644 --- a/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp +++ b/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp @@ -29,6 +29,11 @@ namespace installd { const uid_t OCTAL = 8; const mode_t FILE_MODE = (mode_t)448; +char *g_longName = nullptr; +char *g_longLink = nullptr; +char *g_fullPath = nullptr; +char *g_realName = nullptr; +char *g_realLink = nullptr; uid_t FixUpOwnerDirFile(const uid_t uid, const gid_t gid, const uid_t owner, gid_t& newGid) { @@ -320,27 +325,13 @@ bool UnTarFile::CheckFileAndPath(const char *rootPath, int &ret) } // 处理 tar 文件块 -bool UnTarFile::ProcessTarBlock(char *buff, - const char *rootPath, - EParseType type, - char *longName, - char *longLink, - char *fullPath, - int *ret, - char * realName, - char * realLink) +bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, bool *isSkip) { + if (buff == nullptr || isSkip == nullptr) { + return false; + } - off_t pos = ftello(FilePtr); - // uid & gid - gid_t newGid = 0; - uid_t uid = (uid_t)ParseOctalStr(buff + TUID_BASE, TUID_LEN); - gid_t gid = (gid_t)ParseOctalStr(buff + TGID_BASE, TGID_LEN); - uid_t newUid = FixUpOwnerDirFile(uid, gid, newOwner, newGid); - // file size & content offset - off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; - bool isSoftlink = false; + bool isSoftLink = false; TarHeader *tarHeader = (TarHeader *)buff; switch (tarHeader->typeflag) { case SPLIT_START_TYPE: @@ -352,46 +343,123 @@ bool UnTarFile::ProcessTarBlock(char *buff, } case REGTYPE: case AREGTYPE: - HandleRegularFile(type, buff, realName, fullPath, &isSkip); + HandleRegularFile(type, buff, isSkip); break; case SYMTYPE: - CreateSoftlink(realLink, fullPath); - isSoftlink = true; - isSkip = false; + CreateSoftlink(g_realLink, g_fullPath); + isSoftLink = true; + *isSkip = false; break; case DIRTYPE: - CreateDir(fullPath, FILE_MODE); - isSkip = false; + CreateDir(g_fullPath, FILE_MODE); + *isSkip = false; break; - case TarUtil::GNUTYPE_LONGNAME: { - HandleGnuLongName(); + case TarUtil::GNUTYPE_LONGNAME: + HandleGnuLongName(buff, isSkip); + return true; + case GNUTYPE_LONGLINK: + HandleGnuLongLink(buff, isSkip); return true; - } default: - isSkip = true; + *isSkip = true; + // file size & content offset + off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); break; } - if (!isSkip) { - if (!isSoftlink) { - chmod(fullPath, FILE_MODE); - chown(fullPath, newUid, newGid); - } else { - lchown(fullPath, newUid, newGid); - } + if (!*isSkip) { + SetFileChmodAndChown(buff, isSoftLink); } return true; } +void UnTarFile::SetFileChmodAndChown(char *buff, bool isSoftLink) +{ + // uid & gid + gid_t newGid = 0; + uid_t uid = (uid_t)ParseOctalStr(buff + TUID_BASE, TUID_LEN); + gid_t gid = (gid_t)ParseOctalStr(buff + TGID_BASE, TGID_LEN); + uid_t newUid = FixUpOwnerDirFile(uid, gid, newOwner, newGid); + if (!isSoftLink) { + chmod(g_fullPath, FILE_MODE); + chown(g_fullPath, newUid, newGid); + } else { + lchown(g_fullPath, newUid, newGid); + } +} + +void UnTarFile::HandleGnuLongLink(char *buff, bool *isSkip) +{ + if (buff == nullptr || isSkip == nullptr) { + return; + } + /* long link */ + if (g_longLink != nullptr) { + free(g_longLink); + g_longLink = nullptr; + } + off_t pos = ftello(FilePtr); + off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + size_t nameLen = (size_t)fileSize; + if (nameLen < PATH_MAX_LEN) { + g_longLink = (char *) ((nameLen + 1) * sizeof(char)); + } + if (g_longLink != nullptr) { + memset_s(g_longLink, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); + if (nameLen != fread(g_longLink, sizeof(char), nameLen, FilePtr)) { + free(g_longLink); + g_longLink = nullptr; + } + } + + // anyway, go to correct pos + *isSkip = true; + fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); +} + +void UnTarFile::HandleGnuLongName(char *buff, bool *isSkip) +{ + if (isSkip == nullptr) { + return; + } + if (g_longName != nullptr) { + free(g_longName); + g_longName = nullptr; + } + off_t pos = ftello(FilePtr); + off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + size_t nameLen = (size_t)fileSize; + if (nameLen < PATH_MAX_LEN) { + g_longName = (char *)malloc((nameLen + 1) * sizeof(char)); + } + if (g_longName != nullptr) { + memset_s(g_longName, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); + if (nameLen != fread(g_longName, sizeof(char), nameLen, FilePtr)) { + free(g_longName); + g_longName = nullptr; + } + } + + // anyway, go to correct pos + *isSkip = true; + fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); +} + // 处理常规文件 -void UnTarFile::HandleRegularFile(EParseType type, char *buff, char *realName, char *fullPath, bool *isSkip) +void UnTarFile::HandleRegularFile(EParseType type, char *buff, bool *isSkip) { + if (buff == nullptr || isSkip == nullptr || g_fullPath == nullptr || g_realName == nullptr ) { + return; + } off_t pos = ftello(FilePtr); off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; if (eList == type) { - file_names.push_back(std::string(realName)); + file_names.push_back(std::string(g_realName)); file_sizes.push_back(fileSize); file_data_addrs.push_back(pos); @@ -399,12 +467,15 @@ void UnTarFile::HandleRegularFile(EParseType type, char *buff, char *realName, c return; } if (eUnpack == type) { - HandleRegularEUnpackFile(buff, fullPath, isSkip); + HandleRegularEUnpackFile(buff, isSkip); } } -void UnTarFile::HandleRegularEUnpackFile(char *buff, char *fullPath, bool *isSkip) +void UnTarFile::HandleRegularEUnpackFile(char *buff, bool *isSkip) { + if (buff == nullptr || isSkip == nullptr || g_fullPath) { + return; + } TarHeader *tarHeader = (TarHeader *)buff; off_t pos = ftello(FilePtr); off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); @@ -416,7 +487,7 @@ void UnTarFile::HandleRegularEUnpackFile(char *buff, char *fullPath, bool *isSki return; } memset_s(destBuff, READ_BUFF_SIZE * sizeof(char), 0, READ_BUFF_SIZE * sizeof(char)); - FILE *destF = CreateFile(fullPath, FILE_MODE, tarHeader->typeflag); + FILE *destF = CreateFile(g_fullPath, FILE_MODE, tarHeader->typeflag); if (destF == nullptr) { LOGE("destF is null!"); fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); @@ -452,7 +523,7 @@ void UnTarFile::HandleRegularEUnpackFile(char *buff, char *fullPath, bool *isSki (void)fclose(destF); } if (IsInvalid) { - unlink(fullPath); + unlink(g_fullPath); *isSkip = true; } @@ -462,6 +533,9 @@ void UnTarFile::HandleRegularEUnpackFile(char *buff, char *fullPath, bool *isSki bool UnTarFile::IsProcessTarEnd(char *buff, int *ret) { + if (buff == nullptr || ret == nullptr) { + return true; + } size_t readCnt = fread(buff, 1, BLOCK_SIZE, FilePtr); if (readCnt < BLOCK_SIZE) { LOGE("read short than 512 expected, got %{public}zu, tarSize", readCnt); @@ -501,334 +575,60 @@ bool UnTarFile::IsProcessTarEnd(char *buff, int *ret) int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) { int ret = 0; - if (!CheckFileAndPath(rootPath, ret)) { return ret; } LOGI("ParseTarFile"); - char *longName = nullptr; - char *longLink = nullptr; - char *fullPath = (char *)malloc(PATH_MAX_LEN * sizeof(char)); - if (fullPath == nullptr) { - ret = ERR_MALLOC; - return false; + FreeGlobalPointer(); + g_fullPath = (char *)malloc(PATH_MAX_LEN * sizeof(char)); + if (g_fullPath == nullptr) { + return ERR_MALLOC; } - memset_s(fullPath, PATH_MAX_LEN * sizeof(char), 0, PATH_MAX_LEN * sizeof(char)); + memset_s(g_fullPath, PATH_MAX_LEN * sizeof(char), 0, PATH_MAX_LEN * sizeof(char)); // re-parse tar header char buff[BLOCK_SIZE] = {}; - bool isSkip = false; while (true) { if (IsProcessTarEnd(buff, &ret)) { - FreePointer(longName, longLink, fullPath); + FreeGlobalPointer(); return ret; } TarHeader *tarHeader = (TarHeader *)buff; - char *realName = tarHeader->name; - if (longName != nullptr) { - realName = longName; + g_realName = tarHeader->name; + if (g_longName != nullptr) { + g_realName = g_longName; } - GenRealPath(rootPath, realName, fullPath); - char *realLink = tarHeader->linkname; - if (longLink != nullptr) { - realLink = longLink; + GenRealPath(rootPath, g_realName, g_fullPath); + g_realLink = tarHeader->linkname; + if (g_longLink != nullptr) { + g_realLink = g_longLink; } CreateDir(const_cast(rootPath), FILE_MODE); - if (!ProcessTarBlock(buff, rootPath, type, longName, longLink, fullPath, &ret, realName)) { - FreePointer(longName, longLink, fullPath); - return ret; - } - } -} - -int UnTarFile::ParseTarFile_old(const char *rootPath, EParseType type) -{ - if (FilePtr == nullptr) { - LOGE("read tar happened error!\n"); - return ERR_PARAM; - } - - if (rootPath == nullptr) { - LOGE("rootPath is nullptr!\n"); - return ERR_NOEXIST; - } - LOGI("ParseTarFile"); - - // re-parse tar header - char buff[BLOCK_SIZE] = {0}; - size_t readCnt = 0; - off_t pos = 0; - char *longName = nullptr; - char *longLink = nullptr; - char *fullPath = nullptr; - bool isSkip = false; - bool isSoftlink = false; - int ret = 0; - - // tarSize - fseeko(FilePtr, 0L, SEEK_END); - tarSize = ftello(FilePtr); - - // reback file to begin - fseeko(FilePtr, 0L, SEEK_SET); - if (tarSize % BLOCK_SIZE != 0) { - LOGE("tarfile size should be a multiple of 512 bytes"); - return ERR_FORMAT; - } - - fullPath = (char *)malloc(PATH_MAX_LEN * sizeof(char)); - if (fullPath == nullptr) { - return ERR_MALLOC; - } - - memset_s(fullPath, PATH_MAX_LEN * sizeof(char), 0, PATH_MAX_LEN * sizeof(char)); - - while (1) { - readCnt = fread(buff, 1, BLOCK_SIZE, FilePtr); - if (readCnt < BLOCK_SIZE) { - LOGE("read short than 512 expected, got %{public}zu, tarSize", readCnt); - - // when split unpack, ftell size is over than file really size [0,READ_BUFF_SIZE] - if (!isSplit || readCnt != 0 || ftello(FilePtr) > (tarSize + READ_BUFF_SIZE)) { - ret = ERR_IO; - } - FreePointer(longName, longLink, fullPath); - return ret; - } - - // two empty continuous block indicate end of file - if (IsEmptyBlock(buff)) { - char tailBuff[BLOCK_SIZE] = {0}; - size_t tailRead = 0; - tailRead = fread(tailBuff, 1, BLOCK_SIZE, FilePtr); - if ((tailRead == BLOCK_SIZE) && IsEmptyBlock(tailBuff)) { - LOGI("untarfile is end.Success!"); - FreePointer(longName, longLink, fullPath); - return ret; - } - } - - // check header - TarHeader *tarHeader = (TarHeader *)buff; - if (!IsValidTarBlock(tarHeader)) { - LOGE("isSplit cur size %{public}jd, tarSize %{public}jd", ftello(FilePtr), tarSize); - - // when split unpack, ftell size is over than file really size [0,READ_BUFF_SIZE] - if (!isSplit || ftello(FilePtr) > (tarSize + READ_BUFF_SIZE) || !IsEmptyBlock(buff)) { - ret = ERR_FORMAT; - } - FreePointer(longName, longLink, fullPath); + if (!ProcessTarBlock(buff, type, &isSkip)) { + FreeGlobalPointer(); return ret; } - - // uid & gid - gid_t newGid = 0; - uid_t uid = (uid_t)ParseOctalStr(buff + TUID_BASE, TUID_LEN); - gid_t gid = (gid_t)ParseOctalStr(buff + TGID_BASE, TGID_LEN); - uid_t newUid = FixUpOwnerDirFile(uid, gid, newOwner, newGid); - - // file size & content offset - off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; - pos = ftello(FilePtr); - - // longName & longLink - char *realName = tarHeader->name; - if (longName != nullptr) { - realName = longName; - } - - GenRealPath(rootPath, realName, fullPath); - char *realLink = tarHeader->linkname; - if (longLink != nullptr) { - realLink = longLink; - } - CreateDir(const_cast(rootPath), mode); - switch (tarHeader->typeflag) { - case SPLIT_START_TYPE: - case SPLIT_END_TYPE: - case SPLIT_CONTINUE_TYPE: - if (eCheckSplit == type) { - isSplit = true; - FreePointer(longName, longLink, fullPath); - return ret; - } - case REGTYPE: /* regular file */ - case AREGTYPE: { /* regular file */ - if (eList == type) { - file_names.push_back(std::string(realName)); - file_sizes.push_back(fileSize); - file_data_addrs.push_back(pos); - - fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); - } else if (eUnpack == type) { - char *destBuff = (char *)malloc(READ_BUFF_SIZE * sizeof(char)); - if (destBuff != nullptr) { - FILE *destF = CreateFile(fullPath, mode, tarHeader->typeflag); - bool IsAbort = false; - bool IsInvalid = false; - if (destF != nullptr) { - off_t restSize = fileSize; - size_t readBuffSize = READ_BUFF_SIZE; - - memset_s(destBuff, READ_BUFF_SIZE * sizeof(char), 0, READ_BUFF_SIZE * sizeof(char)); - - while (restSize > 0) { - if (restSize < READ_BUFF_SIZE) { - readBuffSize = restSize; - } - if (readBuffSize != fread(destBuff, sizeof(char), readBuffSize, FilePtr)) { - LOGE("read file content shorter than expect!\n"); - IsInvalid = true; - break; - } - - if (readBuffSize != fwrite(destBuff, sizeof(char), readBuffSize, destF)) { - LOGE("write file content shorter than expect!\n"); - IsInvalid = true; - break; - } - restSize -= readBuffSize; - } - - if (destBuff != nullptr) { - free(destBuff); - destBuff = nullptr; - } - if (destF != nullptr) { - fflush(destF); - (void)fclose(destF); - destF = nullptr; - } - if (IsInvalid) { - unlink(fullPath); - isSkip = true; - } - if (IsAbort) { - FreePointer(longName, longLink, fullPath); - return ret; - } - - // anyway, go to correct pos - fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); - } else { - LOGE("destF is null!"); - fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); - } - } else { - LOGE("malloc memory fail!skip!"); - } - isSkip = false; - } - break; - } - case SYMTYPE: { - CreateSoftlink(realLink, fullPath); - isSoftlink = true; - isSkip = false; - break; - } - case DIRTYPE: { - CreateDir(fullPath, mode); - isSkip = false; - break; - } - case TarUtil::GNUTYPE_LONGNAME: { - if (longName != nullptr) { - free(longName); - longName = nullptr; - } - - size_t nameLen = (size_t)fileSize; - if (nameLen < PATH_MAX_LEN) { - longName = (char *)malloc((nameLen + 1) * sizeof(char)); - } - if (longName != nullptr) { - memset_s(longName, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); - if (nameLen != fread(longName, sizeof(char), nameLen, FilePtr)) { - free(longName); - longName = nullptr; - } - } - - // anyway, go to correct pos - isSkip = true; - fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); - continue; - } - case GNUTYPE_LONGLINK: { - /* long link */ - if (longLink != nullptr) { - free(longLink); - longLink = nullptr; - } - - size_t nameLen = (size_t)fileSize; - if (nameLen < PATH_MAX_LEN) { - longLink = (char *)malloc((nameLen + 1) * sizeof(char)); - } - if (longLink != nullptr) { - memset_s(longLink, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); - if (nameLen != fread(longLink, sizeof(char), nameLen, FilePtr)) { - free(longLink); - longLink = nullptr; - } - } - - // anyway, go to correct pos - isSkip = true; - fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); - continue; - } - default: { - // Ignoring, skip - isSkip = true; - fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); - break; - } - } - - if (!isSkip) { - if (!isSoftlink) { - chmod(fullPath, mode); - chown(fullPath, newUid, newGid); - } else { - lchown(fullPath, newUid, newGid); - isSoftlink = false; - } - } - isSkip = false; - - if (longName != nullptr) { - free(longName); - longName = nullptr; - } - if (longLink != nullptr) { - free(longLink); - longLink = nullptr; - } } - return ret; } -void UnTarFile::FreePointer(char *longName, char *longLink, char *fullPath) +void UnTarFile::FreeGlobalPointer() { - if (fullPath != nullptr) { - free(fullPath); - fullPath = nullptr; + if (g_fullPath != nullptr) { + free(g_fullPath); + g_fullPath = nullptr; } - if (longName != nullptr) { - free(longName); - longName = nullptr; + if (g_longName != nullptr) { + free(g_longName); + g_longName = nullptr; } - if (longLink != nullptr) { - free(longLink); - longLink = nullptr; + if (g_longLink != nullptr) { + free(g_longLink); + g_longLink = nullptr; } } -- Gitee From a68bdcbb623819f4cad9cf0975579c961ac6c1a3 Mon Sep 17 00:00:00 2001 From: yaohua Date: Fri, 18 Apr 2025 15:59:55 +0800 Subject: [PATCH 05/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96-codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- frameworks/native/backup_ext/BUILD.gn | 2 +- ...{InstalldTarUtils.h => installdTarUtils.h} | 0 ...nstalldUnTarFile.h => installdUnTarFile.h} | 7 ++-- .../include/{TarUtil.h => tarUtil.h} | 0 .../native/backup_ext/src/ext_extension.cpp | 2 +- ...lldUnTarFile.cpp => installdUnTarFile.cpp} | 36 ++++++++++++------- 6 files changed, 29 insertions(+), 18 deletions(-) rename frameworks/native/backup_ext/include/{InstalldTarUtils.h => installdTarUtils.h} (100%) rename frameworks/native/backup_ext/include/{InstalldUnTarFile.h => installdUnTarFile.h} (93%) rename frameworks/native/backup_ext/include/{TarUtil.h => tarUtil.h} (100%) rename frameworks/native/backup_ext/src/{InstalldUnTarFile.cpp => installdUnTarFile.cpp} (96%) diff --git a/frameworks/native/backup_ext/BUILD.gn b/frameworks/native/backup_ext/BUILD.gn index 64695e117..4cf968dae 100644 --- a/frameworks/native/backup_ext/BUILD.gn +++ b/frameworks/native/backup_ext/BUILD.gn @@ -34,7 +34,7 @@ ohos_shared_library("backup_extension_ability_native") { "src/ext_backup_loader.cpp", "src/ext_extension.cpp", "src/ext_extension_stub.cpp", - "src/InstalldUnTarFile.cpp", + "src/installdUnTarFile.cpp", "src/sub_ext_extension.cpp", "src/tar_file.cpp", "src/untar_file.cpp", diff --git a/frameworks/native/backup_ext/include/InstalldTarUtils.h b/frameworks/native/backup_ext/include/installdTarUtils.h similarity index 100% rename from frameworks/native/backup_ext/include/InstalldTarUtils.h rename to frameworks/native/backup_ext/include/installdTarUtils.h diff --git a/frameworks/native/backup_ext/include/InstalldUnTarFile.h b/frameworks/native/backup_ext/include/installdUnTarFile.h similarity index 93% rename from frameworks/native/backup_ext/include/InstalldUnTarFile.h rename to frameworks/native/backup_ext/include/installdUnTarFile.h index dee7f4f39..a601ae149 100644 --- a/frameworks/native/backup_ext/include/InstalldUnTarFile.h +++ b/frameworks/native/backup_ext/include/installdUnTarFile.h @@ -17,8 +17,8 @@ #define PHONECLONE_INSTALLDUNTARFILE_H #include #include -#include "InstalldTarUtils.h" -#include "TarUtil.h" +#include "installdTarUtils.h" +#include "tarUtil.h" namespace installd { // helper function. @@ -41,7 +41,7 @@ public: typedef enum { eList = 0, eUnpack = 1, eCheckSplit = 2 } EParseType; private: - bool IsProcessTarEnd(char * buff, int *ret); + bool IsProcessTarEnd(char *buff, int *ret); int ParseTarFile(const char *rootPath = "", EParseType type = eList); bool IsEmptyBlock(const char *p); bool CheckFileAndPath(const char *rootPath, int &ret); @@ -49,6 +49,7 @@ private: void HandleGnuLongLink(char *buff, bool *isSkip); void HandleGnuLongName(char *buff, bool *isSkip); void HandleRegularFile(EParseType type, char *buff, bool *isSkip); + bool FileReadAndWrite(char *destBuff, FILE *destF, size_t readBuffSize); void HandleRegularEUnpackFile(char *buff, bool *isSkip); bool ProcessTarBlock(char *buff, EParseType type, bool *isSkip); bool IsValidTarBlock(const TarHeader *tarHeader); diff --git a/frameworks/native/backup_ext/include/TarUtil.h b/frameworks/native/backup_ext/include/tarUtil.h similarity index 100% rename from frameworks/native/backup_ext/include/TarUtil.h rename to frameworks/native/backup_ext/include/tarUtil.h diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index f50db82de..a2ffbcbab 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -54,11 +54,11 @@ #include "b_utils/b_time.h" #include "filemgmt_libhilog.h" #include "hitrace_meter.h" +#include "installdUnTarFile.h" #include "iservice.h" #include "sandbox_helper.h" #include "service_client.h" #include "tar_file.h" -#include "InstalldUnTarFile.h" namespace OHOS::FileManagement::Backup { const string INDEX_FILE_BACKUP = string(BConstants::PATH_BUNDLE_BACKUP_HOME). diff --git a/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp b/frameworks/native/backup_ext/src/installdUnTarFile.cpp similarity index 96% rename from frameworks/native/backup_ext/src/InstalldUnTarFile.cpp rename to frameworks/native/backup_ext/src/installdUnTarFile.cpp index 38f6663f8..c0d4ef8d4 100644 --- a/frameworks/native/backup_ext/src/InstalldUnTarFile.cpp +++ b/frameworks/native/backup_ext/src/installdUnTarFile.cpp @@ -13,13 +13,13 @@ * limitations under the License. */ -#include "InstalldUnTarFile.h" +#include "installdUnTarFile.h" #include #include +#include #include #include -#include #include #include "securec.h" @@ -28,7 +28,7 @@ namespace installd { const uid_t OCTAL = 8; -const mode_t FILE_MODE = (mode_t)448; +const mode_t FILE_MODE = 448; char *g_longName = nullptr; char *g_longLink = nullptr; char *g_fullPath = nullptr; @@ -405,7 +405,7 @@ void UnTarFile::HandleGnuLongLink(char *buff, bool *isSkip) off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; size_t nameLen = (size_t)fileSize; if (nameLen < PATH_MAX_LEN) { - g_longLink = (char *) ((nameLen + 1) * sizeof(char)); + g_longLink = (char *)((nameLen + 1) * sizeof(char)); } if (g_longLink != nullptr) { memset_s(g_longLink, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); @@ -452,7 +452,7 @@ void UnTarFile::HandleGnuLongName(char *buff, bool *isSkip) // 处理常规文件 void UnTarFile::HandleRegularFile(EParseType type, char *buff, bool *isSkip) { - if (buff == nullptr || isSkip == nullptr || g_fullPath == nullptr || g_realName == nullptr ) { + if (buff == nullptr || isSkip == nullptr || g_fullPath == nullptr || g_realName == nullptr) { return; } off_t pos = ftello(FilePtr); @@ -471,6 +471,23 @@ void UnTarFile::HandleRegularFile(EParseType type, char *buff, bool *isSkip) } } +bool UnTarFile::FileReadAndWrite(char *destBuff, FILE *destF, size_t readBuffSize) +{ + if (destBuff == nullptr || destF == nullptr) { + return false; + } + if (readBuffSize != fread(destBuff, sizeof(char), readBuffSize, FilePtr)) { + LOGE("read file content shorter than expect!\n"); + return false; + } + + if (readBuffSize != fwrite(destBuff, sizeof(char), readBuffSize, destF)) { + LOGE("write file content shorter than expect!\n"); + return false; + } + return true; +} + void UnTarFile::HandleRegularEUnpackFile(char *buff, bool *isSkip) { if (buff == nullptr || isSkip == nullptr || g_fullPath) { @@ -501,14 +518,7 @@ void UnTarFile::HandleRegularEUnpackFile(char *buff, bool *isSkip) if (fileSize < READ_BUFF_SIZE) { readBuffSize = fileSize; } - if (readBuffSize != fread(destBuff, sizeof(char), readBuffSize, FilePtr)) { - LOGE("read file content shorter than expect!\n"); - IsInvalid = true; - break; - } - - if (readBuffSize != fwrite(destBuff, sizeof(char), readBuffSize, destF)) { - LOGE("write file content shorter than expect!\n"); + if (!FileReadAndWrite(destBuff, destF, readBuffSize)) { IsInvalid = true; break; } -- Gitee From 61b2e02cfd4d08c573ec5629ca3a80a5a2b103b8 Mon Sep 17 00:00:00 2001 From: yaohua Date: Fri, 18 Apr 2025 19:13:00 +0800 Subject: [PATCH 06/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96-codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- .../backup_ext/include/installdUnTarFile.h | 26 +- .../backup_ext/src/installdUnTarFile.cpp | 240 ++++++++---------- 2 files changed, 130 insertions(+), 136 deletions(-) diff --git a/frameworks/native/backup_ext/include/installdUnTarFile.h b/frameworks/native/backup_ext/include/installdUnTarFile.h index a601ae149..05c820188 100644 --- a/frameworks/native/backup_ext/include/installdUnTarFile.h +++ b/frameworks/native/backup_ext/include/installdUnTarFile.h @@ -21,6 +21,15 @@ #include "tarUtil.h" namespace installd { + +struct ParseTarPath { + char *longName = nullptr; + char *longLink = nullptr; + char *fullPath = nullptr; + char *realName = nullptr; + char *realLink = nullptr; +}; + // helper function. off_t ParseOctalStr(const char *p, size_t n); @@ -44,19 +53,20 @@ private: bool IsProcessTarEnd(char *buff, int *ret); int ParseTarFile(const char *rootPath = "", EParseType type = eList); bool IsEmptyBlock(const char *p); - bool CheckFileAndPath(const char *rootPath, int &ret); - void SetFileChmodAndChown(char *buff, bool isSoftLink); - void HandleGnuLongLink(char *buff, bool *isSkip); - void HandleGnuLongName(char *buff, bool *isSkip); - void HandleRegularFile(EParseType type, char *buff, bool *isSkip); + int CheckFileAndInitPath(const char *rootPath, ParseTarPath *parseTarPath); + void SetFileChmodAndChown(char *buff, ParseTarPath *parseTarPath, bool isSoftLink); + void HandleGnuLongLink(char *buff, ParseTarPath *parseTarPath, bool &isSkip); + void HandleGnuLongName(char *buff, ParseTarPath *parseTarPath, bool &isSkip); + void HandleRegularFile(EParseType type, char *buff, ParseTarPath *parseTarPath, bool &isSkip); bool FileReadAndWrite(char *destBuff, FILE *destF, size_t readBuffSize); - void HandleRegularEUnpackFile(char *buff, bool *isSkip); - bool ProcessTarBlock(char *buff, EParseType type, bool *isSkip); + void HandleRegularEUnpackFile(char *buff, ParseTarPath *parseTarPath, bool &isSkip); + bool ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip); bool IsValidTarBlock(const TarHeader *tarHeader); bool VerifyChecksum(const TarHeader *tarHeader); bool CheckSliceTar(const char *tarInfo, const char *dstPathName, std::vector &fileNameVector); bool HandleCheckFile(const char *tarBaseName, std::vector &fileNameVector, int &num); - void FreeGlobalPointer(); + void FreePointer(ParseTarPath *parseTarPath); + void FreeLongTypePointer(ParseTarPath *parseTarPath); bool CreateDirWithRecursive(const std::string &filePath, mode_t mode = (mode_t)448); private: diff --git a/frameworks/native/backup_ext/src/installdUnTarFile.cpp b/frameworks/native/backup_ext/src/installdUnTarFile.cpp index c0d4ef8d4..27f72e39c 100644 --- a/frameworks/native/backup_ext/src/installdUnTarFile.cpp +++ b/frameworks/native/backup_ext/src/installdUnTarFile.cpp @@ -23,17 +23,18 @@ #include #include "securec.h" +#include "untar_file.h" #include namespace installd { const uid_t OCTAL = 8; const mode_t FILE_MODE = 448; -char *g_longName = nullptr; -char *g_longLink = nullptr; -char *g_fullPath = nullptr; -char *g_realName = nullptr; -char *g_realLink = nullptr; +// char *g_longName = nullptr; +// char *g_longLink = nullptr; +// char *g_fullPath = nullptr; +// char *g_realName = nullptr; +// char *g_realLink = nullptr; uid_t FixUpOwnerDirFile(const uid_t uid, const gid_t gid, const uid_t owner, gid_t& newGid) { @@ -297,19 +298,16 @@ bool UnTarFile::IsEmptyBlock(const char *p) return ('\0' == p[0]); } -// 检查文件指针和路径 -bool UnTarFile::CheckFileAndPath(const char *rootPath, int &ret) +int UnTarFile::CheckFileAndInitPath(const char *rootPath, ParseTarPath *parseTarPath) { if (FilePtr == nullptr) { LOGE("read tar happened error!\n"); - ret = ERR_PARAM; - return false; + return ERR_PARAM; } if (rootPath == nullptr) { LOGE("rootPath is nullptr!\n"); - ret = ERR_NOEXIST; - return false; + return ERR_NOEXIST; } // tarSize fseeko(FilePtr, 0L, SEEK_END); @@ -318,19 +316,19 @@ bool UnTarFile::CheckFileAndPath(const char *rootPath, int &ret) fseeko(FilePtr, 0L, SEEK_SET); if (tarSize % BLOCK_SIZE != 0) { LOGE("tarfile size should be a multiple of 512 bytes"); - ret = ERR_FORMAT; - return false; + return ERR_FORMAT; } - return true; -} -// 处理 tar 文件块 -bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, bool *isSkip) -{ - if (buff == nullptr || isSkip == nullptr) { - return false; + parseTarPath->fullPath = (char *)malloc(PATH_MAX_LEN * sizeof(char)); + if (parseTarPath->fullPath == nullptr) { + return ERR_MALLOC; } + memset_s(parseTarPath->fullPath, PATH_MAX_LEN * sizeof(char), 0, PATH_MAX_LEN * sizeof(char)); + return 0; +} +bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip) +{ bool isSoftLink = false; TarHeader *tarHeader = (TarHeader *)buff; switch (tarHeader->typeflag) { @@ -343,25 +341,25 @@ bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, bool *isSkip) } case REGTYPE: case AREGTYPE: - HandleRegularFile(type, buff, isSkip); + HandleRegularFile(type, buff, parseTarPath, isSkip); break; case SYMTYPE: - CreateSoftlink(g_realLink, g_fullPath); + CreateSoftlink(parseTarPath->realLink, parseTarPath->fullPath); isSoftLink = true; - *isSkip = false; + isSkip = false; break; case DIRTYPE: - CreateDir(g_fullPath, FILE_MODE); - *isSkip = false; + CreateDir(parseTarPath->fullPath, FILE_MODE); + isSkip = false; break; case TarUtil::GNUTYPE_LONGNAME: - HandleGnuLongName(buff, isSkip); + HandleGnuLongName(buff, parseTarPath, isSkip); return true; case GNUTYPE_LONGLINK: - HandleGnuLongLink(buff, isSkip); + HandleGnuLongLink(buff, parseTarPath, isSkip); return true; default: - *isSkip = true; + isSkip = true; // file size & content offset off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; @@ -369,13 +367,14 @@ bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, bool *isSkip) break; } - if (!*isSkip) { - SetFileChmodAndChown(buff, isSoftLink); + if (!isSkip) { + SetFileChmodAndChown(buff, parseTarPath, isSoftLink); } + FreeLongTypePointer(parseTarPath); return true; } -void UnTarFile::SetFileChmodAndChown(char *buff, bool isSoftLink) +void UnTarFile::SetFileChmodAndChown(char *buff, ParseTarPath *parseTarPath, bool isSoftLink) { // uid & gid gid_t newGid = 0; @@ -383,83 +382,73 @@ void UnTarFile::SetFileChmodAndChown(char *buff, bool isSoftLink) gid_t gid = (gid_t)ParseOctalStr(buff + TGID_BASE, TGID_LEN); uid_t newUid = FixUpOwnerDirFile(uid, gid, newOwner, newGid); if (!isSoftLink) { - chmod(g_fullPath, FILE_MODE); - chown(g_fullPath, newUid, newGid); + chmod(parseTarPath->fullPath, FILE_MODE); + chown(parseTarPath->fullPath, newUid, newGid); } else { - lchown(g_fullPath, newUid, newGid); + lchown(parseTarPath->fullPath, newUid, newGid); } } -void UnTarFile::HandleGnuLongLink(char *buff, bool *isSkip) +void UnTarFile::HandleGnuLongLink(char *buff, ParseTarPath *parseTarPath, bool &isSkip) { - if (buff == nullptr || isSkip == nullptr) { - return; - } /* long link */ - if (g_longLink != nullptr) { - free(g_longLink); - g_longLink = nullptr; + if (parseTarPath->longLink != nullptr) { + free(parseTarPath->longLink); + parseTarPath->longLink = nullptr; } off_t pos = ftello(FilePtr); off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; size_t nameLen = (size_t)fileSize; if (nameLen < PATH_MAX_LEN) { - g_longLink = (char *)((nameLen + 1) * sizeof(char)); + parseTarPath->longLink = (char *)((nameLen + 1) * sizeof(char)); } - if (g_longLink != nullptr) { - memset_s(g_longLink, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); - if (nameLen != fread(g_longLink, sizeof(char), nameLen, FilePtr)) { - free(g_longLink); - g_longLink = nullptr; + if (parseTarPath->longLink != nullptr) { + memset_s(parseTarPath->longLink, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); + if (nameLen != fread(parseTarPath->longLink, sizeof(char), nameLen, FilePtr)) { + free(parseTarPath->longLink); + parseTarPath->longLink = nullptr; } } // anyway, go to correct pos - *isSkip = true; + isSkip = true; fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); } -void UnTarFile::HandleGnuLongName(char *buff, bool *isSkip) +void UnTarFile::HandleGnuLongName(char *buff, ParseTarPath *parseTarPath, bool &isSkip) { - if (isSkip == nullptr) { - return; - } - if (g_longName != nullptr) { - free(g_longName); - g_longName = nullptr; + if (parseTarPath->longName != nullptr) { + free(parseTarPath->longName); + parseTarPath->longName = nullptr; } off_t pos = ftello(FilePtr); off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; size_t nameLen = (size_t)fileSize; if (nameLen < PATH_MAX_LEN) { - g_longName = (char *)malloc((nameLen + 1) * sizeof(char)); + parseTarPath->longName = (char *)malloc((nameLen + 1) * sizeof(char)); } - if (g_longName != nullptr) { - memset_s(g_longName, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); - if (nameLen != fread(g_longName, sizeof(char), nameLen, FilePtr)) { - free(g_longName); - g_longName = nullptr; + if (parseTarPath->longName != nullptr) { + memset_s(parseTarPath->longName, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); + if (nameLen != fread(parseTarPath->longName, sizeof(char), nameLen, FilePtr)) { + free(parseTarPath->longName); + parseTarPath->longName = nullptr; } } // anyway, go to correct pos - *isSkip = true; + isSkip = true; fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); } -// 处理常规文件 -void UnTarFile::HandleRegularFile(EParseType type, char *buff, bool *isSkip) +void UnTarFile::HandleRegularFile(EParseType type, char *buff, ParseTarPath *parseTarPath, bool &isSkip) { - if (buff == nullptr || isSkip == nullptr || g_fullPath == nullptr || g_realName == nullptr) { - return; - } - off_t pos = ftello(FilePtr); - off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; if (eList == type) { - file_names.push_back(std::string(g_realName)); + const off_t pos = ftello(FilePtr); + const off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + const off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + file_names.push_back(std::string(parseTarPath->realName)); file_sizes.push_back(fileSize); file_data_addrs.push_back(pos); @@ -467,15 +456,12 @@ void UnTarFile::HandleRegularFile(EParseType type, char *buff, bool *isSkip) return; } if (eUnpack == type) { - HandleRegularEUnpackFile(buff, isSkip); + HandleRegularEUnpackFile(buff, parseTarPath, isSkip); } } bool UnTarFile::FileReadAndWrite(char *destBuff, FILE *destF, size_t readBuffSize) { - if (destBuff == nullptr || destF == nullptr) { - return false; - } if (readBuffSize != fread(destBuff, sizeof(char), readBuffSize, FilePtr)) { LOGE("read file content shorter than expect!\n"); return false; @@ -488,53 +474,47 @@ bool UnTarFile::FileReadAndWrite(char *destBuff, FILE *destF, size_t readBuffSiz return true; } -void UnTarFile::HandleRegularEUnpackFile(char *buff, bool *isSkip) +void UnTarFile::HandleRegularEUnpackFile(char *buff, ParseTarPath *parseTarPath, bool &isSkip) { - if (buff == nullptr || isSkip == nullptr || g_fullPath) { - return; - } TarHeader *tarHeader = (TarHeader *)buff; - off_t pos = ftello(FilePtr); + const off_t pos = ftello(FilePtr); off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + const off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; char *destBuff = (char *)malloc(READ_BUFF_SIZE * sizeof(char)); if (destBuff == nullptr) { LOGE("malloc memory fail!skip!"); - *isSkip = false; + isSkip = false; return; } memset_s(destBuff, READ_BUFF_SIZE * sizeof(char), 0, READ_BUFF_SIZE * sizeof(char)); - FILE *destF = CreateFile(g_fullPath, FILE_MODE, tarHeader->typeflag); + FILE *destF = CreateFile(parseTarPath->fullPath, FILE_MODE, tarHeader->typeflag); if (destF == nullptr) { LOGE("destF is null!"); + free(destBuff); fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); - *isSkip = false; + isSkip = false; return; } - bool IsInvalid = false; - size_t readBuffSize = READ_BUFF_SIZE; + bool isInvalid = false; + off_t readBuffSize = READ_BUFF_SIZE; while (fileSize > 0) { if (fileSize < READ_BUFF_SIZE) { readBuffSize = fileSize; } if (!FileReadAndWrite(destBuff, destF, readBuffSize)) { - IsInvalid = true; + isInvalid = true; break; } fileSize -= readBuffSize; } - if (destBuff != nullptr) { - free(destBuff); - } - if (destF != nullptr) { - fflush(destF); - (void)fclose(destF); - } - if (IsInvalid) { - unlink(g_fullPath); - *isSkip = true; + free(destBuff); + fflush(destF); + (void)fclose(destF); + if (isInvalid) { + unlink(parseTarPath->fullPath); + isSkip = true; } // anyway, go to correct pos @@ -543,9 +523,6 @@ void UnTarFile::HandleRegularEUnpackFile(char *buff, bool *isSkip) bool UnTarFile::IsProcessTarEnd(char *buff, int *ret) { - if (buff == nullptr || ret == nullptr) { - return true; - } size_t readCnt = fread(buff, 1, BLOCK_SIZE, FilePtr); if (readCnt < BLOCK_SIZE) { LOGE("read short than 512 expected, got %{public}zu, tarSize", readCnt); @@ -584,61 +561,68 @@ bool UnTarFile::IsProcessTarEnd(char *buff, int *ret) int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) { - int ret = 0; - if (!CheckFileAndPath(rootPath, ret)) { + ParseTarPath parseTarPath = {}; + int ret = CheckFileAndInitPath(rootPath, &parseTarPath); + if (ret != 0) { return ret; } LOGI("ParseTarFile"); - FreeGlobalPointer(); - g_fullPath = (char *)malloc(PATH_MAX_LEN * sizeof(char)); - if (g_fullPath == nullptr) { - return ERR_MALLOC; - } - memset_s(g_fullPath, PATH_MAX_LEN * sizeof(char), 0, PATH_MAX_LEN * sizeof(char)); // re-parse tar header char buff[BLOCK_SIZE] = {}; bool isSkip = false; while (true) { if (IsProcessTarEnd(buff, &ret)) { - FreeGlobalPointer(); + FreePointer(&parseTarPath); return ret; } TarHeader *tarHeader = (TarHeader *)buff; - g_realName = tarHeader->name; - if (g_longName != nullptr) { - g_realName = g_longName; + parseTarPath.realName = tarHeader->name; + if (parseTarPath.longName != nullptr) { + parseTarPath.realName = parseTarPath.longName; } - GenRealPath(rootPath, g_realName, g_fullPath); - g_realLink = tarHeader->linkname; - if (g_longLink != nullptr) { - g_realLink = g_longLink; + GenRealPath(rootPath, parseTarPath.realName, parseTarPath.fullPath); + parseTarPath.realLink = tarHeader->linkname; + if (parseTarPath.longLink != nullptr) { + parseTarPath.realLink = parseTarPath.longLink; } CreateDir(const_cast(rootPath), FILE_MODE); - if (!ProcessTarBlock(buff, type, &isSkip)) { - FreeGlobalPointer(); + if (!ProcessTarBlock(buff, type, &parseTarPath, isSkip)) { + FreePointer(&parseTarPath); return ret; } } } -void UnTarFile::FreeGlobalPointer() +void UnTarFile::FreePointer(ParseTarPath *parseTarPath) { - if (g_fullPath != nullptr) { - free(g_fullPath); - g_fullPath = nullptr; + if (parseTarPath->fullPath != nullptr) { + free(parseTarPath->fullPath); + parseTarPath->fullPath = nullptr; } - if (g_longName != nullptr) { - free(g_longName); - g_longName = nullptr; + if (parseTarPath->longName != nullptr) { + free(parseTarPath->longName); + parseTarPath->longName = nullptr; + } + if (parseTarPath->longLink != nullptr) { + free(parseTarPath->longLink); + parseTarPath->longLink = nullptr; + } +} + +void UnTarFile::FreeLongTypePointer(ParseTarPath *parseTarPath) +{ + if (parseTarPath->longName != nullptr) { + free(parseTarPath->longName); + parseTarPath->longName = nullptr; } - if (g_longLink != nullptr) { - free(g_longLink); - g_longLink = nullptr; + if (parseTarPath->longLink != nullptr) { + free(parseTarPath->longLink); + parseTarPath->longLink = nullptr; } } -- Gitee From 65ad654f387bfc9ee44eb8b0bc9e463f3b48d02c Mon Sep 17 00:00:00 2001 From: yaohua Date: Sat, 19 Apr 2025 11:05:10 +0800 Subject: [PATCH 07/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96-codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- .../backup_ext/include/installdUnTarFile.h | 21 ++-- .../backup_ext/src/installdUnTarFile.cpp | 113 +++++++++--------- 2 files changed, 68 insertions(+), 66 deletions(-) diff --git a/frameworks/native/backup_ext/include/installdUnTarFile.h b/frameworks/native/backup_ext/include/installdUnTarFile.h index 05c820188..0de8dfd49 100644 --- a/frameworks/native/backup_ext/include/installdUnTarFile.h +++ b/frameworks/native/backup_ext/include/installdUnTarFile.h @@ -30,6 +30,12 @@ struct ParseTarPath { char *realLink = nullptr; }; +struct TarFileInfo { + off_t fileSize; + off_t fileBlockCnt; + off_t pos; +}; + // helper function. off_t ParseOctalStr(const char *p, size_t n); @@ -50,17 +56,18 @@ public: typedef enum { eList = 0, eUnpack = 1, eCheckSplit = 2 } EParseType; private: - bool IsProcessTarEnd(char *buff, int *ret); + bool IsProcessTarEnd(char *buff, int &ret); int ParseTarFile(const char *rootPath = "", EParseType type = eList); bool IsEmptyBlock(const char *p); int CheckFileAndInitPath(const char *rootPath, ParseTarPath *parseTarPath); - void SetFileChmodAndChown(char *buff, ParseTarPath *parseTarPath, bool isSoftLink); - void HandleGnuLongLink(char *buff, ParseTarPath *parseTarPath, bool &isSkip); - void HandleGnuLongName(char *buff, ParseTarPath *parseTarPath, bool &isSkip); - void HandleRegularFile(EParseType type, char *buff, ParseTarPath *parseTarPath, bool &isSkip); + void SetFileChmodAndChown(char *buff, ParseTarPath *parseTarPath, bool &isSoftLink); + void HandleGnuLongLink(ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo); + void HandleGnuLongName(ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo); + void HandleRegularFile(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip, + TarFileInfo &tarFileInfo); bool FileReadAndWrite(char *destBuff, FILE *destF, size_t readBuffSize); - void HandleRegularEUnpackFile(char *buff, ParseTarPath *parseTarPath, bool &isSkip); - bool ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip); + void HandleRegularEUnpackFile(char *buff, ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo); + bool ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip, bool &isSoftLink); bool IsValidTarBlock(const TarHeader *tarHeader); bool VerifyChecksum(const TarHeader *tarHeader); bool CheckSliceTar(const char *tarInfo, const char *dstPathName, std::vector &fileNameVector); diff --git a/frameworks/native/backup_ext/src/installdUnTarFile.cpp b/frameworks/native/backup_ext/src/installdUnTarFile.cpp index 27f72e39c..c71b67449 100644 --- a/frameworks/native/backup_ext/src/installdUnTarFile.cpp +++ b/frameworks/native/backup_ext/src/installdUnTarFile.cpp @@ -30,11 +30,6 @@ namespace installd { const uid_t OCTAL = 8; const mode_t FILE_MODE = 448; -// char *g_longName = nullptr; -// char *g_longLink = nullptr; -// char *g_fullPath = nullptr; -// char *g_realName = nullptr; -// char *g_realLink = nullptr; uid_t FixUpOwnerDirFile(const uid_t uid, const gid_t gid, const uid_t owner, gid_t& newGid) { @@ -327,10 +322,13 @@ int UnTarFile::CheckFileAndInitPath(const char *rootPath, ParseTarPath *parseTar return 0; } -bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip) +bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip, bool &isSoftLink) { - bool isSoftLink = false; TarHeader *tarHeader = (TarHeader *)buff; + TarFileInfo tarFileInfo = {}; + tarFileInfo.fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); + tarFileInfo.fileBlockCnt = (tarFileInfo.fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; + tarFileInfo.pos = ftello(FilePtr); switch (tarHeader->typeflag) { case SPLIT_START_TYPE: case SPLIT_END_TYPE: @@ -341,7 +339,7 @@ bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parse } case REGTYPE: case AREGTYPE: - HandleRegularFile(type, buff, parseTarPath, isSkip); + HandleRegularFile(buff, type, parseTarPath, isSkip, tarFileInfo); break; case SYMTYPE: CreateSoftlink(parseTarPath->realLink, parseTarPath->fullPath); @@ -353,28 +351,26 @@ bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parse isSkip = false; break; case TarUtil::GNUTYPE_LONGNAME: - HandleGnuLongName(buff, parseTarPath, isSkip); + HandleGnuLongName(parseTarPath, isSkip, tarFileInfo); return true; case GNUTYPE_LONGLINK: - HandleGnuLongLink(buff, parseTarPath, isSkip); + HandleGnuLongLink(parseTarPath, isSkip, tarFileInfo); return true; default: isSkip = true; - // file size & content offset - off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; - fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + fseeko(FilePtr, tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_CUR); break; } if (!isSkip) { SetFileChmodAndChown(buff, parseTarPath, isSoftLink); } + isSkip = false; FreeLongTypePointer(parseTarPath); return true; } -void UnTarFile::SetFileChmodAndChown(char *buff, ParseTarPath *parseTarPath, bool isSoftLink) +void UnTarFile::SetFileChmodAndChown(char *buff, ParseTarPath *parseTarPath, bool &isSoftLink) { // uid & gid gid_t newGid = 0; @@ -384,24 +380,22 @@ void UnTarFile::SetFileChmodAndChown(char *buff, ParseTarPath *parseTarPath, boo if (!isSoftLink) { chmod(parseTarPath->fullPath, FILE_MODE); chown(parseTarPath->fullPath, newUid, newGid); - } else { - lchown(parseTarPath->fullPath, newUid, newGid); + return; } + lchown(parseTarPath->fullPath, newUid, newGid); + isSoftLink = false; } -void UnTarFile::HandleGnuLongLink(char *buff, ParseTarPath *parseTarPath, bool &isSkip) +void UnTarFile::HandleGnuLongLink(ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo) { /* long link */ if (parseTarPath->longLink != nullptr) { free(parseTarPath->longLink); parseTarPath->longLink = nullptr; } - off_t pos = ftello(FilePtr); - off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; - size_t nameLen = (size_t)fileSize; + size_t nameLen = (size_t)tarFileInfo.fileSize; if (nameLen < PATH_MAX_LEN) { - parseTarPath->longLink = (char *)((nameLen + 1) * sizeof(char)); + parseTarPath->longLink = (char *)malloc((nameLen + 1) * sizeof(char)); } if (parseTarPath->longLink != nullptr) { memset_s(parseTarPath->longLink, (nameLen + 1) * sizeof(char), 0, (nameLen + 1) * sizeof(char)); @@ -413,19 +407,16 @@ void UnTarFile::HandleGnuLongLink(char *buff, ParseTarPath *parseTarPath, bool & // anyway, go to correct pos isSkip = true; - fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); + fseeko(FilePtr, tarFileInfo.pos + tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_SET); } -void UnTarFile::HandleGnuLongName(char *buff, ParseTarPath *parseTarPath, bool &isSkip) +void UnTarFile::HandleGnuLongName(ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo) { if (parseTarPath->longName != nullptr) { free(parseTarPath->longName); parseTarPath->longName = nullptr; } - off_t pos = ftello(FilePtr); - off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; - size_t nameLen = (size_t)fileSize; + size_t nameLen = (size_t)tarFileInfo.fileSize; if (nameLen < PATH_MAX_LEN) { parseTarPath->longName = (char *)malloc((nameLen + 1) * sizeof(char)); } @@ -439,24 +430,22 @@ void UnTarFile::HandleGnuLongName(char *buff, ParseTarPath *parseTarPath, bool & // anyway, go to correct pos isSkip = true; - fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); + fseeko(FilePtr, tarFileInfo.pos + tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_SET); } -void UnTarFile::HandleRegularFile(EParseType type, char *buff, ParseTarPath *parseTarPath, bool &isSkip) +void UnTarFile::HandleRegularFile(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip, + TarFileInfo &tarFileInfo) { if (eList == type) { - const off_t pos = ftello(FilePtr); - const off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - const off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; file_names.push_back(std::string(parseTarPath->realName)); - file_sizes.push_back(fileSize); - file_data_addrs.push_back(pos); + file_sizes.push_back(tarFileInfo.fileSize); + file_data_addrs.push_back(tarFileInfo.pos); - fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + fseeko(FilePtr, tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_CUR); return; } if (eUnpack == type) { - HandleRegularEUnpackFile(buff, parseTarPath, isSkip); + HandleRegularEUnpackFile(buff, parseTarPath, isSkip, tarFileInfo); } } @@ -474,54 +463,58 @@ bool UnTarFile::FileReadAndWrite(char *destBuff, FILE *destF, size_t readBuffSiz return true; } -void UnTarFile::HandleRegularEUnpackFile(char *buff, ParseTarPath *parseTarPath, bool &isSkip) +void UnTarFile::HandleRegularEUnpackFile(char *buff, ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo) { TarHeader *tarHeader = (TarHeader *)buff; - const off_t pos = ftello(FilePtr); - off_t fileSize = ParseOctalStr(buff + TSIZE_BASE, TSIZE_LEN); - const off_t fileBlockCnt = (fileSize + BLOCK_SIZE - 1) / BLOCK_SIZE; char *destBuff = (char *)malloc(READ_BUFF_SIZE * sizeof(char)); if (destBuff == nullptr) { LOGE("malloc memory fail!skip!"); isSkip = false; return; } - memset_s(destBuff, READ_BUFF_SIZE * sizeof(char), 0, READ_BUFF_SIZE * sizeof(char)); FILE *destF = CreateFile(parseTarPath->fullPath, FILE_MODE, tarHeader->typeflag); if (destF == nullptr) { LOGE("destF is null!"); free(destBuff); - fseeko(FilePtr, fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + fseeko(FilePtr, tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_CUR); isSkip = false; return; } + memset_s(destBuff, READ_BUFF_SIZE * sizeof(char), 0, READ_BUFF_SIZE * sizeof(char)); bool isInvalid = false; off_t readBuffSize = READ_BUFF_SIZE; - - while (fileSize > 0) { - if (fileSize < READ_BUFF_SIZE) { - readBuffSize = fileSize; + off_t restSize = tarFileInfo.fileSize; + while (restSize > 0) { + if (restSize < READ_BUFF_SIZE) { + readBuffSize = restSize; } if (!FileReadAndWrite(destBuff, destF, readBuffSize)) { isInvalid = true; break; } - fileSize -= readBuffSize; + restSize -= readBuffSize; } - free(destBuff); - fflush(destF); - (void)fclose(destF); + if (destBuff != nullptr) { + free(destBuff); + destBuff = nullptr; + } + if (destF != nullptr) { + fflush(destF); + (void)fclose(destF); + destF = nullptr; + } if (isInvalid) { unlink(parseTarPath->fullPath); isSkip = true; + return; } - + isSkip = false; // anyway, go to correct pos - fseeko(FilePtr, pos + fileBlockCnt * BLOCK_SIZE, SEEK_SET); + fseeko(FilePtr, tarFileInfo.pos + tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_SET); } -bool UnTarFile::IsProcessTarEnd(char *buff, int *ret) +bool UnTarFile::IsProcessTarEnd(char *buff, int &ret) { size_t readCnt = fread(buff, 1, BLOCK_SIZE, FilePtr); if (readCnt < BLOCK_SIZE) { @@ -529,7 +522,7 @@ bool UnTarFile::IsProcessTarEnd(char *buff, int *ret) // when split unpack, ftell size is over than file really size [0,READ_BUFF_SIZE] if (!isSplit || readCnt != 0 || ftello(FilePtr) > (tarSize + READ_BUFF_SIZE)) { - *ret = ERR_IO; + ret = ERR_IO; } return true; } @@ -552,7 +545,7 @@ bool UnTarFile::IsProcessTarEnd(char *buff, int *ret) // when split unpack, ftell size is over than file really size [0,READ_BUFF_SIZE] if (!isSplit || ftello(FilePtr) > (tarSize + READ_BUFF_SIZE) || !IsEmptyBlock(buff)) { - *ret = ERR_FORMAT; + ret = ERR_FORMAT; } return true; } @@ -571,8 +564,9 @@ int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) // re-parse tar header char buff[BLOCK_SIZE] = {}; bool isSkip = false; + bool isSoftLink = false; while (true) { - if (IsProcessTarEnd(buff, &ret)) { + if (IsProcessTarEnd(buff, ret)) { FreePointer(&parseTarPath); return ret; } @@ -591,11 +585,12 @@ int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) CreateDir(const_cast(rootPath), FILE_MODE); - if (!ProcessTarBlock(buff, type, &parseTarPath, isSkip)) { + if (!ProcessTarBlock(buff, type, &parseTarPath, isSkip, isSoftLink)) { FreePointer(&parseTarPath); return ret; } } + return ret; } void UnTarFile::FreePointer(ParseTarPath *parseTarPath) -- Gitee From ca801f9478bf1ca9acecea84dc31c3586d716429 Mon Sep 17 00:00:00 2001 From: yaohua Date: Sat, 19 Apr 2025 11:36:58 +0800 Subject: [PATCH 08/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96-codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- frameworks/native/backup_ext/src/installdUnTarFile.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/frameworks/native/backup_ext/src/installdUnTarFile.cpp b/frameworks/native/backup_ext/src/installdUnTarFile.cpp index c71b67449..23da72b2e 100644 --- a/frameworks/native/backup_ext/src/installdUnTarFile.cpp +++ b/frameworks/native/backup_ext/src/installdUnTarFile.cpp @@ -23,7 +23,6 @@ #include #include "securec.h" -#include "untar_file.h" #include -- Gitee From a923f5faa98c6e13d19c8c0c5d1ba47bf3486db1 Mon Sep 17 00:00:00 2001 From: yaohua Date: Sat, 19 Apr 2025 14:39:05 +0800 Subject: [PATCH 09/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96-tdd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- test/fuzztest/backupext_fuzzer/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/test/fuzztest/backupext_fuzzer/BUILD.gn b/test/fuzztest/backupext_fuzzer/BUILD.gn index a3772fd76..967cf212b 100644 --- a/test/fuzztest/backupext_fuzzer/BUILD.gn +++ b/test/fuzztest/backupext_fuzzer/BUILD.gn @@ -40,6 +40,7 @@ ohos_fuzztest("BackupExtFuzzTest") { "${path_backup}/frameworks/native/backup_ext/src/ext_backup_loader.cpp", "${path_backup}/frameworks/native/backup_ext/src/ext_extension.cpp", "${path_backup}/frameworks/native/backup_ext/src/ext_extension_stub.cpp", + "${path_backup}/frameworks/native/backup_ext/src/installdUnTarFile.cpp", "${path_backup}/frameworks/native/backup_ext/src/sub_ext_extension.cpp", "${path_backup}/frameworks/native/backup_ext/src/tar_file.cpp", "${path_backup}/frameworks/native/backup_ext/src/untar_file.cpp", -- Gitee From 7d8dd3bc4464168f9606b6395fb7359201bf5e0a Mon Sep 17 00:00:00 2001 From: yaohua Date: Sat, 19 Apr 2025 15:25:11 +0800 Subject: [PATCH 10/10] =?UTF-8?q?tar=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96-tdd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- tests/unittests/backup_ext/BUILD.gn | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unittests/backup_ext/BUILD.gn b/tests/unittests/backup_ext/BUILD.gn index 3257f81f0..06f7fb755 100644 --- a/tests/unittests/backup_ext/BUILD.gn +++ b/tests/unittests/backup_ext/BUILD.gn @@ -136,6 +136,7 @@ ohos_unittest("tar_file_test") { "${path_backup}/frameworks/native/backup_ext/src/ext_backup_loader.cpp", "${path_backup}/frameworks/native/backup_ext/src/ext_extension.cpp", "${path_backup}/frameworks/native/backup_ext/src/ext_extension_stub.cpp", + "${path_backup}/frameworks/native/backup_ext/src/installdUnTarFile.cpp", "${path_backup}/frameworks/native/backup_ext/src/sub_ext_extension.cpp", "${path_backup}/frameworks/native/backup_ext/src/tar_file.cpp", "${path_backup}/frameworks/native/backup_ext/src/untar_file.cpp", @@ -209,6 +210,7 @@ ohos_unittest("untar_file_sup_test") { "${path_backup}/frameworks/native/backup_ext/src/ext_backup_loader.cpp", "${path_backup}/frameworks/native/backup_ext/src/ext_extension.cpp", "${path_backup}/frameworks/native/backup_ext/src/ext_extension_stub.cpp", + "${path_backup}/frameworks/native/backup_ext/src/installdUnTarFile.cpp", "${path_backup}/frameworks/native/backup_ext/src/sub_ext_extension.cpp", "${path_backup}/frameworks/native/backup_ext/src/tar_file.cpp", "${path_backup}/tests/mock/library_func_mock/library_func_mock.cpp", @@ -283,6 +285,7 @@ ohos_unittest("untar_file_test") { "${path_backup}/frameworks/native/backup_ext/src/ext_backup_loader.cpp", "${path_backup}/frameworks/native/backup_ext/src/ext_extension.cpp", "${path_backup}/frameworks/native/backup_ext/src/ext_extension_stub.cpp", + "${path_backup}/frameworks/native/backup_ext/src/installdUnTarFile.cpp", "${path_backup}/frameworks/native/backup_ext/src/sub_ext_extension.cpp", "${path_backup}/frameworks/native/backup_ext/src/tar_file.cpp", "${path_backup}/frameworks/native/backup_ext/src/untar_file.cpp", -- Gitee