diff --git a/interfaces/kits/ani/common/enum_util.h b/interfaces/kits/ani/common/enum_util.h index afdc105aeea16e04daa45d82f49b363722261cb0..2f7021b86f3140f88f15756c4ca7caec330900c7 100644 --- a/interfaces/kits/ani/common/enum_util.h +++ b/interfaces/kits/ani/common/enum_util.h @@ -50,6 +50,7 @@ constexpr const char* CLASSNAME_BUNDLE_LAUNCHMODE = "L@ohos/bundle/bundle/Launch constexpr const char* CLASSNAME_ZLIB_COMPRESSLEVEL = "L@ohos/zlib/zlib/CompressLevel;"; constexpr const char* CLASSNAME_ZLIB_MEMLEVEL = "L@ohos/zlib/zlib/MemLevel;"; constexpr const char* CLASSNAME_ZLIB_COMPRESSSTRATEGY = "L@ohos/zlib/zlib/CompressStrategy;"; +constexpr const char* CLASSNAME_ZLIB_PATHSEPARATORSTRATRGY = "L@ohos/zlib/zlib/PathSeparatorStrategy;"; } // namespace CommonFunAniNS class EnumUtils { private: @@ -446,6 +447,16 @@ public: { return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_ZLIB_COMPRESSSTRATEGY, value, 0); } + + /* zlib.PathSeparatorStrategy + enum PathSeparatorStrategy { + PATH_SEPARATOR_STRATEGY_DEFAULT = 0, + PATH_SEPARATOR_STRATEGY_REPLACE_BACKSLASH = 1 + } */ + static inline ani_enum_item EnumNativeToETS_Zlib_PathSeparatorStrategy(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_ZLIB_PATHSEPARATORSTRATRGY, value, 0); + } }; } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/kits/ani/zlib/ani_zlib.cpp b/interfaces/kits/ani/zlib/ani_zlib.cpp index 3559b363dc6bccf3fa1adace08e1f3bd872d38ad..aa0c0870aa62f69250db644b1bf1382802a34cc2 100644 --- a/interfaces/kits/ani/zlib/ani_zlib.cpp +++ b/interfaces/kits/ani/zlib/ani_zlib.cpp @@ -32,6 +32,7 @@ constexpr const char* PROPERTY_NAME_LEVEL = "level"; constexpr const char* PROPERTY_NAME_MEMLEVEL = "memLevel"; constexpr const char* PROPERTY_NAME_STRATEGY = "strategy"; constexpr const char* PROPERTY_NAME_PARALLEL = "parallel"; +constexpr const char* PROPERTY_NAME_PATH_SEPARATOR_STRATEGY = "pathSeparatorStrategy"; constexpr const char* TYPE_NAME_CHECKSUMINTERNAL = "ChecksumInternal"; constexpr const char* PARAM_NAME_IN_FILE = "inFile"; constexpr const char* PARAM_NAME_IN_FILES = "inFiles"; @@ -212,6 +213,10 @@ static bool ANIParseOptions(ani_env* env, ani_object object, LIBZIP::OPTIONS& op RETURN_FALSE_IF_FALSE(EnumUtils::EnumETSToNative(env, enumItem, options.parallel)); } + // pathSeparatorStrategy?: PathSeparatorStrategy + if (CommonFunAni::CallGetterOptional(env, object, PROPERTY_NAME_PATH_SEPARATOR_STRATEGY, &enumItem)) { + RETURN_FALSE_IF_FALSE(EnumUtils::EnumETSToNative(env, enumItem, options.pathSeparatorStrategy)); + } return true; } diff --git a/interfaces/kits/ani/zlib/ets/@ohos.zlib.ets b/interfaces/kits/ani/zlib/ets/@ohos.zlib.ets index efbf0f567baa825ae0cba4f186b7c060beeb986a..03c7dc253b302b838c3c8e145bc18ed5c519aced 100644 --- a/interfaces/kits/ani/zlib/ets/@ohos.zlib.ets +++ b/interfaces/kits/ani/zlib/ets/@ohos.zlib.ets @@ -44,6 +44,11 @@ export default namespace zlib { PARALLEL_STRATEGY_PARALLEL_DECOMPRESSION = 1 } + export enum PathSeparatorStrategy { + PATH_SEPARATOR_STRATEGY_DEFAULT = 0, + PATH_SEPARATOR_STRATEGY_REPLACE_BACKSLASH = 1 + } + export enum MemLevel { MEM_LEVEL_MIN = 1, MEM_LEVEL_MAX = 9, @@ -55,6 +60,7 @@ export default namespace zlib { memLevel?: MemLevel; strategy?: CompressStrategy; parallel?: ParallelStrategy; + pathSeparatorStrategy?: PathSeparatorStrategy; } class OptionsInner implements Options { @@ -62,6 +68,7 @@ export default namespace zlib { memLevel?: MemLevel | undefined; strategy?: CompressStrategy | undefined; parallel?: ParallelStrategy | undefined; + pathSeparatorStrategy?: PathSeparatorStrategy | undefined; } export function compressFile(inFile: string, outFile: string, options: Options, callback: AsyncCallback): void { diff --git a/interfaces/kits/js/zip/include/zip_reader.h b/interfaces/kits/js/zip/include/zip_reader.h index b193ea16d940064e6b7ee8e44c4e762c2b532833..407620bb48cf88517ff6f1c95558a05f4c954922 100755 --- a/interfaces/kits/js/zip/include/zip_reader.h +++ b/interfaces/kits/js/zip/include/zip_reader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -128,6 +128,7 @@ public: }; ZipReader(); + ZipReader(bool needChangePathSeparator); ~ZipReader(); // Opens the zip file specified by |zipFilePath|. Returns true on @@ -195,6 +196,7 @@ private: unzFile zipFile_; int numEntries_; bool reachedEnd_; + bool needChangePathSeparator_ = false; std::unique_ptr currentEntryInfo_; DISALLOW_COPY_AND_ASSIGN(ZipReader); @@ -203,6 +205,7 @@ private: class ZipParallelReader : public ZipReader { public: ZipParallelReader() : ZipReader() {} + ZipParallelReader(bool needChangePathSeparator) : ZipReader(needChangePathSeparator) {} ~ZipParallelReader(); // Opens th zip file multi times specified by |zipFilePath|. Returns true on diff --git a/interfaces/kits/js/zip/include/zip_utils.h b/interfaces/kits/js/zip/include/zip_utils.h index cba8574e95842f64204a58ef7bdec2db15e7ed23..8cc7d75db6cded369b6a47a489401524749cacb0 100755 --- a/interfaces/kits/js/zip/include/zip_utils.h +++ b/interfaces/kits/js/zip/include/zip_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -103,6 +103,13 @@ using PARALLEL_STRATEGY = enum ParallelStrategy; enum MemoryLevel { MEM_LEVEL_MIN_MEMLEVEL = 1, MEM_LEVEL_DEFAULT_MEMLEVEL = 8, MEM_LEVEL_MAX_MEMLEVEL = 9 }; using MEMORY_LEVEL = enum MemoryLevel; +// Path Separator Strategy +enum PathSeparatorStrategy { + PATH_SEPARATOR_STRATEGY_DEFAULT = 0, + PATH_SEPARATOR_STRATEGY_REPLACE_BACKSLASH = 1 +}; +using PATH_SEPARATOR_STRATEGY = enum PathSeparatorStrategy; + // Compression Options struct Options { FLUSH_TYPE flush; @@ -114,6 +121,7 @@ struct Options { MEMORY_LEVEL memLevel; // Internal compression status, how much memory should be allocated COMPRESS_STRATEGY strategy; // CompressStrategy PARALLEL_STRATEGY parallel; // ParallelStrategy + PATH_SEPARATOR_STRATEGY pathSeparatorStrategy; // PathSeparatorStrategy // default constructor Options() @@ -131,6 +139,7 @@ struct Options { memLevel = MEM_LEVEL_DEFAULT_MEMLEVEL; strategy = COMPRESS_STRATEGY_DEFAULT_STRATEGY; parallel = PARALLEL_STRATEGY_SEQUENTIAL; + pathSeparatorStrategy = PATH_SEPARATOR_STRATEGY_DEFAULT; } }; using OPTIONS = struct Options; diff --git a/interfaces/kits/js/zip/napi/napi_zlib.cpp b/interfaces/kits/js/zip/napi/napi_zlib.cpp index 8a6a0e1cae64c65aee61f4247b46f1c3ee21c45e..dc950df258171bc963c442ccb60b7142132ef1b8 100755 --- a/interfaces/kits/js/zip/napi/napi_zlib.cpp +++ b/interfaces/kits/js/zip/napi/napi_zlib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -93,6 +93,14 @@ enum ReturnStatus { return ret; \ } +#define PATH_SEPARATOR_STRATEGY_CHECK(path_separator, false) \ + if (!((path_separator) == PATH_SEPARATOR_STRATEGY_DEFAULT || \ + (path_separator) == PATH_SEPARATOR_STRATEGY_REPLACE_BACKSLASH)) { \ + APP_LOGE("pathSeparatorStrategy parameter =[%{public}d] value is incorrect", \ + static_cast(path_separator)); \ + return ret; \ + } + void CompressExcute(napi_env env, AsyncZipCallbackInfo *asyncZipCallbackInfo); void DecompressExcute(napi_env env, AsyncZipCallbackInfo *asyncZipCallbackInfo); napi_value UnwrapZipParam(CallZipUnzipParam ¶m, napi_env env, napi_value *args, size_t argc); @@ -268,6 +276,32 @@ napi_value ParallelStrategyInit(napi_env env, napi_value exports) return exports; } +/** + * @brief PathSeparatorStrategy data initialization. + * + * @param env The environment that the Node-API call is invoked under. + * @param exports An empty object via the exports parameter as a convenience. + * + * @return The return value from Init is treated as the exports object for the module. + */ +napi_value PathSeparatorStrategyInit(napi_env env, napi_value exports) +{ + const int PATH_SEPARATOR_STRATEGY_DEFAULT = 0; + const int PATH_SEPARATOR_STRATEGY_REPLACE_BACKSLASH = 1; + + napi_value pathSeparatorStrategy = nullptr; + napi_create_object(env, &pathSeparatorStrategy); + SetNamedProperty(env, pathSeparatorStrategy, "PATH_SEPARATOR_STRATEGY_DEFAULT", PATH_SEPARATOR_STRATEGY_DEFAULT); + SetNamedProperty(env, pathSeparatorStrategy, "PATH_SEPARATOR_STRATEGY_REPLACE_BACKSLASH", + PATH_SEPARATOR_STRATEGY_REPLACE_BACKSLASH); + + napi_property_descriptor properties[] = { + DECLARE_NAPI_PROPERTY("PathSeparatorStrategy", pathSeparatorStrategy), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties)); + + return exports; +} /** * @brief MemLevel data initialization. * @@ -569,6 +603,11 @@ bool UnwrapOptionsParams(OPTIONS &options, napi_env env, napi_value arg) PARALLEL_STRATEGY_CHECK(ret, false) options.parallel = static_cast(ret); } + } else if (strProName == std::string("pathSeparatorStrategy")) { + if (UnwrapIntValue(env, jsProValue, ret)) { + PATH_SEPARATOR_STRATEGY_CHECK(ret, false) + options.pathSeparatorStrategy = static_cast(ret); + } } } return true; diff --git a/interfaces/kits/js/zip/napi/napi_zlib.h b/interfaces/kits/js/zip/napi/napi_zlib.h index 8f94d8428d782b3f158b73ad40edb376e67737d5..318225a329a36dcdba02c0102d2363196927bbd2 100755 --- a/interfaces/kits/js/zip/napi/napi_zlib.h +++ b/interfaces/kits/js/zip/napi/napi_zlib.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -84,6 +84,16 @@ napi_value CompressStrategyInit(napi_env env, napi_value exports); */ napi_value ParallelStrategyInit(napi_env env, napi_value exports); +/** + * @brief PathSeparatorStrategy data initialization. + * + * @param env The environment that the Node-API call is invoked under. + * @param exports An empty object via the exports parameter as a convenience. + * + * @return The return value from Init is treated as the exports object for the module. + */ +napi_value PathSeparatorStrategyInit(napi_env env, napi_value exports); + /** * @brief MemLevel data initialization. * diff --git a/interfaces/kits/js/zip/napi/native_module.cpp b/interfaces/kits/js/zip/napi/native_module.cpp index 3d147c70e07a2211d299cba198a58b2cfc1c2444..8f5322003687007a74edaa6bc4320a13be585570 100755 --- a/interfaces/kits/js/zip/napi/native_module.cpp +++ b/interfaces/kits/js/zip/napi/native_module.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -40,6 +40,7 @@ static napi_value Init(napi_env env, napi_value exports) CompressMethodInit(env, exports); CompressStrategyInit(env, exports); ParallelStrategyInit(env, exports); + PathSeparatorStrategyInit(env, exports); MemLevelInit(env, exports); ReturnStatusInit(env, exports); OffsetReferencePointInit(env, exports); diff --git a/interfaces/kits/js/zip/src/zip.cpp b/interfaces/kits/js/zip/src/zip.cpp index b05f5999cb94ecbb03d25273ae15b7f384689f0c..bd38e8999ff166fa6c78df7b0dd63a70d05588f8 100644 --- a/interfaces/kits/js/zip/src/zip.cpp +++ b/interfaces/kits/js/zip/src/zip.cpp @@ -241,10 +241,10 @@ bool Zips(const ZipParams ¶ms, const OPTIONS &options) } ErrCode UnzipWithFilterAndWriters(const PlatformFile &srcFile, FilePath &destDir, WriterFactory writerFactory, - DirectoryCreator directoryCreator, UnzipParam &unzipParam) + DirectoryCreator directoryCreator, UnzipParam &unzipParam, bool needChangePathSeparator) { APP_LOGD("destDir=%{private}s", destDir.Value().c_str()); - ZipReader reader; + ZipReader reader(needChangePathSeparator); if (!reader.OpenFromPlatformFile(srcFile)) { APP_LOGI("Failed to open srcFile"); return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; @@ -291,10 +291,10 @@ ErrCode UnzipWithFilterAndWriters(const PlatformFile &srcFile, FilePath &destDir } ErrCode UnzipWithFilterAndWritersParallel(const FilePath &srcFile, FilePath &destDir, WriterFactory writerFactory, - DirectoryCreator directoryCreator, UnzipParam &unzipParam) + DirectoryCreator directoryCreator, UnzipParam &unzipParam, bool needChangePathSeparator) { APP_LOGD("destDir=%{private}s", destDir.Value().c_str()); - ZipParallelReader reader; + ZipParallelReader reader(needChangePathSeparator); FilePath src = srcFile; if (!reader.Open(src)) { @@ -387,12 +387,17 @@ ErrCode UnzipWithFilterCallback( } ErrCode ret = ERR_OK; + bool needChangePathSeparator = false; + if (options.pathSeparatorStrategy == PathSeparatorStrategy::PATH_SEPARATOR_STRATEGY_REPLACE_BACKSLASH) { + needChangePathSeparator = true; + } if (options.parallel == PARALLEL_STRATEGY_PARALLEL_DECOMPRESSION) { ret = UnzipWithFilterAndWritersParallel(src, dest, std::bind(&CreateFilePathWriterDelegate, std::placeholders::_1, std::placeholders::_2), std::bind(&CreateDirectory, std::placeholders::_1, std::placeholders::_2), - unzipParam); + unzipParam, + needChangePathSeparator); } else { PlatformFile zipFd = open(src.Value().c_str(), S_IREAD, O_CREAT); if (zipFd == kInvalidPlatformFile) { @@ -403,7 +408,8 @@ ErrCode UnzipWithFilterCallback( dest, std::bind(&CreateFilePathWriterDelegate, std::placeholders::_1, std::placeholders::_2), std::bind(&CreateDirectory, std::placeholders::_1, std::placeholders::_2), - unzipParam); + unzipParam, + needChangePathSeparator); close(zipFd); } return ret; diff --git a/interfaces/kits/js/zip/src/zip_reader.cpp b/interfaces/kits/js/zip/src/zip_reader.cpp index 7a7676366a8009a6733a9a3622b79fae6fd19db4..432f269bb3f7cf3b7fe8c982f71e4d000e2d756f 100755 --- a/interfaces/kits/js/zip/src/zip_reader.cpp +++ b/interfaces/kits/js/zip/src/zip_reader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -62,6 +62,12 @@ ZipReader::ZipReader() Reset(); } +ZipReader::ZipReader(bool needChangePathSeparator) +{ + needChangePathSeparator_ = needChangePathSeparator; + Reset(); +} + ZipReader::~ZipReader() { Close(); @@ -179,7 +185,11 @@ bool ZipReader::OpenCurrentEntryInZip() if (raw_file_name_in_zip[0] == '\0') { return false; } - EntryInfo *entryInfo = new (std::nothrow) EntryInfo(std::string(raw_file_name_in_zip), raw_file_info); + std::string originalFileNameInZip(raw_file_name_in_zip); + if (needChangePathSeparator_) { + std::replace(originalFileNameInZip.begin(), originalFileNameInZip.end(), '\\', '/'); + } + EntryInfo *entryInfo = new (std::nothrow) EntryInfo(originalFileNameInZip, raw_file_info); if (entryInfo == nullptr) { return false; }