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