• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "package_normalize.h"
17 
18 #include "json/json_utils.h"
19 #include "json/pack_info.h"
20 #include "log.h"
21 #include "utils.h"
22 #include "zip_utils.h"
23 
24 namespace OHOS {
25 namespace AppPackingTool {
PackageNormalize(const std::map<std::string,std::string> & parameterMap,std::string & resultReceiver)26 PackageNormalize::PackageNormalize(const std::map<std::string, std::string> &parameterMap, std::string &resultReceiver)
27     : Packager(parameterMap, resultReceiver)
28 {}
29 
InitAllowedParam()30 int32_t PackageNormalize::InitAllowedParam()
31 {
32     allowedParameters_ = {
33         {}
34     };
35     return ERR_OK;
36 }
37 
38 
PreProcess()39 int32_t PackageNormalize::PreProcess()
40 {
41     if (!IsOutDirectoryValid()) {
42         return ERR_INVALID_VALUE;
43     }
44     auto it = parameterMap_.find(Constants::PARAM_HSP_LIST);
45     if (it == parameterMap_.end()) {
46         LOGE("hsp-list is empty.");
47         return ERR_INVALID_VALUE;
48     }
49     if (!CompatibleProcess(it->second, hspList_, Constants::HSP_SUFFIX)) {
50         LOGE("hsp-list is invalid.");
51         return ERR_INVALID_VALUE;
52     }
53     if (hspList_.empty()) {
54         LOGE("hsp-list is empty.");
55         return ERR_INVALID_VALUE;
56     }
57 
58     it = parameterMap_.find(Constants::PARAM_BUNDLE_NAME);
59     std::regex pattern(Constants::BUNDLE_NAME_PATTERN);
60     if (it == parameterMap_.end() || it->second.length() < Constants::BUNDLE_NAME_LEN_MIN ||
61         it->second.length() > Constants::BUNDLE_NAME_LEN_MAX || !std::regex_match(it->second, pattern)) {
62         LOGE("bundle-name is invalid.");
63         return ERR_INVALID_VALUE;
64     }
65 
66     it = parameterMap_.find(Constants::PARAM_VERSION_CODE);
67     if (it == parameterMap_.end() || !Utils::IsPositiveInteger(it->second)) {
68         LOGE("version-code is invalid.");
69         return ERR_INVALID_VALUE;
70     }
71     return ERR_OK;
72 }
73 
ModifyModuleJson(const std::string & moduleJsonPath,const int32_t & newVersionCode,const std::string & newBundleName)74 bool PackageNormalize::ModifyModuleJson(const std::string &moduleJsonPath,
75     const int32_t &newVersionCode, const std::string &newBundleName)
76 {
77     ModuleJson moduleJson;
78     if (!moduleJson.ParseFromFile(moduleJsonPath)) {
79         LOGE("Update module.json failed, parse json is null.");
80         return false;
81     }
82     if (!moduleJson.SetBundleName(newBundleName)) {
83         LOGE("Parse and modify module.json failed, json file not valid.");
84         return false;
85     }
86     if (!moduleJson.SetStageVersionCode(newVersionCode)) {
87         LOGE("Parse and modify module.json failed, json file not valid.");
88         return false;
89     }
90     if (!JsonUtils::StrToFile(moduleJson.ToString(), moduleJsonPath)) {
91         LOGE("Parse and modify module.json failed, write Json failed.");
92         return false;
93     }
94     return true;
95 }
96 
ModifyPackInfo(const std::string & packInfoPath,const int32_t & newVersionCode,const std::string & newBundleName)97 bool PackageNormalize::ModifyPackInfo(const std::string &packInfoPath,
98     const int32_t &newVersionCode, const std::string &newBundleName)
99 {
100     PackInfo packInfo;
101     if (!packInfo.ParseFromFile(packInfoPath)) {
102         LOGE("Update packInfo failed, parse json is null.");
103         return false;
104     }
105     if (!packInfo.SetBundleName(newBundleName)) {
106         LOGE("Parse and modify packInfo failed, json file not valid.");
107         return false;
108     }
109     if (!packInfo.SetVersionCode(newVersionCode)) {
110         LOGE("Parse and modify packInfo failed, json file not valid.");
111         return false;
112     }
113     if (!JsonUtils::StrToFile(packInfo.ToString(), packInfoPath)) {
114         LOGE("Parse and modify packinfo failed, write Json failed.");
115         return false;
116     }
117     return true;
118 }
119 
Process()120 int32_t PackageNormalize::Process()
121 {
122     std::string outPath = parameterMap_.at(Constants::PARAM_OUT_PATH);
123     std::string tempPath = outPath + Constants::LINUX_FILE_SEPARATOR + Constants::COMPRESSOR_PACKAGENORMALIZE_TEMP_DIR
124         + Utils::GenerateUUID();
125     int32_t versionCode = 0;
126     auto it = parameterMap_.find(Constants::PARAM_VERSION_CODE);
127     if (it != parameterMap_.end()) {
128         try {
129             versionCode = std::stoi(it->second);
130         } catch (const std::exception& e) {
131             LOGE("Exception: %s", e.what());
132             return ERR_INVALID_VALUE;
133         }
134     } else {
135         LOGE("Parameter not found: %s", Constants::PARAM_VERSION_CODE.c_str());
136         return ERR_INVALID_VALUE;
137     }
138     std::string bundleName = parameterMap_.at(Constants::PARAM_BUNDLE_NAME);
139     for (const std::string &path : hspList_) {
140         if (ZipUtils::Unzip(path, tempPath) != ZIP_ERR_SUCCESS) {
141             Utils::ForceRemoveDirectory(tempPath);
142             return ERR_INVALID_VALUE;
143         }
144         std::string moduleJsonPath = tempPath +  Constants::LINUX_FILE_SEPARATOR + Constants::MODULE_JSON;
145         std::string packInfoPath = tempPath + Constants::LINUX_FILE_SEPARATOR + Constants::PACK_INFO;
146         fs::path entryPath(path);
147         std::string filePath = entryPath.filename().string();
148         if (!fs::exists(moduleJsonPath) || !fs::is_regular_file(moduleJsonPath) || !fs::exists(packInfoPath) ||
149                 !fs::is_regular_file(packInfoPath)) {
150             LOGE("PackageNormalize failed: hsp not have file module.json or pack.info.");
151             Utils::ForceRemoveDirectory(tempPath);
152             return ERR_INVALID_VALUE;
153         }
154 
155         if (!ModifyModuleJson(moduleJsonPath, versionCode, bundleName)) {
156             Utils::ForceRemoveDirectory(tempPath);
157             return ERR_INVALID_VALUE;
158         }
159         if (!ModifyPackInfo(packInfoPath, versionCode, bundleName)) {
160             Utils::ForceRemoveDirectory(tempPath);
161             return ERR_INVALID_VALUE;
162         }
163         if (ZipUtils::Zip(tempPath, outPath + Constants::LINUX_FILE_SEPARATOR + filePath) != ZIP_ERR_SUCCESS) {
164             Utils::ForceRemoveDirectory(tempPath);
165             return ERR_INVALID_VALUE;
166         }
167         Utils::ForceRemoveDirectory(tempPath);
168     }
169     return ERR_OK;
170 }
171 
PostProcess()172 int32_t PackageNormalize::PostProcess()
173 {
174     return ERR_OK;
175 }
176 } // namespace AppPackingTool
177 } // namespace OHOS