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             FSCRYPT_LOGE("Failed to read config file, err = %d", errno);
51             break;
52         }
53         buffer[fileStat.st_size] = '\0';
54     } while (0);
55 
56     if (fd != NULL) {
57         (void)fclose(fd);
58         fd = NULL;
59     }
60     return buffer;
61 }
62 
SplitString(char * srcPtr,const char * del,char ** dstPtr,int maxNum)63 int SplitString(char *srcPtr, const char *del, char **dstPtr, int maxNum)
64 {
65     FSCRYPT_CHECK_RETURN_VALUE(srcPtr != NULL && dstPtr != NULL && del != NULL, -1);
66     char *buf = NULL;
67     dstPtr[0] = strtok_r(srcPtr, del, &buf);
68     int counter = 0;
69     while ((counter < maxNum) && (dstPtr[counter] != NULL)) {
70         counter++;
71         if (counter >= maxNum) {
72             break;
73         }
74         dstPtr[counter] = strtok_r(NULL, del, &buf);
75     }
76     return counter;
77 }
78 
FreeStringVector(char ** vector,int count)79 void FreeStringVector(char **vector, int count)
80 {
81     if (vector != NULL) {
82         for (int i = 0; i < count; i++) {
83             if (vector[i] != NULL) {
84                 free(vector[i]);
85             }
86         }
87         free(vector);
88     }
89 }
90 
SplitStringExt(char * buffer,const char * del,int * returnCount,int maxItemCount)91 char **SplitStringExt(char *buffer, const char *del, int *returnCount, int maxItemCount)
92 {
93     FSCRYPT_CHECK_RETURN_VALUE((maxItemCount >= 0) && (buffer != NULL) && (del != NULL) && (returnCount != NULL), NULL);
94     // Why is this number?
95     // Now we use this function to split a string with a given delimiter
96     // We do not know how many sub-strings out there after splitting.
97     // 50 is just a guess value.
98     const int defaultItemCounts = 50;
99     int itemCounts = maxItemCount;
100 
101     if (maxItemCount > defaultItemCounts) {
102         itemCounts = defaultItemCounts;
103     }
104     char **items = (char **)malloc(sizeof(char*) * itemCounts);
105     FSCRYPT_ERROR_CHECK(items != NULL, return NULL, "No enough memory to store items");
106     char *rest = NULL;
107     char *p = strtok_r(buffer, del, &rest);
108     int count = 0;
109     while (p != NULL) {
110         if (count > itemCounts - 1) {
111             itemCounts += (itemCounts / 2) + 1; // 2 Request to increase the original memory by half.
112             FSCRYPT_LOGV("Too many items,expand size");
113 
114             char **expand = (char **)malloc(sizeof(char*) * itemCounts);
115             FSCRYPT_ERROR_CHECK(expand != NULL, FreeStringVector(items, count);
116                 return NULL, "Failed to expand memory");
117             int ret = memcpy_s(expand, sizeof(char *) * itemCounts, items, sizeof(char *) * count);
118             if (ret != 0) {
119                 FreeStringVector(items, count);
120                 FreeStringVector(expand, itemCounts);
121                 FSCRYPT_LOGV("Too many items,expand size");
122                 return NULL;
123             }
124             items = expand;
125         }
126         size_t len = strlen(p);
127         items[count] = (char *)malloc(len + 1);
128         FSCRYPT_CHECK(items[count] != NULL, FreeStringVector(items, count);
129             return NULL);
130         if (strncpy_s(items[count], len + 1, p, len) != EOK) {
131             FSCRYPT_LOGE("Copy string failed");
132             FreeStringVector(items, count);
133             return NULL;
134         }
135         items[count][len] = '\0';
136         count++;
137         p = strtok_r(NULL, del, &rest);
138     }
139     *returnCount = count;
140     return items;
141 }