From 97a0e7ea1f33c0e9af1cec51b0bc72041fa586d1 Mon Sep 17 00:00:00 2001 From: z30034863 Date: Wed, 20 Aug 2025 15:18:10 +0800 Subject: [PATCH] feature: check querySchemes Signed-off-by: z30034863 --- adapter/ohos/Compressor.java | 21 ++++++ adapter/ohos/ModuleJsonUtil.java | 46 +++++++++++++ .../frameworks/include/json/module_json.h | 4 ++ packing_tool/frameworks/src/hap_packager.cpp | 5 ++ .../frameworks/src/json/module_json.cpp | 67 +++++++++++++++++++ 5 files changed, 143 insertions(+) diff --git a/adapter/ohos/Compressor.java b/adapter/ohos/Compressor.java index 99f0dbb0..0ae4eb86 100644 --- a/adapter/ohos/Compressor.java +++ b/adapter/ohos/Compressor.java @@ -183,6 +183,8 @@ public class Compressor { private static final String TARGET_FILE_PATH = HAPADDITION_FOLDER_NAME + LINUX_FILE_SEPARATOR + "resources" + LINUX_FILE_SEPARATOR + "base" + LINUX_FILE_SEPARATOR + "profile"; private static final String BACKUP_PREFIX = "backup"; + private static final int QUERY_SCHEMES_CHECK_COUNT = 50; + private static final int QUERY_SCHEMES_CHECK_MIN_API_VERSION = 21; // set timestamp to get fixed MD5 private static final int ATOMIC_SERVICE_ENTRY_SIZE_LIMIT_DEFAULT = 2048; // 2MB;unit is KB @@ -1079,6 +1081,12 @@ public class Compressor { "Check the continueBundleName parameter in the Stage module failed.")); return false; } + // check querySchemes in module.json + if (!checkQuerySchemes(jsonString)) { + LOG.error(PackingToolErrMsg.CHECK_STAGE_HAP_FAILED.toString( + "Check the querySchemes parameter in the Stage module failed.")); + return false; + } return true; } @@ -1136,6 +1144,19 @@ public class Compressor { return true; } + private static boolean checkQuerySchemes(String jsonString) throws BundleException { + int minAPIVersion = ModuleJsonUtil.getMinAPIVersion(jsonString); + List querySchemes = ModuleJsonUtil.getQuerySchemes(jsonString); + int querySchemesCount = querySchemes.size(); + if (querySchemesCount > QUERY_SCHEMES_CHECK_COUNT && minAPIVersion < QUERY_SCHEMES_CHECK_MIN_API_VERSION) { + String errMsg = "The number of querySchemes in the Hap(entry) exceeds " + QUERY_SCHEMES_CHECK_COUNT + + ", and the minAPIVersion is less than " + QUERY_SCHEMES_CHECK_MIN_API_VERSION; + LOG.error(PackingToolErrMsg.CHECK_STAGE_HAP_FAILED.toString(errMsg)); + return false; + } + return true; + } + private static boolean checkStageUbsanEnabledValid(String jsonString) throws BundleException { boolean asanEnabled = ModuleJsonUtil.getStageAsanEnabled(jsonString); boolean tsanEnabled = ModuleJsonUtil.getStageTsanEnabled(jsonString); diff --git a/adapter/ohos/ModuleJsonUtil.java b/adapter/ohos/ModuleJsonUtil.java index 0e1101c6..c6d6b2c4 100644 --- a/adapter/ohos/ModuleJsonUtil.java +++ b/adapter/ohos/ModuleJsonUtil.java @@ -107,6 +107,7 @@ class ModuleJsonUtil { private static final String PROXY_DATAS = "proxyDatas"; private static final String PROXY_DATA = "proxyData"; private static final String PROXY_URI = "uri"; + private static final String QUERY_SCHEMES = "querySchemes"; private static final String CONTINUE_TYPE = "continueType"; private static final String CONTINUE_BUNDLE_NAME = "continueBundleName"; private static final String MULTI_APP_MODE = "multiAppMode"; @@ -1718,6 +1719,51 @@ class ModuleJsonUtil { return continueBundleName; } + /** + * get querySchemes from json file. + * + * @param jsonString is the json String of module.json + * @return querySchemes URL list + */ + public static List getQuerySchemes(String jsonString) throws BundleException { + List querySchemes = new ArrayList<>(); + JSONObject moduleObj = getModuleObj(jsonString); + if (!moduleObj.containsKey(QUERY_SCHEMES)) { + return querySchemes; + } + JSONArray querySchemesArray = moduleObj.getJSONArray(QUERY_SCHEMES); + if (querySchemesArray != null) { + querySchemesArray.stream() + .map(Object::toString) + .forEach(querySchemes::add); + } + return querySchemes; + } + + /** + * Gets the minAPIVersion from a {@code module.json} string. + *

+ * For example: + *

+     *   build-profile.json5                  module.json  minAPIVersion
+     *   "compatibleSdkVersion": "5.0.0(12)"  50000012     50000012 % 1000 //The last three digits represent the version
+     *   12                                   12           12
+     * 
+ * + * @param jsonString the JSON string of module.json + * @return the minAPIVersion value extracted from the module.json + */ + public static int getMinAPIVersion(String jsonString) throws BundleException { + JSONObject appObj = ModuleJsonUtil.getAppObj(jsonString); + if (!appObj.containsKey(MIN_API_VERSION)) { + LOG.error(PackingToolErrMsg.CHECK_STAGE_HAP_FAILED.toString( + "Get compatibleSdkVersion in the Stage module failed.")); + throw new BundleException("Get compatibleSdkVersion failed."); + } + int rawMinAPIVersion = appObj.getIntValue(MIN_API_VERSION); + return rawMinAPIVersion % 1000; + } + /** * get apiReleaseType in module.json * diff --git a/packing_tool/frameworks/include/json/module_json.h b/packing_tool/frameworks/include/json/module_json.h index ab20207c..b7f5eee8 100644 --- a/packing_tool/frameworks/include/json/module_json.h +++ b/packing_tool/frameworks/include/json/module_json.h @@ -203,12 +203,16 @@ public: bool GetMinApiVersion(int32_t& minAPIVersion); bool GetTargetApiVersion(int32_t& targetAPIVersion); bool GetDeliveryWithInstall(bool& deliveryWithInstall); + bool GetQuerySchemes(std::list& querySchemes); + bool GetQuerySchemesByModuleObj(std::unique_ptr& moduleObj, std::list& querySchemes); + bool GetQuerySchemesByArray(std::unique_ptr& querySchemesObj, std::list& querySchemes); bool IsModuleAtomicServiceValid(); bool CheckEntryInAtomicService(); bool CheckAtomicServiceInstallationFree(); bool CheckStageAsanTsanEnabledValid(); bool CheckStageAtomicService(); + bool CheckQuerySchemes(); bool CheckStageOverlayCfg(); bool GetGenerateBuildHash(bool& generateBuildHash); diff --git a/packing_tool/frameworks/src/hap_packager.cpp b/packing_tool/frameworks/src/hap_packager.cpp index 323f9f2c..24a53876 100644 --- a/packing_tool/frameworks/src/hap_packager.cpp +++ b/packing_tool/frameworks/src/hap_packager.cpp @@ -423,6 +423,11 @@ bool HapPackager::CheckStageHap(const std::string &jsonPath) return false; } + if (!moduleJson_.CheckQuerySchemes()) { + LOGE("CheckQuerySchemes failed."); + return false; + } + return true; } diff --git a/packing_tool/frameworks/src/json/module_json.cpp b/packing_tool/frameworks/src/json/module_json.cpp index c9d7bce8..5c11cd55 100644 --- a/packing_tool/frameworks/src/json/module_json.cpp +++ b/packing_tool/frameworks/src/json/module_json.cpp @@ -31,6 +31,9 @@ const std::string VERSIONNAME = "versionName"; const std::string MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode"; const std::string API_VERSION = "apiVersion"; const std::string MIN_API_VERSION = "minAPIVersion"; +// const std::string QUERY_SCHEMES = "querySchemes"; +// const int32_t QUERY_SCHEMES_CHECK_COUNT = 50; +// const int32_t QUERY_SCHEMES_CHECK_MIN_API_VERSION = 21; const std::string TARGET_API_VERSION = "targetAPIVersion"; const std::string API_RELEASE_TYPE = "apiReleaseType"; const std::string DEBUG = "debug"; @@ -1236,6 +1239,22 @@ bool ModuleJson::CheckStageAtomicService() return true; } +bool ModuleJson::CheckQuerySchemes() +{ + // int32_t rawMinAPIVersion = -1; + // GetMinApiVersion(rawMinAPIVersion); + // int32_t minAPIVersion = rawMinAPIVersion % 1000; + // std::list querySchemes; + // GetQuerySchemes(querySchemes); + // int querySchemesCount = querySchemes.size(); + // if (querySchemesCount > QUERY_SCHEMES_CHECK_COUNT && minAPIVersion < QUERY_SCHEMES_CHECK_MIN_API_VERSION) { + // LOGE("The number of querySchemes in the Hap(entry) exceeds %d, and the minAPIVersion is less than %d", + // QUERY_SCHEMES_CHECK_COUNT, QUERY_SCHEMES_CHECK_MIN_API_VERSION); + // return false; + // } + return true; +} + bool ModuleJson::CheckStageOverlayCfg() { std::string targetModuleName; @@ -1647,5 +1666,53 @@ bool ModuleJson::GetDeliveryWithInstall(bool& deliveryWithInstall) } return true; } + +// bool ModuleJson::GetQuerySchemes(std::list& querySchemes) +// { +// std::unique_ptr moduleObj; +// if (!GetModuleObject(moduleObj)) { +// LOGE("GetModuleObject failed!"); +// return false; +// } +// return GetQuerySchemesByModuleObj(moduleObj, querySchemes); +// } + +// bool ModuleJson::GetQuerySchemesByModuleObj(std::unique_ptr& moduleObj, std::list& querySchemes) +// { +// if (!moduleObj) { +// LOGE("Module node is null!"); +// return false; +// } +// if (moduleObj->Contains(QUERY_SCHEMES.c_str())) { +// std::unique_ptr querySchemesObj; +// if (moduleObj->GetArray(QUERY_SCHEMES.c_str(), &querySchemesObj) != Result::SUCCESS) { +// LOGE("Module node get %s array node failed!", QUERY_SCHEMES.c_str()); +// return false; +// } +// if (!GetQuerySchemesByArray(querySchemesObj, querySchemes)) { +// LOGE("GetQuerySchemesByArray failed!"); +// return false; +// } +// } +// return true; +// } + +// bool ModuleJson::GetQuerySchemesByArray(std::unique_ptr& querySchemesObj, +// std::list& querySchemes) +// { +// if (!querySchemesObj) { +// LOGE("querySchemes node is null!"); +// return false; +// } +// for (int32_t i = 0; i < querySchemesObj->GetSize(); i++) { +// std::unique_ptr obj = querySchemesObj->Get(i); +// if (obj == nullptr) { +// LOGE("querySchemesObj->Get(%{public}d) returned null", i); +// continue; +// } +// querySchemes.push_back(obj->GetString()); +// } +// return true; +// } } // namespace AppPackingTool } // namespace OHOS -- Gitee