• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 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 "bundle_util.h"
17 
18 #include <new>
19 
20 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
21 #include <dirent.h>
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include "bundle_daemon_client.h"
29 #else
30 #include "adapter.h"
31 #include "bundlems_log.h"
32 #include "cstdio"
33 #include "dirent.h"
34 #include "fcntl.h"
35 #include "los_tick.h"
36 #include "sys/stat.h"
37 #include "unistd.h"
38 #endif
39 #include <cstdlib>
40 #include "utils.h"
41 
42 namespace OHOS {
43 const char DIGITSTR[] = "0123456789";
44 const uint8_t MAX_CHARACTER_VALUE = 26;
45 const uint8_t NUM_OF_TYPE = 3;
46 #ifdef __LITEOS_M__
47 const int32_t MAX_JSON_SIZE = 1024 * 64;
48 #else
49 const uint32_t MAX_JSON_SIZE = 1024 * 64;
50 #endif
51 
52 /*
53  * path should not include ".." or "./" or ".\0"
54  */
CheckRealPath(const char * path)55 bool BundleUtil::CheckRealPath(const char *path)
56 {
57     if (path == nullptr) {
58 #ifdef APP_PLATFORM_WATCHGT
59         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path null");
60 #endif
61         return false;
62     }
63     if (strlen(path) > PATH_LENGTH) {
64 #ifdef APP_PLATFORM_WATCHGT
65         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path too long:%d", strlen(path));
66 #endif
67         return false;
68     }
69     char *next = const_cast<char *>(path);
70     for (; *next != '\0'; next++) {
71         if (*next != '.') {
72             continue;
73         }
74         next++;
75         if (*next == '\0' || *next == '.' || *next == '/') {
76 #ifdef APP_PLATFORM_WATCHGT
77             HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path fail:%d", *next);
78 #endif
79             return false;
80         }
81     }
82     return true;
83 }
84 
IsFile(const char * path)85 bool BundleUtil::IsFile(const char *path)
86 {
87     if (!CheckRealPath(path)) {
88         return false;
89     }
90 
91     struct stat buf = { 0 };
92     int32_t ret = stat(path, &buf);
93     if (ret != 0) {
94         return false;
95     }
96 
97     int32_t fp = open(path, O_RDONLY, S_IREAD | S_IWRITE);
98     if (fp >= 0) {
99         close(fp);
100         return true;
101     }
102     return false;
103 }
104 
IsDir(const char * path)105 bool BundleUtil::IsDir(const char *path)
106 {
107     if (path == nullptr) {
108         return false;
109     }
110 
111     struct stat buf = { 0 };
112     int32_t ret = stat(path, &buf);
113     if (ret != 0) {
114         return false;
115     }
116 
117     if ((buf.st_mode & S_IFDIR) == S_IFDIR) {
118         return true;
119     }
120     return false;
121 }
122 
EndWith(const char * str,const char * subStr)123 bool BundleUtil::EndWith(const char *str, const char *subStr)
124 {
125     if (str == nullptr || subStr == nullptr) {
126         return false;
127     }
128 
129     int32_t strLen = strlen(str);
130     int32_t subStrLen = strlen(subStr);
131     if (strLen == 0 || subStrLen == 0 || strLen < subStrLen) {
132         return false;
133     }
134 
135     while (subStrLen >= 1) {
136         if (str[strLen - 1] != subStr[subStrLen - 1]) {
137             return false;
138         }
139         strLen--;
140         subStrLen--;
141     }
142     return true;
143 }
144 
StartWith(const char * str,const char * subStr)145 bool BundleUtil::StartWith(const char *str, const char *subStr)
146 {
147     if (str == nullptr || subStr == nullptr) {
148         return false;
149     }
150 
151     int32_t strLen = strlen(str);
152     int32_t subStrLen = strlen(subStr);
153     if (strLen == 0 || subStrLen == 0 || strLen < subStrLen) {
154         return false;
155     }
156 
157     int32_t index = 0;
158     while (index < subStrLen) {
159         if (str[index] != subStr[index]) {
160             return false;
161         }
162         index++;
163     }
164     return true;
165 }
166 
IsDigitStr(const char * str)167 bool BundleUtil::IsDigitStr(const char *str)
168 {
169     if (str == nullptr) {
170         return false;
171     }
172     return strspn(str, DIGITSTR) == strlen(str);
173 }
174 
GetFileSize(const char * filePath)175 uint32_t BundleUtil::GetFileSize(const char *filePath)
176 {
177     if (!CheckRealPath(filePath)) {
178         return 0;
179     }
180 
181     struct stat fileInfo;
182     int32_t ret = stat(filePath, &fileInfo);
183     if (ret != 0) {
184         return 0;
185     }
186     return fileInfo.st_size;
187 }
188 
GetFileFolderSize(const char * filePath)189 uint32_t BundleUtil::GetFileFolderSize(const char *filePath)
190 {
191     if (!CheckRealPath(filePath)) {
192         return 0;
193     }
194     List<char *>* list = new (std::nothrow)List<char *>();
195     if (list == nullptr) {
196 #ifdef APP_PLATFORM_WATCHGT
197         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetFolderSize failed, list is null");
198 #endif
199         return 0;
200     }
201 
202     list->PushFront(Utils::Strdup(filePath));
203     uint32_t fileFolderSize = 0;
204     while (!list->IsEmpty()) {
205         char *curPath = list->Front();
206         if (curPath == nullptr) {
207             break;
208         }
209         fileFolderSize += GetCurrentFolderSize(curPath, list);
210         list->PopFront();
211         AdapterFree(curPath);
212     }
213 
214     if (!list->IsEmpty()) {
215 #ifdef APP_PLATFORM_WATCHGT
216         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] After get folder size, list is still not empty");
217 #endif
218         for (auto node = list->Begin(); node != list->End(); node = node->next_) {
219             AdapterFree(node->value_);
220         }
221     }
222     delete list;
223     return fileFolderSize;
224 }
225 
GetCurrentFolderSize(const char * dirPath,List<char * > * list)226 uint32_t BundleUtil::GetCurrentFolderSize(const char *dirPath, List<char *>* list)
227 {
228     DIR *dir = nullptr;
229     if ((dir = opendir(dirPath)) == nullptr) {
230         return 0;
231     }
232     dirent *dp = nullptr;
233     char filePath[PATH_LENGTH] = { 0 };
234     struct stat buf = { 0 };
235     uint32_t fileSize = 0;
236     while ((dp = readdir(dir)) != nullptr) {
237         if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..")) == 0) {
238             continue;
239         }
240 
241         if (memset_s(filePath, PATH_LENGTH, 0, PATH_LENGTH) != EOK) {
242             continue;
243         }
244 
245         if (sprintf_s(filePath, PATH_LENGTH, "%s/%s", dirPath, dp->d_name) < 0) {
246             continue;
247         }
248 
249         if (!IsDir(filePath)) {
250             if (stat(filePath, &buf) != 0 || buf.st_size <= 0) {
251                 fileSize = 0;
252                 break;
253             }
254             fileSize += buf.st_size;
255         } else {
256             list->PushBack(Utils::Strdup(filePath));
257         }
258     }
259     closedir(dir);
260     return fileSize;
261 }
262 
DeleteJsonFile(const char * bundleName,const char * randStr)263 void BundleUtil::DeleteJsonFile(const char *bundleName, const char *randStr)
264 {
265     if (bundleName == nullptr || randStr == nullptr) {
266         return;
267     }
268     char *bundleTmpJsonPathComp[] = {
269         const_cast<char *>(JSON_PATH), const_cast<char *>(bundleName), const_cast<char *>(randStr),
270         const_cast<char *>(JSON_SUFFIX)
271     };
272 
273     char *bundleTmpJsonPath = Strscat(bundleTmpJsonPathComp, sizeof(bundleTmpJsonPathComp) / sizeof(char *));
274     if (bundleTmpJsonPath == nullptr) {
275         return;
276     }
277 
278     if (IsFile(bundleTmpJsonPath)) {
279 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
280         BundleDaemonClient::GetInstance().RemoveFile(bundleTmpJsonPath);
281 #else
282         (void)unlink(bundleTmpJsonPath);
283 #endif
284         AdapterFree(bundleTmpJsonPath);
285         return;
286     }
287     AdapterFree(bundleTmpJsonPath);
288 
289     char *bundleJsonPathComp[] = {
290         const_cast<char *>(JSON_PATH), const_cast<char *>(bundleName), const_cast<char *>(JSON_SUFFIX)
291     };
292     char *bundleJsonPath = Strscat(bundleJsonPathComp, sizeof(bundleJsonPathComp) / sizeof(char *));
293     if (bundleJsonPath == nullptr) {
294         return;
295     }
296     if (IsFile(bundleJsonPath)) {
297 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
298         BundleDaemonClient::GetInstance().RemoveFile(bundleJsonPath);
299 #else
300         (void)unlink(bundleJsonPath);
301 #endif
302     }
303     AdapterFree(bundleJsonPath);
304 }
305 
Strscat(char * str[],uint32_t len)306 char *BundleUtil::Strscat(char *str[], uint32_t len)
307 {
308     int32_t strSize = 0;
309     for (uint32_t i = 0; i < len; i++) {
310         if (str[i] == nullptr) {
311             return nullptr;
312         }
313         strSize += strlen(str[i]);
314     }
315 
316     char *outStr = reinterpret_cast<char *>(AdapterMalloc((strSize + 1) * sizeof(char)));
317     if (outStr == nullptr) {
318         return nullptr;
319     }
320 
321     char *pos = outStr;
322     int32_t count = 0;
323     for (uint32_t i = 0; i < len; i++) {
324         int32_t size = strlen(str[i]);
325         if (memcpy_s(pos, strSize + 1 - count, str[i], size) != EOK) {
326             AdapterFree(outStr);
327             return nullptr;
328         }
329         count += size;
330         pos += size;
331     }
332     *pos = '\0';
333     return outStr;
334 }
335 
GetJsonStream(const char * path)336 cJSON *BundleUtil::GetJsonStream(const char *path)
337 {
338     struct stat fileInfo;
339     int32_t size = 0;
340 
341     if (!IsFile(path)) {
342 #ifdef APP_PLATFORM_WATCHGT
343         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream IsFile fail");
344 #endif
345         return nullptr;
346     }
347 
348     if (stat(path, &fileInfo) != 0 || (size = fileInfo.st_size) <= 0) {
349 #ifdef APP_PLATFORM_WATCHGT
350         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream path fail");
351 #endif
352         return nullptr;
353     }
354 
355     if (size > MAX_JSON_SIZE) {
356 #ifdef APP_PLATFORM_WATCHGT
357         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream size fail:%d", size);
358 #endif
359         return nullptr;
360     }
361 
362     int32_t fp = open(path, O_RDONLY, S_IREAD | S_IWRITE);
363     if (fp < 0) {
364 #ifdef APP_PLATFORM_WATCHGT
365         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream open fail:%d", fp);
366 #endif
367         return nullptr;
368     }
369 
370     char *json = reinterpret_cast<char *>(AdapterMalloc(size));
371     if (json == nullptr) {
372         close(fp);
373 #ifdef APP_PLATFORM_WATCHGT
374         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream AdapterMalloc fail");
375 #endif
376         return nullptr;
377     }
378 
379     if (read(fp, json, size) != size) {
380         AdapterFree(json);
381         close(fp);
382 #ifdef APP_PLATFORM_WATCHGT
383         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream read fail");
384 #endif
385         return nullptr;
386     }
387     close(fp);
388 
389     cJSON *root = cJSON_Parse(json);
390     AdapterFree(json);
391     json = nullptr;
392     if (root == nullptr) {
393 #ifdef APP_PLATFORM_WATCHGT
394         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] cJSON_Parse fail");
395 #endif
396     }
397     return root;
398 }
399 
CheckBundleJsonIsValid(const char * bundleName,char ** codePath,char ** appId,int32_t & versionCode)400 bool BundleUtil::CheckBundleJsonIsValid(const char *bundleName, char **codePath, char **appId, int32_t &versionCode)
401 {
402     if (bundleName == nullptr || codePath == nullptr || appId == nullptr) {
403 #ifdef APP_PLATFORM_WATCHGT
404         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckBundleJsonIsValid parameters are not valid");
405 #endif
406         return false;
407     }
408 
409     char bundleJsonPath[PATH_LENGTH] = { 0 };
410     if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
411 #ifdef APP_PLATFORM_WATCHGT
412         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] failed to organize bundleJson data file path");
413 #endif
414         return false;
415     }
416 
417     cJSON *object = GetJsonStream(bundleJsonPath);
418     if (object == nullptr) {
419 #ifdef APP_PLATFORM_WATCHGT
420         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] failed to open json file");
421 #endif
422         return false;
423     }
424 
425     cJSON *item = cJSON_GetObjectItem(object, JSON_SUB_KEY_CODEPATH);
426     if (!cJSON_IsString(item)) {
427         cJSON_Delete(object);
428 #ifdef APP_PLATFORM_WATCHGT
429         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsing codePath is not a string");
430 #endif
431         return false;
432     }
433     *codePath = Utils::Strdup(item->valuestring);
434     if (*codePath == nullptr) {
435         cJSON_Delete(object);
436 #ifdef APP_PLATFORM_WATCHGT
437         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is nullptr");
438 #endif
439         return false;
440     }
441     if (!IsDir(*codePath)) {
442         cJSON_Delete(object);
443 #ifdef APP_PLATFORM_WATCHGT
444         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is not dir");
445 #endif
446         return false;
447     }
448     if (!EndWith(*codePath, bundleName)) {
449         cJSON_Delete(object);
450 #ifdef APP_PLATFORM_WATCHGT
451         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is not valid");
452 #endif
453         return false;
454     }
455 
456     item = cJSON_GetObjectItem(object, JSON_SUB_KEY_APPID);
457     if (!cJSON_IsString(item)) {
458         cJSON_Delete(object);
459 #ifdef APP_PLATFORM_WATCHGT
460         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsinng appId is not a string");
461 #endif
462         return false;
463     }
464     *appId = Utils::Strdup(item->valuestring);
465     if (*appId == nullptr) {
466         cJSON_Delete(object);
467 #ifdef APP_PLATFORM_WATCHGT
468         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed appId is null");
469 #endif
470         return false;
471     }
472 
473     item = cJSON_GetObjectItem(object, JSON_SUB_KEY_VERSIONCODE);
474     if (!cJSON_IsNumber(item)) {
475         cJSON_Delete(object);
476 #ifdef APP_PLATFORM_WATCHGT
477         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsinng versionCode is not a string");
478 #endif
479         return false;
480     }
481     versionCode = item->valueint;
482     if (versionCode < 0) {
483         cJSON_Delete(object);
484 #ifdef APP_PLATFORM_WATCHGT
485         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed versionCode is not valid");
486 #endif
487         return false;
488     }
489 
490     cJSON_Delete(object);
491     return true;
492 }
493 
GetValueFromBundleJson(const char * bundleName,const char * key)494 char *BundleUtil::GetValueFromBundleJson(const char *bundleName, const char *key)
495 {
496     if (bundleName == nullptr || key == nullptr) {
497         return nullptr;
498     }
499 
500     char bundleJsonPath[PATH_LENGTH] = { 0 };
501     if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
502         return nullptr;
503     }
504 
505     cJSON *object = GetJsonStream(bundleJsonPath);
506     if (object == nullptr) {
507         return nullptr;
508     }
509 
510     cJSON *item = cJSON_GetObjectItem(object, key);
511     if (!cJSON_IsString(item)) {
512         cJSON_Delete(object);
513         return nullptr;
514     }
515 
516     char *value = Utils::Strdup(item->valuestring);
517     cJSON_Delete(object);
518     return value;
519 }
520 
GetValueFromBundleJson(const char * bundleName,const char * key,int32_t defaultValue)521 int32_t BundleUtil::GetValueFromBundleJson(const char *bundleName, const char *key, int32_t defaultValue)
522 {
523     if (bundleName == nullptr || key == nullptr) {
524         return defaultValue;
525     }
526 
527     char bundleJsonPath[PATH_LENGTH] = { 0 };
528     if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
529         return defaultValue;
530     }
531 
532     cJSON *object = GetJsonStream(bundleJsonPath);
533     if (object == nullptr) {
534         return defaultValue;
535     }
536 
537     cJSON *item = cJSON_GetObjectItem(object, key);
538     if (!cJSON_IsNumber(item)) {
539         cJSON_Delete(object);
540         return defaultValue;
541     }
542 
543     int32_t value = item->valueint;
544     cJSON_Delete(object);
545     return value;
546 }
547 
ConvertInstallRecordToJson(const InstallRecord & installRecord)548 cJSON *BundleUtil::ConvertInstallRecordToJson(const InstallRecord &installRecord)
549 {
550     cJSON *root = cJSON_CreateObject();
551     if (root == nullptr) {
552         return nullptr;
553     }
554 
555     if ((cJSON_AddStringToObject(root, JSON_SUB_KEY_PACKAGE, installRecord.bundleName) == nullptr) ||
556         (cJSON_AddStringToObject(root, JSON_SUB_KEY_APPID, installRecord.appId) == nullptr) ||
557 #ifdef APP_PLATFORM_WATCHGT
558 #ifdef BC_TRANS_ENABLE
559     (cJSON_AddStringToObject(root, JSON_SUB_KEY_JSENGINE_VERSION, installRecord.jsEngineVersion) == nullptr) ||
560     (cJSON_AddNumberToObject(root, JSON_SUB_KEY_TRANSFORM_RESULT, installRecord.transformResult) == nullptr) ||
561 #endif
562 #endif
563     (cJSON_AddNumberToObject(root, JSON_SUB_KEY_VERSIONCODE, installRecord.versionCode) == nullptr) ||
564 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
565     (cJSON_AddNumberToObject(root, JSON_SUB_KEY_UID, installRecord.uid) == nullptr) ||
566     (cJSON_AddNumberToObject(root, JSON_SUB_KEY_GID, installRecord.gid) == nullptr) ||
567 #endif
568     (cJSON_AddStringToObject(root, JSON_SUB_KEY_CODEPATH, installRecord.codePath) == nullptr)) {
569         cJSON_Delete(root);
570         return nullptr;
571     }
572     return root;
573 }
574 
CreateRandStr(char * str,uint32_t len)575 void BundleUtil::CreateRandStr(char *str, uint32_t len)
576 {
577     if (str == nullptr) {
578         return;
579     }
580 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
581     srand(time(NULL));
582 #else
583     srand(LOS_TickCountGet());
584 #endif
585     uint32_t i;
586     for (i = 0; i < len - 1; ++i) {
587         switch ((rand() % NUM_OF_TYPE)) {
588             case 0:
589                 str[i] = 'A' + rand() % MAX_CHARACTER_VALUE;
590                 break;
591             case 1:
592                 str[i] = 'a' + rand() % MAX_CHARACTER_VALUE;
593                 break;
594             default:
595                 str[i] = '0' + rand() % MAX_SINGLE_DIGIT_VALUE;
596                 break;
597         }
598     }
599     str[i] = '\0';
600 }
601 
602 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
ObtainUidAndGidJson(bool flag)603 cJSON *BundleUtil::ObtainUidAndGidJson(bool flag)
604 {
605     std::string uidJsonPath = std::string(JSON_PATH) + UID_GID_MAP + JSON_SUFFIX;
606     cJSON *object = BundleUtil::GetJsonStream(uidJsonPath.c_str());
607     if ((object != nullptr) || (!flag)) {
608         return object;
609     }
610 
611     object = cJSON_CreateObject();
612     if (object == nullptr) {
613         return nullptr;
614     }
615     cJSON *size = cJSON_CreateNumber(0);
616     if (size == nullptr) {
617         cJSON_Delete(object);
618         return nullptr;
619     }
620     if (!cJSON_AddItemToObject(object, PROFILE_KEY_UID_SIZE, size)) {
621         cJSON_Delete(size);
622         cJSON_Delete(object);
623         return nullptr;
624     }
625     cJSON *uids = cJSON_AddArrayToObject(object, PROFILE_KEY_UID_AND_GID);
626     if (uids == nullptr) {
627         cJSON_Delete(object);
628         return nullptr;
629     }
630     return object;
631 }
632 
AddUidAndGidInfo(const InstallRecord & installRecord,cJSON * size,cJSON * uids)633 bool BundleUtil::AddUidAndGidInfo(const InstallRecord &installRecord, cJSON *size, cJSON *uids)
634 {
635     if ((size == nullptr) || (uids == nullptr)) {
636         return false;
637     }
638     cJSON_SetNumberValue(size, size->valueint + 1);
639     cJSON *uid = cJSON_CreateObject();
640     if (uid == nullptr) {
641         return false;
642     }
643     if ((cJSON_AddStringToObject(uid, JSON_SUB_KEY_PACKAGE, installRecord.bundleName) == nullptr) ||
644         (cJSON_AddNumberToObject(uid, JSON_SUB_KEY_UID, installRecord.uid) == nullptr) ||
645         (cJSON_AddNumberToObject(uid, JSON_SUB_KEY_GID, installRecord.gid) == nullptr)) {
646         cJSON_Delete(uid);
647         return false;
648     }
649     if (!cJSON_AddItemToArray(uids, uid)) {
650         cJSON_Delete(uid);
651         return false;
652     }
653     return true;
654 }
655 
ConvertUidAndGidToJson(const InstallRecord & installRecord)656 cJSON *BundleUtil::ConvertUidAndGidToJson(const InstallRecord &installRecord)
657 {
658     if (installRecord.bundleName == nullptr) {
659         return nullptr;
660     }
661 
662     cJSON *object = ObtainUidAndGidJson(true);
663     if (object == nullptr) {
664         return nullptr;
665     }
666 
667     cJSON *size = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_SIZE);
668     if (!cJSON_IsNumber(size)) {
669         cJSON_Delete(object);
670         return nullptr;
671     }
672     cJSON *uids = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_AND_GID);
673     if (!cJSON_IsArray(uids)) {
674         cJSON_Delete(object);
675         return nullptr;
676     }
677 
678     cJSON *item = nullptr;
679     cJSON_ArrayForEach(item, uids) {
680         cJSON *innerBundleName = cJSON_GetObjectItemCaseSensitive(item, JSON_SUB_KEY_PACKAGE);
681         if ((cJSON_IsString(innerBundleName)) && (innerBundleName->valuestring != nullptr)) {
682             if (strcmp(innerBundleName->valuestring, installRecord.bundleName) == 0) {
683                 return object;
684             }
685         }
686     }
687 
688     if (!AddUidAndGidInfo(installRecord, size, uids)) {
689         cJSON_Delete(object);
690         return nullptr;
691     }
692 
693     return object;
694 }
695 
DeleteInnerUidInfoFromUidArray(const char * bundleName,cJSON * size,cJSON * uids)696 bool BundleUtil::DeleteInnerUidInfoFromUidArray(const char *bundleName, cJSON *size, cJSON *uids)
697 {
698     if ((size == nullptr) || (uids == nullptr) || (bundleName == nullptr)) {
699         return false;
700     }
701     cJSON *uid = nullptr;
702     int32_t index = -1;
703     bool isFound = false;
704     cJSON_ArrayForEach(uid, uids) {
705         index++;
706         cJSON *innerBundleName = cJSON_GetObjectItemCaseSensitive(uid, JSON_SUB_KEY_PACKAGE);
707         if ((cJSON_IsString(innerBundleName)) && (innerBundleName->valuestring != nullptr)) {
708             if (strcmp(innerBundleName->valuestring, bundleName) == 0) {
709                 isFound = true;
710                 break;
711             }
712         }
713     }
714     if (isFound) {
715         cJSON_DeleteItemFromArray(uids, index);
716         cJSON_SetNumberValue(size, size->valueint - 1);
717     }
718     return true;
719 }
720 
DeleteUidInfoFromJson(const char * bundleName)721 bool BundleUtil::DeleteUidInfoFromJson(const char *bundleName)
722 {
723     cJSON *object = ObtainUidAndGidJson(false);
724     if (object == nullptr) {
725         return false;
726     }
727 
728     cJSON *size = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_SIZE);
729     if (!cJSON_IsNumber(size)) {
730         cJSON_Delete(object);
731         return false;
732     }
733     cJSON *uids = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_AND_GID);
734     if (!cJSON_IsArray(uids)) {
735         cJSON_Delete(object);
736         return false;
737     }
738     if (!DeleteInnerUidInfoFromUidArray(bundleName, size, uids)) {
739         cJSON_Delete(object);
740         return false;
741     }
742 
743     std::string uidJsonPath = std::string(JSON_PATH) + UID_GID_MAP + JSON_SUFFIX;
744     if (size->valueint == 0) {
745         BundleDaemonClient::GetInstance().RemoveFile(uidJsonPath.c_str());
746     } else {
747         char *out = cJSON_Print(object);
748         if (out == nullptr) {
749             cJSON_Delete(object);
750             return false;
751         }
752         BundleDaemonClient::GetInstance().StoreContentToFile(uidJsonPath.c_str(), out, strlen(out) + 1);
753         cJSON_free(out);
754     }
755 
756     cJSON_Delete(object);
757     return true;
758 }
759 #else
MkDirs(const char * dir)760 bool BundleUtil::MkDirs(const char *dir)
761 {
762     if (IsDir(dir)) {
763         return true;
764     }
765     if (strlen(dir) > PATH_LENGTH) {
766 #ifdef APP_PLATFORM_WATCHGT
767         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] MkDirs failed, path is too long");
768 #endif
769         return false;
770     }
771     int32_t len = strlen(dir);
772     char *rootDir = nullptr;
773     bool isRootDirExists = true;
774     for (int32_t i = 1; i < len; i++) {
775         if (dir[i] != '/') {
776             continue;
777         }
778         rootDir = GetRootDir(dir, i);
779         if (rootDir == nullptr) {
780 #ifdef APP_PLATFORM_WATCHGT
781             HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] MkDirs failed, rootDir is null");
782 #endif
783             return false;
784         }
785         if (isRootDirExists) {
786             if (IsDir(rootDir)) {
787                 UI_Free(rootDir);
788                 rootDir = nullptr;
789                 continue;
790             }
791             isRootDirExists = false;
792         }
793         if (mkdir(rootDir, S_IREAD | S_IWRITE) < 0) {
794             UI_Free(rootDir);
795 #ifdef APP_PLATFORM_WATCHGT
796             HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] make rootDir failed");
797 #endif
798             return false;
799         }
800         UI_Free(rootDir);
801         rootDir = nullptr;
802     }
803     return (mkdir(dir, S_IREAD | S_IWRITE) < 0) ? false : true;
804 }
805 
RemoveDir(const char * path)806 bool BundleUtil::RemoveDir(const char *path)
807 {
808     if (!IsDir(path)) {
809         (void) unlink(path);
810         return true;
811     }
812 
813     List<char *>* list = new (std::nothrow)List<char *>();
814     if (list == nullptr) {
815 #ifdef APP_PLATFORM_WATCHGT
816         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] RemoveDir failed, list is null");
817 #endif
818         return false;
819     }
820     list->PushFront(Utils::Strdup(path));
821     while (!list->IsEmpty()) {
822         char *curPath = list->Front();
823         if (curPath == nullptr) {
824             break;
825         }
826         if (CheckDirIsEmpty(curPath, list)) {
827             list->PopFront();
828             if (rmdir(curPath) < 0) {
829                 AdapterFree(curPath);
830                 break;
831             }
832             AdapterFree(curPath);
833         }
834     }
835 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
836     for (auto node = list->Begin(); node != list->End(); node = node->next_) {
837         AdapterFree(node->value_);
838     }
839 #endif
840     if (!list->IsEmpty()) {
841         delete list;
842 #ifdef APP_PLATFORM_WATCHGT
843         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] After delete, file is still not empty");
844 #endif
845         return false;
846     }
847 
848     delete list;
849     return true;
850 }
851 
RenameDir(const char * oldDir,const char * newDir)852 bool BundleUtil::RenameDir(const char *oldDir, const char *newDir)
853 {
854     if (oldDir == nullptr || newDir == nullptr) {
855         return false;
856     }
857 
858     if (IsDir(newDir) && !RemoveDir(newDir)) {
859         return false;
860     }
861 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
862     if (frename(oldDir, newDir) != 0) {
863         return false;
864     }
865 #else
866     if (rename(oldDir, newDir) != 0) {
867         return false;
868     }
869 #endif
870     return true;
871 }
872 
RenameFile(const char * oldFile,const char * newFile)873 bool BundleUtil::RenameFile(const char *oldFile, const char *newFile)
874 {
875     if (oldFile == nullptr || newFile == nullptr) {
876         return false;
877     }
878 
879     if (IsFile(newFile) && unlink(newFile) < 0) {
880         return false;
881     }
882 
883 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
884     if (frename(oldFile, newFile) != 0) {
885         return false;
886     }
887 #else
888     if (rename(oldFile, newFile) != 0) {
889         return false;
890     }
891 #endif
892     return true;
893 }
894 
GetRootDir(const char * dir,int32_t index)895 char *BundleUtil::GetRootDir(const char *dir, int32_t index)
896 {
897     char *rootDir = reinterpret_cast<char *>(UI_Malloc((index + 1) * sizeof(char)));
898     if (rootDir == nullptr) {
899         return nullptr;
900     }
901     errno_t err = strncpy_s(rootDir, index + 1, dir, index);
902     if (err != EOK) {
903         UI_Free(rootDir);
904         return nullptr;
905     }
906     return rootDir;
907 }
908 
CheckDirIsEmpty(const char * dirPath,List<char * > * list)909 bool BundleUtil::CheckDirIsEmpty(const char *dirPath, List<char *>* list)
910 {
911     DIR *dir = nullptr;
912     if ((dir = opendir(dirPath)) == nullptr) {
913         return false;
914     }
915     bool isEmptyDir = true;
916     dirent *dp = nullptr;
917     char filePath[PATH_LENGTH] = { 0 };
918     while ((dp = readdir(dir)) != nullptr) {
919         if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..")) == 0) {
920             continue;
921         }
922 
923         if (memset_s(filePath, PATH_LENGTH, 0, PATH_LENGTH) != EOK) {
924             continue;
925         }
926 
927         if (sprintf_s(filePath, PATH_LENGTH, "%s/%s", dirPath, dp->d_name) < 0) {
928             continue;
929         }
930 
931         if (IsDir(filePath)) {
932             list->PushFront(Utils::Strdup(filePath));
933             isEmptyDir = false;
934         } else {
935             (void) unlink(filePath);
936         }
937     }
938     closedir(dir);
939     return isEmptyDir;
940 }
StoreJsonContentToFile(const char * packageJson,const cJSON * object)941 bool BundleUtil::StoreJsonContentToFile(const char *packageJson, const cJSON *object)
942 {
943     if (object == nullptr) {
944 #ifdef APP_PLATFORM_WATCHGT
945         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json data object is null");
946 #endif
947         return false;
948     }
949 
950     char *out = cJSON_Print(object);
951     if (out == nullptr) {
952 #ifdef APP_PLATFORM_WATCHGT
953         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] turn Json data to char sequence failed");
954 #endif
955         return false;
956     }
957 
958     if (!CheckRealPath(packageJson)) {
959         cJSON_free(out);
960 #ifdef APP_PLATFORM_WATCHGT
961         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json file path doest not exist");
962 #endif
963         return false;
964     }
965 
966     if (IsFile(packageJson) && unlink(packageJson) < 0) {
967         cJSON_free(out);
968 #ifdef APP_PLATFORM_WATCHGT
969         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json file path is invalid");
970 #endif
971         return false;
972     }
973 
974     int32_t fp = open(packageJson, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
975     if (fp < 0) {
976         cJSON_free(out);
977 #ifdef APP_PLATFORM_WATCHGT
978         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] open Json file failed");
979 #endif
980         return false;
981     }
982 
983     if (write(fp, out, strlen(out)) != strlen(out)) {
984         cJSON_free(out);
985         close(fp);
986 #ifdef APP_PLATFORM_WATCHGT
987         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] write to Json file failed");
988 #endif
989         return false;
990     }
991 
992     cJSON_free(out);
993     close(fp);
994     return true;
995 }
996 
FreeStrArrayMemory(char ** pointer,uint32_t len)997 void BundleUtil::FreeStrArrayMemory(char **pointer, uint32_t len)
998 {
999     if (len != 0 && pointer != nullptr) {
1000         for (uint32_t i = 0; i < len; i++) {
1001             AdapterFree(*(pointer + i));
1002         }
1003         AdapterFree(pointer);
1004     }
1005 }
1006 #endif
1007 } // namespace OHOS