• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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