From fbb23d6a22692342e41d97bbc18720569a2bef70 Mon Sep 17 00:00:00 2001 From: yaohua Date: Thu, 17 Apr 2025 09:01:49 +0800 Subject: [PATCH 1/7] =?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 e6e445de615195ce4fe87f94969a1e2c26faaba1 Mon Sep 17 00:00:00 2001 From: yaohua Date: Sat, 19 Apr 2025 15:52:16 +0800 Subject: [PATCH 2/7] =?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=E6=95=B4=E6=94=B9?= 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} | 34 +- .../include/{TarUtil.h => tarUtil.h} | 0 .../native/backup_ext/src/ext_extension.cpp | 2 +- ...lldUnTarFile.cpp => installdUnTarFile.cpp} | 514 ++++++++++-------- test/fuzztest/backupext_fuzzer/BUILD.gn | 1 + tests/unittests/backup_ext/BUILD.gn | 3 + 8 files changed, 313 insertions(+), 243 deletions(-) rename frameworks/native/backup_ext/include/{InstalldTarUtils.h => installdTarUtils.h} (100%) rename frameworks/native/backup_ext/include/{InstalldUnTarFile.h => installdUnTarFile.h} (60%) rename frameworks/native/backup_ext/include/{TarUtil.h => tarUtil.h} (100%) rename frameworks/native/backup_ext/src/{InstalldUnTarFile.cpp => installdUnTarFile.cpp} (57%) diff --git a/frameworks/native/backup_ext/BUILD.gn b/frameworks/native/backup_ext/BUILD.gn index 35f7fbf65..4cf968dae 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 = [ 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 60% rename from frameworks/native/backup_ext/include/InstalldUnTarFile.h rename to frameworks/native/backup_ext/include/installdUnTarFile.h index e51ed8b58..0de8dfd49 100644 --- a/frameworks/native/backup_ext/include/InstalldUnTarFile.h +++ b/frameworks/native/backup_ext/include/installdUnTarFile.h @@ -17,10 +17,25 @@ #define PHONECLONE_INSTALLDUNTARFILE_H #include #include -#include "InstalldTarUtils.h" -#include "TarUtil.h" +#include "installdTarUtils.h" +#include "tarUtil.h" namespace installd { + +struct ParseTarPath { + char *longName = nullptr; + char *longLink = nullptr; + char *fullPath = nullptr; + char *realName = nullptr; + 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); @@ -41,13 +56,24 @@ public: typedef enum { eList = 0, eUnpack = 1, eCheckSplit = 2 } EParseType; private: - int ParseTarFile(const char *rootPath = "", UnTarFile::EParseType type = eList); + 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(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, 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); bool HandleCheckFile(const char *tarBaseName, std::vector &fileNameVector, int &num); - void FreePointer(char *longName, char *longLink, char *fullPath); + 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/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 57% rename from frameworks/native/backup_ext/src/InstalldUnTarFile.cpp rename to frameworks/native/backup_ext/src/installdUnTarFile.cpp index 96759236c..e0d43e5a5 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,6 +28,7 @@ namespace installd { const uid_t OCTAL = 8; +const mode_t FILE_MODE = 448; uid_t FixUpOwnerDirFile(const uid_t uid, const gid_t gid, const uid_t owner, gid_t& newGid) { @@ -291,7 +292,7 @@ bool UnTarFile::IsEmptyBlock(const char *p) return ('\0' == p[0]); } -int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) +int UnTarFile::CheckFileAndInitPath(const char *rootPath, ParseTarPath *parseTarPath) { if (FilePtr == nullptr) { LOGE("read tar happened error!\n"); @@ -302,23 +303,9 @@ int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) 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) { @@ -326,257 +313,310 @@ int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) return ERR_FORMAT; } - fullPath = (char *)malloc(PATH_MAX_LEN * sizeof(char)); - if (fullPath == nullptr) { + 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; +} - memset_s(fullPath, PATH_MAX_LEN * sizeof(char), 0, PATH_MAX_LEN * sizeof(char)); +bool UnTarFile::ProcessTarBlock(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip, bool &isSoftLink) +{ + 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: + case SPLIT_CONTINUE_TYPE: + if (eCheckSplit == type) { + isSplit = true; + return false; + } + case REGTYPE: + case AREGTYPE: + HandleRegularFile(buff, type, parseTarPath, isSkip, tarFileInfo); + break; + case SYMTYPE: + CreateSoftlink(parseTarPath->realLink, parseTarPath->fullPath); + isSoftLink = true; + isSkip = false; + break; + case DIRTYPE: + CreateDir(parseTarPath->fullPath, FILE_MODE); + isSkip = false; + break; + case TarUtil::GNUTYPE_LONGNAME: + HandleGnuLongName(parseTarPath, isSkip, tarFileInfo); + return true; + case GNUTYPE_LONGLINK: + HandleGnuLongLink(parseTarPath, isSkip, tarFileInfo); + return true; + default: + isSkip = true; + fseeko(FilePtr, tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + break; + } - while (1) { - readCnt = fread(buff, 1, BLOCK_SIZE, FilePtr); - if (readCnt < BLOCK_SIZE) { - LOGE("read short than 512 expected, got %{public}zu, tarSize", readCnt); + if (!isSkip) { + SetFileChmodAndChown(buff, parseTarPath, isSoftLink); + } + isSkip = false; + FreeLongTypePointer(parseTarPath); + return true; +} - // 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; +void UnTarFile::SetFileChmodAndChown(char *buff, ParseTarPath *parseTarPath, 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(parseTarPath->fullPath, FILE_MODE); + chown(parseTarPath->fullPath, newUid, newGid); + return; + } + lchown(parseTarPath->fullPath, newUid, newGid); + isSoftLink = false; +} + +void UnTarFile::HandleGnuLongLink(ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo) +{ + /* long link */ + if (parseTarPath->longLink != nullptr) { + free(parseTarPath->longLink); + parseTarPath->longLink = nullptr; + } + size_t nameLen = (size_t)tarFileInfo.fileSize; + if (nameLen < PATH_MAX_LEN) { + 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)); + if (nameLen != fread(parseTarPath->longLink, sizeof(char), nameLen, FilePtr)) { + free(parseTarPath->longLink); + parseTarPath->longLink = nullptr; } + } - // 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; - } + // anyway, go to correct pos + isSkip = true; + fseeko(FilePtr, tarFileInfo.pos + tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_SET); +} + +void UnTarFile::HandleGnuLongName(ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo) +{ + if (parseTarPath->longName != nullptr) { + free(parseTarPath->longName); + parseTarPath->longName = nullptr; + } + size_t nameLen = (size_t)tarFileInfo.fileSize; + if (nameLen < PATH_MAX_LEN) { + parseTarPath->longName = (char *)malloc((nameLen + 1) * sizeof(char)); + } + 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; } + } - // check header - TarHeader *tarHeader = (TarHeader *)buff; - if (!IsValidTarBlock(tarHeader)) { - LOGE("isSplit cur size %{public}jd, tarSize %{public}jd", ftello(FilePtr), tarSize); + // anyway, go to correct pos + isSkip = true; + fseeko(FilePtr, tarFileInfo.pos + tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_SET); +} - // 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; +void UnTarFile::HandleRegularFile(char *buff, EParseType type, ParseTarPath *parseTarPath, bool &isSkip, + TarFileInfo &tarFileInfo) +{ + if (eList == type) { + file_names.push_back(std::string(parseTarPath->realName)); + file_sizes.push_back(tarFileInfo.fileSize); + file_data_addrs.push_back(tarFileInfo.pos); + + fseeko(FilePtr, tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_CUR); + return; + } + if (eUnpack == type) { + HandleRegularEUnpackFile(buff, parseTarPath, isSkip, tarFileInfo); + } +} + +bool UnTarFile::FileReadAndWrite(char *destBuff, FILE *destF, size_t readBuffSize) +{ + 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, ParseTarPath *parseTarPath, bool &isSkip, TarFileInfo &tarFileInfo) +{ + TarHeader *tarHeader = (TarHeader *)buff; + char *destBuff = (char *)malloc(READ_BUFF_SIZE * sizeof(char)); + if (destBuff == nullptr) { + LOGE("malloc memory fail!skip!"); + isSkip = false; + return; + } + FILE *destF = CreateFile(parseTarPath->fullPath, FILE_MODE, tarHeader->typeflag); + if (destF == nullptr) { + LOGE("destF is null!"); + free(destBuff); + 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; + off_t restSize = tarFileInfo.fileSize; + while (restSize > 0) { + if (restSize < READ_BUFF_SIZE) { + readBuffSize = restSize; } + if (!FileReadAndWrite(destBuff, destF, readBuffSize)) { + isInvalid = true; + break; + } + restSize -= readBuffSize; + } - // mode - mode_t mode = (mode_t) 448; + if (destBuff != nullptr) { + free(destBuff); + destBuff = nullptr; + } + if (destF != nullptr) { + fflush(destF); + (void)fclose(destF); + destF = nullptr; + } + if (isInvalid) { + unlink(parseTarPath->fullPath); + isSkip = true; + } else { + isSkip = false; + } + // anyway, go to correct pos + fseeko(FilePtr, tarFileInfo.pos + tarFileInfo.fileBlockCnt * BLOCK_SIZE, SEEK_SET); +} - // 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); +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); - // 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); + // 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; + } - // longName & longLink - char *realName = tarHeader->name; - if (longName != nullptr) { - realName = longName; + // 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; } + } - GenRealPath(rootPath, realName, fullPath); - char *realLink = tarHeader->linkname; - if (longLink != nullptr) { - realLink = longLink; + // 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; } - 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; - } + return true; + } + return false; +} + +int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) +{ + ParseTarPath parseTarPath = {}; + int ret = CheckFileAndInitPath(rootPath, &parseTarPath); + if (ret != 0) { + return ret; + } + LOGI("ParseTarFile"); + + // re-parse tar header + char buff[BLOCK_SIZE] = {}; + bool isSkip = false; + bool isSoftLink = false; + while (true) { + if (IsProcessTarEnd(buff, ret)) { + FreePointer(&parseTarPath); + return ret; } - if (!isSkip) { - if (!isSoftlink) { - chmod(fullPath, mode); - chown(fullPath, newUid, newGid); - } else { - lchown(fullPath, newUid, newGid); - isSoftlink = false; - } + TarHeader *tarHeader = (TarHeader *)buff; + parseTarPath.realName = tarHeader->name; + if (parseTarPath.longName != nullptr) { + parseTarPath.realName = parseTarPath.longName; } - isSkip = false; - if (longName != nullptr) { - free(longName); - longName = nullptr; + GenRealPath(rootPath, parseTarPath.realName, parseTarPath.fullPath); + parseTarPath.realLink = tarHeader->linkname; + if (parseTarPath.longLink != nullptr) { + parseTarPath.realLink = parseTarPath.longLink; } - if (longLink != nullptr) { - free(longLink); - longLink = nullptr; + + CreateDir(const_cast(rootPath), FILE_MODE); + + if (!ProcessTarBlock(buff, type, &parseTarPath, isSkip, isSoftLink)) { + FreePointer(&parseTarPath); + return ret; } } return ret; } -void UnTarFile::FreePointer(char *longName, char *longLink, char *fullPath) +void UnTarFile::FreePointer(ParseTarPath *parseTarPath) { - if (fullPath != nullptr) { - free(fullPath); - fullPath = nullptr; + if (parseTarPath->fullPath != nullptr) { + free(parseTarPath->fullPath); + parseTarPath->fullPath = nullptr; + } + if (parseTarPath->longName != nullptr) { + free(parseTarPath->longName); + parseTarPath->longName = nullptr; + } + if (parseTarPath->longLink != nullptr) { + free(parseTarPath->longLink); + parseTarPath->longLink = nullptr; } - if (longName != nullptr) { - free(longName); - longName = nullptr; +} + +void UnTarFile::FreeLongTypePointer(ParseTarPath *parseTarPath) +{ + if (parseTarPath->longName != nullptr) { + free(parseTarPath->longName); + parseTarPath->longName = nullptr; } - if (longLink != nullptr) { - free(longLink); - longLink = nullptr; + if (parseTarPath->longLink != nullptr) { + free(parseTarPath->longLink); + parseTarPath->longLink = nullptr; } } 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", 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 From f453be2710709ba724000e706294cccdd9c305c3 Mon Sep 17 00:00:00 2001 From: yaohua Date: Tue, 22 Apr 2025 14:59:03 +0800 Subject: [PATCH 3/7] =?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=E6=95=B4=E6=94=B9?= 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 +- .../include/{installdTarUtils.h => installd_tar_utils.h} | 0 .../include/{installdUnTarFile.h => installd_un_tar_file.h} | 6 +++--- .../native/backup_ext/include/{tarUtil.h => tar_util.h} | 0 frameworks/native/backup_ext/src/ext_extension.cpp | 2 +- .../src/{installdUnTarFile.cpp => installd_un_tar_file.cpp} | 2 +- test/fuzztest/backupext_fuzzer/BUILD.gn | 2 +- tests/unittests/backup_ext/BUILD.gn | 6 +++--- 8 files changed, 10 insertions(+), 10 deletions(-) rename frameworks/native/backup_ext/include/{installdTarUtils.h => installd_tar_utils.h} (100%) rename frameworks/native/backup_ext/include/{installdUnTarFile.h => installd_un_tar_file.h} (98%) rename frameworks/native/backup_ext/include/{tarUtil.h => tar_util.h} (100%) rename frameworks/native/backup_ext/src/{installdUnTarFile.cpp => installd_un_tar_file.cpp} (99%) diff --git a/frameworks/native/backup_ext/BUILD.gn b/frameworks/native/backup_ext/BUILD.gn index 4cf968dae..13b68d5c6 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/installd_un_tar_file.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/installd_tar_utils.h similarity index 100% rename from frameworks/native/backup_ext/include/installdTarUtils.h rename to frameworks/native/backup_ext/include/installd_tar_utils.h diff --git a/frameworks/native/backup_ext/include/installdUnTarFile.h b/frameworks/native/backup_ext/include/installd_un_tar_file.h similarity index 98% rename from frameworks/native/backup_ext/include/installdUnTarFile.h rename to frameworks/native/backup_ext/include/installd_un_tar_file.h index 0de8dfd49..1d35bbb5a 100644 --- a/frameworks/native/backup_ext/include/installdUnTarFile.h +++ b/frameworks/native/backup_ext/include/installd_un_tar_file.h @@ -15,10 +15,10 @@ #ifndef PHONECLONE_INSTALLDUNTARFILE_H #define PHONECLONE_INSTALLDUNTARFILE_H -#include +#include "installd_tar_utils.h" +#include "tar_util.h" #include -#include "installdTarUtils.h" -#include "tarUtil.h" +#include namespace installd { diff --git a/frameworks/native/backup_ext/include/tarUtil.h b/frameworks/native/backup_ext/include/tar_util.h similarity index 100% rename from frameworks/native/backup_ext/include/tarUtil.h rename to frameworks/native/backup_ext/include/tar_util.h diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index a2ffbcbab..c5e57f971 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -54,7 +54,7 @@ #include "b_utils/b_time.h" #include "filemgmt_libhilog.h" #include "hitrace_meter.h" -#include "installdUnTarFile.h" +#include "installd_un_tar_file.h" #include "iservice.h" #include "sandbox_helper.h" #include "service_client.h" diff --git a/frameworks/native/backup_ext/src/installdUnTarFile.cpp b/frameworks/native/backup_ext/src/installd_un_tar_file.cpp similarity index 99% rename from frameworks/native/backup_ext/src/installdUnTarFile.cpp rename to frameworks/native/backup_ext/src/installd_un_tar_file.cpp index e0d43e5a5..57c07a619 100644 --- a/frameworks/native/backup_ext/src/installdUnTarFile.cpp +++ b/frameworks/native/backup_ext/src/installd_un_tar_file.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "installdUnTarFile.h" +#include "installd_un_tar_file.h" #include #include diff --git a/test/fuzztest/backupext_fuzzer/BUILD.gn b/test/fuzztest/backupext_fuzzer/BUILD.gn index 967cf212b..b444f6c94 100644 --- a/test/fuzztest/backupext_fuzzer/BUILD.gn +++ b/test/fuzztest/backupext_fuzzer/BUILD.gn @@ -40,7 +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/installd_un_tar_file.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", diff --git a/tests/unittests/backup_ext/BUILD.gn b/tests/unittests/backup_ext/BUILD.gn index 06f7fb755..ddedb28a3 100644 --- a/tests/unittests/backup_ext/BUILD.gn +++ b/tests/unittests/backup_ext/BUILD.gn @@ -136,7 +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/installd_un_tar_file.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", @@ -210,7 +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/installd_un_tar_file.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", @@ -285,7 +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/installd_un_tar_file.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 bfd029927d2ceb70ab692ba14dda5329b197c128 Mon Sep 17 00:00:00 2001 From: yaohua Date: Tue, 22 Apr 2025 22:13:32 +0800 Subject: [PATCH 4/7] =?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=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- frameworks/native/backup_ext/src/installd_un_tar_file.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frameworks/native/backup_ext/src/installd_un_tar_file.cpp b/frameworks/native/backup_ext/src/installd_un_tar_file.cpp index 57c07a619..da86712a3 100644 --- a/frameworks/native/backup_ext/src/installd_un_tar_file.cpp +++ b/frameworks/native/backup_ext/src/installd_un_tar_file.cpp @@ -564,7 +564,8 @@ int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) char buff[BLOCK_SIZE] = {}; bool isSkip = false; bool isSoftLink = false; - while (true) { + const off_t blockCnt = tarSize / BLOCK_SIZE; + for (off_t i = 0; i < blockCnt; i++) { if (IsProcessTarEnd(buff, ret)) { FreePointer(&parseTarPath); return ret; @@ -589,6 +590,8 @@ int UnTarFile::ParseTarFile(const char *rootPath, EParseType type) return ret; } } + LOGI("blockCnt overflow"); + FreePointer(&parseTarPath); return ret; } -- Gitee From f0c2d09f8b4ea3e7ff816934c696bf1b1e492e13 Mon Sep 17 00:00:00 2001 From: yaohua Date: Thu, 24 Apr 2025 19:44:21 +0800 Subject: [PATCH 5/7] =?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-ut?= 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 | 36 ++ .../backup_ext/installd_un_tar_file_test.cpp | 334 ++++++++++++++++++ 2 files changed, 370 insertions(+) create mode 100644 tests/unittests/backup_ext/installd_un_tar_file_test.cpp diff --git a/tests/unittests/backup_ext/BUILD.gn b/tests/unittests/backup_ext/BUILD.gn index f7e6b7373..d363e6a35 100644 --- a/tests/unittests/backup_ext/BUILD.gn +++ b/tests/unittests/backup_ext/BUILD.gn @@ -445,6 +445,41 @@ ohos_unittest("tar_file_sub_test") { use_exceptions = true } +ohos_unittest("installd_un_tar_file_test") { + module_out_path = path_module_out_tests + + sources = [ + "${path_backup}/frameworks/native/backup_ext/src/installd_un_tar_file.cpp", + "installd_un_tar_file_test.cpp", + ] + + include_dirs = [ + "${path_backup}/frameworks/native/backup_ext/include", + "${path_backup}/interfaces/common/include", + "${path_backup}/utils/include", + ] + + cflags = [ "--coverage" ] + ldflags = [ "--coverage" ] + cflags_cc = [ "--coverage" ] + + deps = [ + "${path_backup}/utils:backup_utils", + "${path_backup}/tests/utils:backup_test_utils", + ] + + external_deps = [ + "c_utils:utils", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + ] + + defines = [ "private=public" ] + + use_exceptions = true +} + group("backup_ext_test") { testonly = true if (!use_libfuzzer) { @@ -455,6 +490,7 @@ group("backup_ext_test") { ":tar_file_test", ":untar_file_sup_test", ":untar_file_test", + ":installd_un_tar_file_test", ] } } diff --git a/tests/unittests/backup_ext/installd_un_tar_file_test.cpp b/tests/unittests/backup_ext/installd_un_tar_file_test.cpp new file mode 100644 index 000000000..df40cb7cf --- /dev/null +++ b/tests/unittests/backup_ext/installd_un_tar_file_test.cpp @@ -0,0 +1,334 @@ +/* + * 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 +#include + +#include "installd_un_tar_file.h" + +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "test_manager.h" + +#include + +namespace OHOS::FileManagement::Backup { +using namespace std; +using namespace testing; + +class InstalldUnTarFileTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(); + void SetUp() override {}; + void TearDown() override {}; +}; + +void InstalldUnTarFileTest::SetUpTestCase() +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest::SetUpTestCase enter"; +} + +void InstalldUnTarFileTest::TearDownTestCase() +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest::TearDownTestCase enter"; +} + +static string CreateUnSplitTar(const string &rootPath, const string &rootPathSubPath, int32_t innerFileCount) +{ + try { + string testDir = rootPath + rootPathSubPath; + if (mkdir(testDir.data(), S_IRWXU) && errno != EEXIST) { + GTEST_LOG_(INFO) << " invoked mkdir failure, errno :" << errno; + throw BError(errno); + } + for (int i = 0; i < innerFileCount; ++i) { + string file = testDir + "/" + to_string(i + 1) + ".txt"; + SaveStringToFile(file, "hello" + to_string(i)); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an access: " << access(file.c_str(), F_OK); + } + + string tarFile = rootPath + "testUnSplit.tar"; + string cmd = "tar -cvf " + tarFile + " " + testDir; + if (system(cmd.c_str()) != 0) { + GTEST_LOG_(INFO) << " execute tar failure, errno :" << errno; + throw BError(errno); + } + return tarFile; + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by CreateUnSplitTar."; + } + return ""; +} + +static vector CreateSplitTar(const string& rootPath, const string& rootPathSubPath) +{ + try { + const string testDir = rootPath + rootPathSubPath; + vector needCreateDir = {testDir, testDir + "/dir1", testDir + "/dir1/dir2", testDir + "/dir3", + testDir + "/dir4"}; + for (const auto &dir : needCreateDir) { + if (mkdir(dir.data(), S_IRWXU) && errno != EEXIST) { + throw BError(errno); + } + } + constexpr int32_t fileCount = 5; + for (auto i = 0; i < needCreateDir.size(); ++i) { + string file = needCreateDir[i] + "/" + to_string(i) + ".txt"; + string data = ""; + for (auto j = 0; j < fileCount * (i + 1); ++j) { + data += "test data 123456789"; + } + SaveStringToFile(file, data); + } + + string tarDir = rootPath + "testTar"; + if (mkdir(tarDir.data(), S_IRWXU) && errno != EEXIST) { + throw BError(errno); + } + + string tarPath = tarDir + "/test.tar"; + string softlinkCmd = "cd " + testDir + "/dir4" + " && ln -s " + testDir + "/dir4/4.txt ./4_new.txt"; + string tarCmd = "tar -cvf " + tarPath + " " + testDir; + string splitTarCmd = "cd " + tarDir + " && split -b 4k -a 2 test.tar test.tar."; + vector cmds = {softlinkCmd, tarCmd, splitTarCmd}; + + for (const string& cmd : cmds) { + if (system(cmd.c_str()) != 0) { + throw BError(errno); + } + } + vector res; + for (const auto& entry : std::filesystem::directory_iterator(tarDir)) { + if (entry.path().filename() != "test.tar") { + res.push_back(entry.path().string()); + } + } + return res; + } catch (...) { + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by CreateSplitTar."; + } + return {}; +} + +/** + * @tc.number: Installd_Un_Tar_File_UnTarFile_0100 + * @tc.name: Installd_Un_Tar_File_UnTarFile_0100 + * @tc.desc: test File_UnTarFile gen + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC15LE + */ +HWTEST_F(InstalldUnTarFileTest, Installd_Un_Tar_File_UnTarFile_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin Installd_Un_Tar_File_UnTarFile_0100"; + try { + char *tarPath = nullptr; + installd::UnTarFile unTarFile(tarPath); + + const char *tarPath2 = string("/data/test/backup/test.tar").c_str(); + installd::UnTarFile unTarFile2(tarPath2); + + EXPECT_TRUE(true); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by InstalldUnTarFile."; + } + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-end Installd_Un_Tar_File_UnTarFile_0100"; +} + +/** + * @tc.number: Installd_Un_Tar_File_CheckIsSplitTar_0100 + * @tc.name: Installd_Un_Tar_File_CheckIsSplitTar_0100 + * @tc.desc: test File_CheckIsSplitTar method + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC15LE + */ +HWTEST_F(InstalldUnTarFileTest, Installd_Un_Tar_File_CheckIsSplitTar_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin Installd_Un_Tar_File_CheckIsSplitTar_0100"; + try { + const TestManager tm("Installd_Un_Tar_File_CheckIsSplitTar_0100"); + const string rootPath = tm.GetRootDirCurTest(); + constexpr int32_t innerFileCount = 10; + const string tarPath = CreateUnSplitTar(rootPath, "testTarPath", innerFileCount); + EXPECT_FALSE(tarPath.empty()); + installd::UnTarFile unTarFile(rootPath.c_str()); + const bool ret = unTarFile.CheckIsSplitTar(tarPath, rootPath); + EXPECT_FALSE(ret); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by InstalldUnTarFile."; + } + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-end Installd_Un_Tar_File_CheckIsSplitTar_0100"; +} + +/** + * @tc.number: Installd_Un_Tar_File_IsEmptyBlock_0100 + * @tc.name: Installd_Un_Tar_File_IsEmptyBlock_0100 + * @tc.desc: test File_IsEmptyBlock method + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC15LE + */ +HWTEST_F(InstalldUnTarFileTest, Installd_Un_Tar_File_IsEmptyBlock_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin Installd_Un_Tar_File_IsEmptyBlock_0100"; + try { + const char *p = "\0"; + installd::UnTarFile unTarFile(nullptr); + bool ret = unTarFile.IsEmptyBlock(p); + EXPECT_TRUE(ret); + + const char *p1 = "test"; + installd::UnTarFile unTarFile1(nullptr); + ret = unTarFile.IsEmptyBlock(p1); + EXPECT_FALSE(ret); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by InstalldUnTarFile."; + } + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-end Installd_Un_Tar_File_IsEmptyBlock_0100"; +} + +/** + * @tc.number: Installd_Un_Tar_File_CreateDirWithRecursive_0100 + * @tc.name: Installd_Un_Tar_File_CreateDirWithRecursive_0100 + * @tc.desc: test File_CreateDirWithRecursive method + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC15LE + */ +HWTEST_F(InstalldUnTarFileTest, Installd_Un_Tar_File_CreateDirWithRecursive_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin Installd_Un_Tar_File_CreateDirWithRecursive_0100"; + try { + installd::UnTarFile unTarFile(nullptr); + mode_t mode = (mode_t)448; + bool ret = unTarFile.CreateDirWithRecursive("", mode); + EXPECT_FALSE(ret); + + TestManager tm("Installd_Un_Tar_File_CreateDirWithRecursive_0100"); + string root = tm.GetRootDirCurTest(); + ret = unTarFile.CreateDirWithRecursive(root, mode); + EXPECT_TRUE(ret); + + string destPath(root + "/testDir/test1/test2"); + ret = unTarFile.CreateDirWithRecursive(destPath, mode); + EXPECT_TRUE(ret); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by InstalldUnTarFile."; + } + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-end Installd_Un_Tar_File_CreateDirWithRecursive_0100"; +} + +/** + * @tc.number: Installd_Un_Tar_File_UnSplitTar_0100 + * @tc.name: Installd_Un_Tar_File_UnSplitTar_0100 + * @tc.desc: test File_UnSplitTar method + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC15LE + */ +HWTEST_F(InstalldUnTarFileTest, Installd_Un_Tar_File_UnSplitTar_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin Installd_Un_Tar_File_UnSplitTar_0100"; + try { + TestManager tm("Installd_Un_Tar_File_UnSplitTar_0100"); + string rootPath = tm.GetRootDirCurTest(); + vector splitTarList = CreateSplitTar(rootPath, "testTarFile"); + EXPECT_FALSE(splitTarList.empty()); + + installd::UnTarFile unTarFile(nullptr); + for (auto& tarName : splitTarList) { + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin tarName: " << tarName; + auto ret = unTarFile.UnSplitTar(tarName, rootPath); + EXPECT_EQ(ret, 0); + } + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by InstalldUnTarFile."; + } + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-end Installd_Un_Tar_File_UnSplitTar_0100"; +} + +/** + * @tc.number: Installd_Un_Tar_File_FreePointer_0100 + * @tc.name: Installd_Un_Tar_File_FreePointer_0100 + * @tc.desc: test File_FreePointer method + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC15LE + */ +HWTEST_F(InstalldUnTarFileTest, Installd_Un_Tar_File_FreePointer_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin Installd_Un_Tar_File_FreePointer_0100"; + try { + installd::ParseTarPath parseTarPath = {}; + parseTarPath.fullPath = (char *)malloc(sizeof(char)); + parseTarPath.longName = (char *)malloc(sizeof(char)); + parseTarPath.longLink = (char *)malloc(sizeof(char)); + installd::UnTarFile unTarFile(nullptr); + unTarFile.FreePointer(&parseTarPath); + EXPECT_TRUE(parseTarPath.fullPath == nullptr); + EXPECT_TRUE(parseTarPath.longName == nullptr); + EXPECT_TRUE(parseTarPath.longLink == nullptr); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by InstalldUnTarFile."; + } + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-end Installd_Un_Tar_File_FreePointer_0100"; +} + +/** + * @tc.number: Installd_Un_Tar_File_FreeLongTypePointer_0100 + * @tc.name: Installd_Un_Tar_File_FreeLongTypePointer_0100 + * @tc.desc: test File_FreeLongTypePointer method + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC15LE + */ +HWTEST_F(InstalldUnTarFileTest, Installd_Un_Tar_File_FreeLongTypePointer_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin Installd_Un_Tar_File_FreeLongTypePointer_0100"; + try { + installd::ParseTarPath parseTarPath = {}; + parseTarPath.longName = (char *)malloc(sizeof(char)); + parseTarPath.longLink = (char *)malloc(sizeof(char)); + installd::UnTarFile unTarFile(nullptr); + unTarFile.FreeLongTypePointer(&parseTarPath); + EXPECT_TRUE(parseTarPath.longName == nullptr); + EXPECT_TRUE(parseTarPath.longLink == nullptr); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-an exception occurred by InstalldUnTarFile."; + } + GTEST_LOG_(INFO) << "InstalldUnTarFileTest-end Installd_Un_Tar_File_FreeLongTypePointer_0100"; +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file -- Gitee From 58454d9ac8c86d69718e0dae1dc051e2bcaa9409 Mon Sep 17 00:00:00 2001 From: yaohua Date: Thu, 24 Apr 2025 20:44:21 +0800 Subject: [PATCH 6/7] =?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-ut?= 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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unittests/backup_ext/BUILD.gn b/tests/unittests/backup_ext/BUILD.gn index d363e6a35..139df97bb 100644 --- a/tests/unittests/backup_ext/BUILD.gn +++ b/tests/unittests/backup_ext/BUILD.gn @@ -464,8 +464,8 @@ ohos_unittest("installd_un_tar_file_test") { cflags_cc = [ "--coverage" ] deps = [ - "${path_backup}/utils:backup_utils", "${path_backup}/tests/utils:backup_test_utils", + "${path_backup}/utils:backup_utils", ] external_deps = [ @@ -486,11 +486,11 @@ group("backup_ext_test") { deps = [ ":ext_backup_js_test", ":ext_extension_test", + ":installd_un_tar_file_test", ":tar_file_sub_test", ":tar_file_test", ":untar_file_sup_test", ":untar_file_test", - ":installd_un_tar_file_test", ] } } -- Gitee From d9aa0af6c22f364ccf7ed4475ddb5869676b1948 Mon Sep 17 00:00:00 2001 From: yaohua Date: Thu, 24 Apr 2025 20:50:38 +0800 Subject: [PATCH 7/7] =?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-ut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaohua --- tests/unittests/backup_ext/installd_un_tar_file_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unittests/backup_ext/installd_un_tar_file_test.cpp b/tests/unittests/backup_ext/installd_un_tar_file_test.cpp index df40cb7cf..fc768dd5c 100644 --- a/tests/unittests/backup_ext/installd_un_tar_file_test.cpp +++ b/tests/unittests/backup_ext/installd_un_tar_file_test.cpp @@ -226,7 +226,7 @@ HWTEST_F(InstalldUnTarFileTest, Installd_Un_Tar_File_CreateDirWithRecursive_0100 GTEST_LOG_(INFO) << "InstalldUnTarFileTest-begin Installd_Un_Tar_File_CreateDirWithRecursive_0100"; try { installd::UnTarFile unTarFile(nullptr); - mode_t mode = (mode_t)448; + mode_t mode = 448; bool ret = unTarFile.CreateDirWithRecursive("", mode); EXPECT_FALSE(ret); -- Gitee