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 unsigned 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 unsigned 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 unsigned 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 unsigned char *GtExtractorUtil::ReadString(int32_t fp, uint32_t len)
81 {
82 unsigned char *buf = reinterpret_cast<unsigned char *>(UI_Malloc((len + 1) * sizeof(unsigned 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 = reinterpret_cast<char *>(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 RefreshAllServiceTimeStamp();
121 uint8_t errorCode = ExtractFileAttr(fp, fileName, relativeFilePath, fileSize);
122 if (errorCode != ERR_OK) {
123 return errorCode;
124 }
125
126 if (!HasWrittenFile(appInstallPath, *relativeFilePath, *fileName, fp, fileSize)) {
127 return ERR_APPEXECFWK_INSTALL_FAILED_CREATE_FILE_ERROR;
128 }
129 return ERR_OK;
130 }
131
ExtractFileAttr(int32_t fp,char ** fileName,char ** relativeFilePath,uint64_t & fileSize)132 uint8_t GtExtractorUtil::ExtractFileAttr(int32_t fp, char **fileName, char **relativeFilePath, uint64_t &fileSize)
133 {
134 uint32_t nameLen = ReadInt(fp);
135 if (nameLen == UINT_MAX) {
136 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read name Int fail");
137 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
138 }
139
140 if ((*fileName = reinterpret_cast<char *>(ReadString(fp, nameLen))) == nullptr) {
141 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read fileName fail");
142 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
143 }
144
145 uint32_t pathLen = ReadInt(fp);
146 if (pathLen == UINT_MAX) {
147 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read path Int fail");
148 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
149 } else {
150 if ((*relativeFilePath = reinterpret_cast<char *>(ReadString(fp, pathLen))) == nullptr) {
151 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read relativeFilePath fail");
152 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
153 }
154 }
155
156 fileSize = ReadLong(fp);
157 if (fileSize == 0) {
158 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read fail size fail");
159 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
160 }
161 return ERR_OK;
162 }
163
ExtractFileAttr(int32_t fp,char ** fileName,uint32_t & pathLen,uint64_t & fileSize)164 uint8_t GtExtractorUtil::ExtractFileAttr(int32_t fp, char **fileName, uint32_t &pathLen, uint64_t &fileSize)
165 {
166 uint32_t nameLen = ReadInt(fp);
167 if (nameLen == UINT_MAX) {
168 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read name Int fail");
169 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
170 }
171
172 if ((*fileName = reinterpret_cast<char *>(ReadString(fp, nameLen))) == nullptr) {
173 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read fileName fail");
174 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
175 }
176
177 pathLen = ReadInt(fp);
178 if (pathLen == UINT_MAX) {
179 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read path Int fail");
180 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
181 } else {
182 int32_t ret = lseek(fp, pathLen, SEEK_CUR);
183 if (ret < 0) {
184 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
185 }
186 }
187
188 fileSize = ReadLong(fp);
189 if (fileSize == 0) {
190 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Read fail size fail");
191 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_DATA_INVALID;
192 }
193 return ERR_OK;
194 }
195
HasWrittenFile(const char * installPath,const char * path,const char * filename,int32_t fp,uint64_t size)196 bool GtExtractorUtil::HasWrittenFile(const char *installPath, const char *path, const char *filename, int32_t fp,
197 uint64_t size)
198 {
199 if (installPath == nullptr || path == nullptr || filename == nullptr) {
200 return false;
201 }
202
203 int32_t len = strlen(installPath) + strlen(path) + 1;
204 char *destPath = reinterpret_cast<char *>(UI_Malloc(len));
205 if (destPath == nullptr) {
206 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] malloc destPath addr fail");
207 return false;
208 }
209 if (sprintf_s(destPath, len, "%s%s", installPath, path) < 0) {
210 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] strcat destPath path fail");
211 UI_Free(destPath);
212 return false;
213 }
214
215 if (!BundleUtil::MkDirs(destPath)) {
216 UI_Free(destPath);
217 return false;
218 }
219 UI_Free(destPath);
220
221 char destName[PATH_LENGTH] = { 0 };
222 if (sprintf_s(destName, PATH_LENGTH, "%s%s/%s", installPath, path, filename) < 0) {
223 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] strcat file path fail");
224 return false;
225 }
226
227 if (!HasCopiedData(destName, fp, size)) {
228 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] copy file data fail");
229 return false;
230 }
231 return true;
232 }
233
HasCopiedData(const char * filePath,int32_t fp,uint64_t size)234 bool GtExtractorUtil::HasCopiedData(const char *filePath, int32_t fp, uint64_t size)
235 {
236 uint64_t remain = size;
237 uint64_t reading = (remain > READ_SIZE) ? READ_SIZE : remain;
238
239 if (!BundleUtil::CheckRealPath(filePath)) {
240 return false;
241 }
242
243 int32_t dfp = open(filePath, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
244 if (dfp < 0) {
245 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] open file when copy file data");
246 return false;
247 }
248
249 char *buf = reinterpret_cast<char *>(UI_Malloc(reading));
250 if (buf == nullptr) {
251 close(dfp);
252 return false;
253 }
254 while (remain > 0) {
255 int32_t ret = read(fp, buf, reading);
256 if (ret < 0 || ret != reading) {
257 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] read file when copy file data");
258 close(dfp);
259 UI_Free(buf);
260 return false;
261 }
262 ret = write(dfp, buf, reading);
263 if (ret < 0 || ret != reading) {
264 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] write file when copy file data");
265 close(dfp);
266 UI_Free(buf);
267 return false;
268 }
269 remain = remain - reading;
270 reading = (remain > READ_SIZE) ? READ_SIZE : remain;
271 }
272 UI_Free(buf);
273 close(dfp);
274 return true;
275 }
276 } // namespace OHOS