1 /*
2 * Copyright (c) 2023 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 #include "init_utils.h"
16
17 #include <string.h>
18
19 #include "fscrypt_log.h"
20 #include "securec.h"
21
22 #define MAX_FILE_LEN 102400 // max init.cfg size 100KB
23
ReadFileToBuf(const char * configFile)24 char *ReadFileToBuf(const char *configFile)
25 {
26 char *buffer = NULL;
27 FILE *fd = NULL;
28 struct stat fileStat = {0};
29 FSCRYPT_CHECK_RETURN_VALUE(configFile != NULL && *configFile != '\0', NULL);
30 do {
31 if (stat(configFile, &fileStat) != 0 ||
32 fileStat.st_size <= 0 || fileStat.st_size > MAX_FILE_LEN) {
33 FSCRYPT_LOGE("Unexpected config file \" %s \", check if it exist. if exist, check file size", configFile);
34 break;
35 }
36 fd = fopen(configFile, "r");
37 if (fd == NULL) {
38 FSCRYPT_LOGE("Open %s failed. err = %d", configFile, errno);
39 break;
40 }
41 buffer = (char*)malloc((size_t)(fileStat.st_size + 1));
42 if (buffer == NULL) {
43 FSCRYPT_LOGE("Failed to allocate memory for config file, err = %d", errno);
44 break;
45 }
46
47 if (fread(buffer, fileStat.st_size, 1, fd) != 1) {
48 free(buffer);
49 buffer = NULL;
50 break;
51 }
52 buffer[fileStat.st_size] = '\0';
53 } while (0);
54
55 if (fd != NULL) {
56 (void)fclose(fd);
57 fd = NULL;
58 }
59 return buffer;
60 }
61
SplitString(char * srcPtr,const char * del,char ** dstPtr,int maxNum)62 int SplitString(char *srcPtr, const char *del, char **dstPtr, int maxNum)
63 {
64 FSCRYPT_CHECK_RETURN_VALUE(srcPtr != NULL && dstPtr != NULL && del != NULL, -1);
65 char *buf = NULL;
66 dstPtr[0] = strtok_r(srcPtr, del, &buf);
67 int counter = 0;
68 while ((counter < maxNum) && (dstPtr[counter] != NULL)) {
69 counter++;
70 if (counter >= maxNum) {
71 break;
72 }
73 dstPtr[counter] = strtok_r(NULL, del, &buf);
74 }
75 return counter;
76 }
77
FreeStringVector(char ** vector,int count)78 void FreeStringVector(char **vector, int count)
79 {
80 if (vector != NULL) {
81 for (int i = 0; i < count; i++) {
82 if (vector[i] != NULL) {
83 free(vector[i]);
84 }
85 }
86 free(vector);
87 }
88 }
89
SplitStringExt(char * buffer,const char * del,int * returnCount,int maxItemCount)90 char **SplitStringExt(char *buffer, const char *del, int *returnCount, int maxItemCount)
91 {
92 FSCRYPT_CHECK_RETURN_VALUE((maxItemCount >= 0) && (buffer != NULL) && (del != NULL) && (returnCount != NULL), NULL);
93 // Why is this number?
94 // Now we use this function to split a string with a given delimiter
95 // We do not know how many sub-strings out there after splitting.
96 // 50 is just a guess value.
97 const int defaultItemCounts = 50;
98 int itemCounts = maxItemCount;
99
100 if (maxItemCount > defaultItemCounts) {
101 itemCounts = defaultItemCounts;
102 }
103 char **items = (char **)malloc(sizeof(char*) * itemCounts);
104 FSCRYPT_ERROR_CHECK(items != NULL, return NULL, "No enough memory to store items");
105 char *rest = NULL;
106 char *p = strtok_r(buffer, del, &rest);
107 int count = 0;
108 while (p != NULL) {
109 if (count > itemCounts - 1) {
110 itemCounts += (itemCounts / 2) + 1; // 2 Request to increase the original memory by half.
111 FSCRYPT_LOGV("Too many items,expand size");
112
113 char **expand = (char **)malloc(sizeof(char*) * itemCounts);
114 FSCRYPT_ERROR_CHECK(expand != NULL, FreeStringVector(items, count);
115 return NULL, "Failed to expand memory");
116 int ret = memcpy_s(expand, sizeof(char *) * itemCounts, items, sizeof(char *) * count);
117 if (ret != 0) {
118 FreeStringVector(items, count);
119 FreeStringVector(expand, itemCounts);
120 FSCRYPT_LOGV("Too many items,expand size");
121 return NULL;
122 }
123 items = expand;
124 }
125 size_t len = strlen(p);
126 items[count] = (char *)malloc(len + 1);
127 FSCRYPT_CHECK(items[count] != NULL, FreeStringVector(items, count);
128 return NULL);
129 if (strncpy_s(items[count], len + 1, p, len) != EOK) {
130 FSCRYPT_LOGE("Copy string failed");
131 FreeStringVector(items, count);
132 return NULL;
133 }
134 items[count][len] = '\0';
135 count++;
136 p = strtok_r(NULL, del, &rest);
137 }
138 *returnCount = count;
139 return items;
140 }