1 /*
2 * Copyright (c) 2021 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 "gt_extractor_util.h"
17
18 #include <climits>
19 #include "appexecfwk_errors.h"
20 #include "bundle_common.h"
21 #include "bundle_util.h"
22 #include "bundlems_log.h"
23 #include "cstdio"
24 #include "dirent.h"
25 #include "fcntl.h"
26 #include "sys/stat.h"
27 #include "unistd.h"
28 #include "utils.h"
29
30 namespace OHOS {
31 const uint8_t MAGIC_NUMBER_VALUE = 190;
32 const uint8_t SHIFT_NUM = 8;
33
ReadInt(int32_t fp)34 uint32_t GtExtractorUtil::ReadInt(int32_t fp)
35 {
36 char buf[INT_LENGTH] = {0};
37 if (read(fp, buf, INT_LENGTH) != INT_LENGTH) {
38 return UINT_MAX;
39 }
40
41 uint32_t result = 0;
42 for (uint8_t i = 0; i < INT_LENGTH; i++) {
43 if (result > MAX_INT) {
44 return UINT_MAX;
45 }
46 result += (static_cast<uint32_t>(buf[i])) << (SHIFT_NUM * (INT_LENGTH - i - 1));
47 }
48 return result;
49 }
50
CheckMagicNumber(int32_t fp)51 bool GtExtractorUtil::CheckMagicNumber(int32_t fp)
52 {
53 char buf[MAGIC_NUMBER_LEN] = {0};
54 if (read(fp, buf, MAGIC_NUMBER_LEN) != MAGIC_NUMBER_LEN) {
55 return false;
56 }
57 if (static_cast<uint8_t>(buf[MAGIC_NUMBER_LEN - 1]) != MAGIC_NUMBER_VALUE) {
58 return false;
59 }
60 return true;
61 }
62
ReadLong(int32_t fp)63 uint64_t GtExtractorUtil::ReadLong(int32_t fp)
64 {
65 char buf[LONG_LENGTH] = {0};
66 if (read(fp, buf, LONG_LENGTH) != LONG_LENGTH) {
67 return 0;
68 }
69
70 uint64_t result = 0;
71 for (uint8_t i = 0; i < LONG_LENGTH; i++) {
72 if (result > LONG_MAX) {
73 return 0;
74 }
75 result += (static_cast<uint64_t>(buf[i])) << (SHIFT_NUM * (LONG_LENGTH - i - 1));
76 }
77 return result;
78 }
79
ReadString(int32_t fp,uint32_t len)80 char *GtExtractorUtil::ReadString(int32_t fp, uint32_t len)
81 {
82 char *buf = reinterpret_cast<char *>(UI_Malloc((len + 1) * sizeof(char)));
83 if (buf == nullptr) {
84 return nullptr;
85 }
86
87 if (len == 0) {
88 *buf = '\0';
89 return buf;
90 }
91
92 if (read(fp, buf, len) != len) {
93 UI_Free(buf);
94 return nullptr;
95 }
96 *(buf + len) = '\0';
97 return buf;
98 }
99
ExtractFileHeaderInfo(int32_t fp,char ** bundleName)100 uint8_t GtExtractorUtil::ExtractFileHeaderInfo(int32_t fp, char **bundleName)
101 {
102 if (!CheckMagicNumber(fp)) {
103 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
104 }
105
106 uint32_t bundleNameLen = ReadInt(fp);
107 if (bundleNameLen == UINT_MAX) {
108 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
109 }
110
111 if ((*bundleName = ReadString(fp, bundleNameLen)) == nullptr) {
112 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
113 }
114 return ERR_OK;
115 }
116
ExtractFileToPath(const char * appInstallPath,int32_t fp,uint64_t & fileSize,char ** fileName,char ** relativeFilePath)117 uint8_t GtExtractorUtil::ExtractFileToPath(const char *appInstallPath, int32_t fp, uint64_t &fileSize, char **fileName,
118 char **relativeFilePath)
119 {
120 uint8_t errorCode = ExtractFileAttr(fp, fileName, relativeFilePath, fileSize);
121 if (errorCode != ERR_OK) {
122 return errorCode;
123 }
124
125 if (!HasWrittenFile(appInstallPath, *relativeFilePath, *fileName, fp, fileSize)) {
126 return ERR_APPEXECFWK_INSTALL_FAILED_CREATE_FILE_ERROR;
127 }
128 return ERR_OK;
129 }
130
ExtractFileAttr(int32_t fp,char ** fileName,char ** relativeFilePath,uint64_t & fileSize)131 uint8_t GtExtractorUtil::ExtractFileAttr(int32_t fp, char **fileName, char **relativeFilePath, uint64_t &fileSize)
132 {
133 uint32_t nameLen = ReadInt(fp);
134 if (nameLen == UINT_MAX) {
135 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read name Int fail");
136 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
137 }
138
139 if ((*fileName = ReadString(fp, nameLen)) == nullptr) {
140 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read fileName fail");
141 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
142 }
143
144 uint32_t pathLen = ReadInt(fp);
145 if (pathLen == UINT_MAX) {
146 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read path Int fail");
147 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
148 } else {
149 if ((*relativeFilePath = ReadString(fp, pathLen)) == nullptr) {
150 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read relativeFilePath fail");
151 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
152 }
153 }
154
155 fileSize = ReadLong(fp);
156 if (fileSize == 0) {
157 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read fail size fail");
158 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
159 }
160 return ERR_OK;
161 }
162
ExtractFileAttr(int32_t fp,char ** fileName,uint32_t & pathLen,uint64_t & fileSize)163 uint8_t GtExtractorUtil::ExtractFileAttr(int32_t fp, char **fileName, uint32_t &pathLen, uint64_t &fileSize)
164 {
165 uint32_t nameLen = ReadInt(fp);
166 if (nameLen == UINT_MAX) {
167 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read name Int fail");
168 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
169 }
170
171 if ((*fileName = ReadString(fp, nameLen)) == nullptr) {
172 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read fileName fail");
173 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
174 }
175
176 pathLen = ReadInt(fp);
177 if (pathLen == UINT_MAX) {
178 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read path Int fail");
179 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
180 } else {
181 int32_t ret = lseek(fp, pathLen, SEEK_CUR);
182 if (ret < 0) {
183 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
184 }
185 }
186
187 fileSize = ReadLong(fp);
188 if (fileSize == 0) {
189 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read fail size fail");
190 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
191 }
192 return ERR_OK;
193 }
194
HasWrittenFile(const char * installPath,const char * path,const char * filename,int32_t fp,uint64_t size)195 bool GtExtractorUtil::HasWrittenFile(const char *installPath, const char *path, const char *filename, int32_t fp,
196 uint64_t size)
197 {
198 if (installPath == nullptr || path == nullptr || filename == nullptr) {
199 return false;
200 }
201
202 int32_t len = strlen(installPath) + strlen(path) + 1;
203 char *destPath = reinterpret_cast<char *>(UI_Malloc(len));
204 if (destPath == nullptr) {
205 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] malloc destPath addr fail");
206 return false;
207 }
208 if (sprintf_s(destPath, len, "%s%s", installPath, path) < 0) {
209 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] strcat destPath path fail");
210 UI_Free(destPath);
211 return false;
212 }
213
214 if (!BundleUtil::MkDirs(destPath)) {
215 UI_Free(destPath);
216 return false;
217 }
218 UI_Free(destPath);
219
220 char destName[PATH_LENGTH] = { 0 };
221 if (sprintf_s(destName, PATH_LENGTH, "%s%s/%s", installPath, path, filename) < 0) {
222 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] strcat file path fail");
223 return false;
224 }
225
226 if (!HasCopiedData(destName, fp, size)) {
227 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] copy file data fail");
228 return false;
229 }
230 return true;
231 }
232
HasCopiedData(const char * filePath,int32_t fp,uint64_t size)233 bool GtExtractorUtil::HasCopiedData(const char *filePath, int32_t fp, uint64_t size)
234 {
235 uint64_t remain = size;
236 uint64_t reading = (remain > READ_SIZE) ? READ_SIZE : remain;
237
238 if (!BundleUtil::CheckRealPath(filePath)) {
239 return false;
240 }
241
242 int32_t dfp = open(filePath, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
243 if (dfp < 0) {
244 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] open file when copy file data");
245 return false;
246 }
247
248 char *buf = reinterpret_cast<char *>(UI_Malloc(reading));
249 if (buf == nullptr) {
250 close(dfp);
251 return false;
252 }
253 while (remain > 0) {
254 int32_t ret = read(fp, buf, reading);
255 if (ret < 0 || ret != reading) {
256 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] read file when copy file data");
257 close(dfp);
258 UI_Free(buf);
259 return false;
260 }
261 ret = write(dfp, buf, reading);
262 if (ret < 0 || ret != reading) {
263 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] write file when copy file data");
264 close(dfp);
265 UI_Free(buf);
266 return false;
267 }
268 remain = remain - reading;
269 reading = (remain > READ_SIZE) ? READ_SIZE : remain;
270 }
271 UI_Free(buf);
272 close(dfp);
273 return true;
274 }
275 } // namespace OHOS