• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 
16 #include "softbus_json_utils.h"
17 
18 #include <securec.h>
19 
20 #include "comm_log.h"
21 #include "softbus_adapter_mem.h"
22 #include "softbus_error_code.h"
23 
24 #define MAX_STR_LEN (512 * 1024)
25 #define MAX_DEPTH 10
26 
GetStringItemByJsonObject(const cJSON * json,const char * const string,char * target,uint32_t targetLen)27 int32_t GetStringItemByJsonObject(const cJSON *json, const char * const string, char *target,
28     uint32_t targetLen)
29 {
30     if (json == NULL || string == NULL || target == NULL) {
31         COMM_LOGE(COMM_UTILS, "invalid param");
32         return SOFTBUS_INVALID_PARAM;
33     }
34     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
35     if (item == NULL || !cJSON_IsString(item)) {
36         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
37         return SOFTBUS_PARSE_JSON_ERR;
38     }
39     uint32_t length = strlen(item->valuestring);
40     if (length >= targetLen) {
41         COMM_LOGE(COMM_UTILS, "the length is to long. length=%{public}d, string=%{public}s", length, string);
42         return SOFTBUS_INVALID_PARAM;
43     }
44     int32_t ret = strcpy_s(target, targetLen, item->valuestring);
45     if (ret != EOK) {
46         COMM_LOGE(COMM_UTILS, "strcpy error. ret=%{public}d", ret);
47         return SOFTBUS_STRCPY_ERR;
48     }
49     return SOFTBUS_OK;
50 }
51 
GetJsonObjectStringItem(const cJSON * json,const char * const string,char * target,uint32_t targetLen)52 bool GetJsonObjectStringItem(const cJSON *json, const char * const string, char *target,
53     uint32_t targetLen)
54 {
55     if (json == NULL || string == NULL || target == NULL) {
56         COMM_LOGE(COMM_UTILS, "invalid param");
57         return false;
58     }
59     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
60     if (item == NULL || !cJSON_IsString(item)) {
61         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
62         return false;
63     }
64     uint32_t length = strlen(item->valuestring);
65     if (length >= targetLen) {
66         COMM_LOGE(COMM_UTILS, "the length is to long. length=%{public}d, string=%{public}s", length, string);
67         return false;
68     }
69     int32_t ret = strcpy_s(target, targetLen, item->valuestring);
70     if (ret != EOK) {
71         COMM_LOGE(COMM_UTILS, "strcpy error. ret=%{public}d", ret);
72         return false;
73     }
74     return true;
75 }
76 
GetJsonObjectNumberItem(const cJSON * json,const char * const string,int32_t * target)77 bool GetJsonObjectNumberItem(const cJSON *json, const char * const string, int32_t *target)
78 {
79     if (json == NULL || string == NULL || target == NULL) {
80         COMM_LOGE(COMM_UTILS, "invalid param");
81         return false;
82     }
83     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
84     if (item == NULL || !cJSON_IsNumber(item) || (item->valuedouble < 0)) {
85         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
86         return false;
87     }
88     *target = (int32_t)item->valuedouble;
89     return true;
90 }
91 
GetJsonObjectSignedNumberItem(const cJSON * json,const char * const string,int32_t * target)92 bool GetJsonObjectSignedNumberItem(const cJSON *json, const char * const string, int32_t *target)
93 {
94     if (json == NULL || string == NULL || target == NULL) {
95         COMM_LOGE(COMM_UTILS, "invalid param");
96         return false;
97     }
98     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
99     if (item == NULL || !cJSON_IsNumber(item)) {
100         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
101         return false;
102     }
103     *target = (int32_t)item->valuedouble;
104     return true;
105 }
106 
GetJsonObjectDoubleItem(const cJSON * json,const char * const string,double * target)107 bool GetJsonObjectDoubleItem(const cJSON *json, const char * const string, double *target)
108 {
109     if (json == NULL || string == NULL || target == NULL) {
110         COMM_LOGE(COMM_UTILS, "invalid param");
111         return false;
112     }
113     cJSON* item = cJSON_GetObjectItemCaseSensitive(json, string);
114     if (item == NULL || !cJSON_IsNumber(item)) {
115         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
116         return false;
117     }
118     *target = item->valuedouble;
119     return true;
120 }
121 
GetJsonObjectNumber16Item(const cJSON * json,const char * const string,uint16_t * target)122 bool GetJsonObjectNumber16Item(const cJSON *json, const char * const string, uint16_t *target)
123 {
124     if (json == NULL || string == NULL || target == NULL) {
125         COMM_LOGE(COMM_UTILS, "invalid param");
126         return false;
127     }
128     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
129     if (item == NULL || !cJSON_IsNumber(item) || (item->valuedouble < 0)) {
130         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
131         return false;
132     }
133     *target = (uint16_t)item->valuedouble;
134     return true;
135 }
136 
GetJsonObjectNumber64Item(const cJSON * json,const char * const string,int64_t * target)137 bool GetJsonObjectNumber64Item(const cJSON *json, const char * const string, int64_t *target)
138 {
139     if (json == NULL || string == NULL || target == NULL) {
140         COMM_LOGE(COMM_UTILS, "invalid param");
141         return false;
142     }
143     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
144     if (item == NULL || !cJSON_IsNumber(item) || (item->valuedouble < 0)) {
145         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
146         return false;
147     }
148     *target = (int64_t)item->valuedouble;
149     return true;
150 }
151 
GetJsonObjectSignedNumber64Item(const cJSON * json,const char * const string,int64_t * target)152 bool GetJsonObjectSignedNumber64Item(const cJSON *json, const char * const string, int64_t *target)
153 {
154     if (json == NULL || string == NULL || target == NULL) {
155         COMM_LOGE(COMM_UTILS, "invalid param");
156         return false;
157     }
158     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
159     if (item == NULL || !cJSON_IsNumber(item)) {
160         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
161         return false;
162     }
163     *target = (int64_t)item->valuedouble;
164     return true;
165 }
166 
GetJsonObjectInt32Item(const cJSON * json,const char * const string,int32_t * target)167 bool GetJsonObjectInt32Item(const cJSON *json, const char * const string, int32_t *target)
168 {
169     if (json == NULL || string == NULL || target == NULL) {
170         COMM_LOGE(COMM_UTILS, "invalid param");
171         return false;
172     }
173     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
174     if (item == NULL || !cJSON_IsNumber(item)) {
175         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
176         return false;
177     }
178     *target = (int32_t)item->valuedouble;
179     return true;
180 }
181 
GetJsonObjectBoolItem(const cJSON * json,const char * const string,bool * target)182 bool GetJsonObjectBoolItem(const cJSON *json, const char * const string, bool *target)
183 {
184     if (json == NULL || string == NULL || target == NULL) {
185         COMM_LOGE(COMM_UTILS, "invalid param");
186         return false;
187     }
188     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
189     if (item == NULL || !cJSON_IsBool(item)) {
190         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
191         return false;
192     }
193     *target = (bool)item->valueint;
194     return true;
195 }
196 
AddStringToJsonObject(cJSON * json,const char * const string,const char * value)197 bool AddStringToJsonObject(cJSON *json, const char * const string, const char *value)
198 {
199     if (value == NULL || json == NULL || string == NULL) {
200         COMM_LOGE(COMM_UTILS, "invalid param");
201         return false;
202     }
203     cJSON *item = cJSON_CreateString(value);
204     if (item == NULL) {
205         COMM_LOGD(COMM_UTILS, "Cannot create cJSON string object. string=%{public}s", string);
206         return false;
207     }
208     if (!cJSON_AddItemToObject(json, string, item)) {
209         cJSON_Delete(item);
210         return false;
211     }
212     return true;
213 }
214 
AddStringArrayToJsonObject(cJSON * json,const char * const string,const char * const * strings,int32_t count)215 bool AddStringArrayToJsonObject(cJSON *json, const char * const string, const char * const *strings, int32_t count)
216 {
217     COMM_CHECK_AND_RETURN_RET_LOGE(json != NULL && string != NULL && strings != NULL, false, COMM_UTILS,
218         "param is null");
219     COMM_CHECK_AND_RETURN_RET_LOGE(count > 0, false, COMM_UTILS, "count <= 0");
220 
221     cJSON *item = cJSON_CreateStringArray(strings, count);
222     if (item == NULL) {
223         COMM_LOGE(COMM_UTILS, "Cannot create cJSON string array object. string=%{public}s", string);
224         return false;
225     }
226 
227     if (!cJSON_AddItemToObject(json, string, item)) {
228         COMM_LOGE(COMM_UTILS, "Cannot add string array object to json. string=%{public}s", string);
229         cJSON_Delete(item);
230         return false;
231     }
232     return true;
233 }
234 
AddNumber16ToJsonObject(cJSON * json,const char * const string,uint16_t num)235 bool AddNumber16ToJsonObject(cJSON *json, const char * const string, uint16_t num)
236 {
237     if (json == NULL || string == NULL) {
238         COMM_LOGE(COMM_UTILS, "invalid param");
239         return false;
240     }
241     cJSON *item = cJSON_CreateNumber((double)num);
242     if (item == NULL) {
243         COMM_LOGE(COMM_UTILS, "Cannot create cJSON number object. string=%{public}s", string);
244         return false;
245     }
246     if (!cJSON_AddItemToObject(json, string, item)) {
247         COMM_LOGE(COMM_UTILS, "Cannot add num object to json. string=%{public}s", string);
248         cJSON_Delete(item);
249         return false;
250     }
251     return true;
252 }
253 
AddNumberToJsonObject(cJSON * json,const char * const string,int32_t num)254 bool AddNumberToJsonObject(cJSON *json, const char * const string, int32_t num)
255 {
256     if (json == NULL || string == NULL) {
257         COMM_LOGE(COMM_UTILS, "invalid param");
258         return false;
259     }
260     cJSON *item = cJSON_CreateNumber((double)num);
261     if (item == NULL) {
262         COMM_LOGE(COMM_UTILS, "Cannot create cJSON number object. string=%{public}s", string);
263         return false;
264     }
265     if (!cJSON_AddItemToObject(json, string, item)) {
266         COMM_LOGE(COMM_UTILS, "Cannot add num object to json. string=%{public}s", string);
267         cJSON_Delete(item);
268         return false;
269     }
270     return true;
271 }
272 
AddNumber64ToJsonObject(cJSON * json,const char * const string,int64_t num)273 bool AddNumber64ToJsonObject(cJSON *json, const char * const string, int64_t num)
274 {
275     if (json == NULL || string == NULL) {
276         COMM_LOGE(COMM_UTILS, "invalid param");
277         return false;
278     }
279     cJSON *item = cJSON_CreateNumber((double)num);
280     if (item == NULL) {
281         COMM_LOGE(COMM_UTILS, "Cannot create cJSON number object. string=%{public}s", string);
282         return false;
283     }
284     if (!cJSON_AddItemToObject(json, string, item)) {
285         COMM_LOGE(COMM_UTILS, "Cannot add num64 object to json. string=%{public}s", string);
286         cJSON_Delete(item);
287         return false;
288     }
289     return true;
290 }
291 
AddDoubleToJsonObject(cJSON * json,const char * const string,double num)292 bool AddDoubleToJsonObject(cJSON *json, const char * const string, double num)
293 {
294     if (json == NULL || string == NULL) {
295         COMM_LOGE(COMM_UTILS, "invalid param");
296         return false;
297     }
298     cJSON *item = cJSON_CreateNumber(num);
299     if (item == NULL) {
300         COMM_LOGE(COMM_UTILS, "Cannot create cJSON number object. string=%{public}s", string);
301         return false;
302     }
303     if (!cJSON_AddItemToObject(json, string, item)) {
304         COMM_LOGE(COMM_UTILS, "Cannot add double object to json. string=%{public}s", string);
305         cJSON_Delete(item);
306         return false;
307     }
308     return true;
309 }
310 
AddBoolToJsonObject(cJSON * json,const char * const string,bool value)311 bool AddBoolToJsonObject(cJSON *json, const char * const string, bool value)
312 {
313     if (json == NULL || string == NULL) {
314         COMM_LOGE(COMM_UTILS, "invalid param");
315         return false;
316     }
317     cJSON *item = cJSON_CreateBool(value);
318     if (item == NULL) {
319         COMM_LOGE(COMM_UTILS, "Cannot create cJSON bool object. string=%{public}s", string);
320         return false;
321     }
322     if (!cJSON_AddItemToObject(json, string, item)) {
323         COMM_LOGE(COMM_UTILS, "Cannot add bool object to json. string=%{public}s", string);
324         cJSON_Delete(item);
325         return false;
326     }
327     return true;
328 }
329 
GetDynamicStringItemByJsonObject(const cJSON * const json,const char * const string,uint32_t limit)330 char *GetDynamicStringItemByJsonObject(const cJSON * const json, const char * const string, uint32_t limit)
331 {
332     if (json == NULL || string == NULL) {
333         COMM_LOGE(COMM_UTILS, "invalid param");
334         return NULL;
335     }
336 
337     cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string);
338     if (item == NULL || !cJSON_IsString(item)) {
339         COMM_LOGD(COMM_UTILS, "Cannot find or invalid string. string=%{public}s", string);
340         return NULL;
341     }
342     uint32_t length = strlen(item->valuestring);
343     if (length > limit) {
344         COMM_LOGE(COMM_UTILS,
345             "key length is large than limit. string=%{public}s, length=%{public}u, limit=%{public}u", string, length,
346             limit);
347         return NULL;
348     }
349     char *value = SoftBusCalloc(length + 1);
350     if (value == NULL) {
351         COMM_LOGE(COMM_UTILS, "malloc failed, length=%{public}u", length);
352         return NULL;
353     }
354     if (strcpy_s(value, length + 1, item->valuestring) != EOK) {
355         COMM_LOGE(COMM_UTILS, "copy failed, length=%{public}u", length);
356         SoftBusFree(value);
357         return NULL;
358     }
359     return value;
360 }
361 
AddIntArrayToJsonObject(cJSON * json,const char * string,const int32_t * array,int32_t arrayLen)362 bool AddIntArrayToJsonObject(cJSON *json, const char *string, const int32_t *array, int32_t arrayLen)
363 {
364     if (json == NULL || string == NULL || array == NULL || arrayLen <= 0) {
365         COMM_LOGE(COMM_UTILS, "invalid param");
366         return false;
367     }
368     cJSON *arrayObj = cJSON_CreateIntArray(array, arrayLen);
369     if (arrayObj == NULL) {
370         COMM_LOGE(COMM_EVENT, "Cannot create cJSON array object. string=%{public}s", string);
371         return false;
372     }
373     if (!cJSON_AddItemToObject((cJSON *)json, string, arrayObj)) {
374         cJSON_Delete(arrayObj);
375         return false;
376     }
377     return true;
378 }
379 
GetJsonObjectIntArrayItem(const cJSON * json,const char * string,int32_t * array,int32_t arrayLen)380 bool GetJsonObjectIntArrayItem(const cJSON *json, const char *string, int32_t *array, int32_t arrayLen)
381 {
382     if (json == NULL || string == NULL || array == NULL || arrayLen <= 0) {
383         COMM_LOGE(COMM_UTILS, "invalid param");
384         return false;
385     }
386     cJSON *objValue = cJSON_GetObjectItem(json, string);
387     if (objValue == NULL) {
388         COMM_LOGE(COMM_EVENT, "Cannot create cJSON objValue. string=%{public}s", string);
389         return false;
390     }
391     if (!cJSON_IsArray(objValue)) {
392         return false;
393     }
394     int32_t size = cJSON_GetArraySize(objValue);
395     if (size > arrayLen) {
396         size = arrayLen;
397     }
398     uint32_t index = 0;
399     for (int32_t i = 0; i < size; i++) {
400         cJSON *item = cJSON_GetArrayItem(objValue, i);
401         if (item == NULL) {
402             return false;
403         }
404         if (!cJSON_IsNumber(item)) {
405             continue;
406         }
407         array[index++] = item->valueint;
408     }
409     return true;
410 }
411 
GetCjsonMaxDepth(const char * jsonStr)412 static int32_t GetCjsonMaxDepth(const char *jsonStr)
413 {
414     COMM_CHECK_AND_RETURN_RET_LOGE(jsonStr != NULL, SOFTBUS_INVALID_PARAM, COMM_UTILS, "jsonStr is nullptr");
415 
416     int32_t max = 0;
417     uint32_t len = strlen(jsonStr);
418     int32_t cnt = 0;
419     for (uint32_t i = 0; i < len; i++) {
420         if (jsonStr[i] == '{' || jsonStr[i] == '[') {
421             cnt++;
422             if (cnt > max) {
423                 max = cnt;
424             }
425         } else if (jsonStr[i] == '}' || jsonStr[i] == ']') {
426             cnt--;
427         }
428     }
429     return max;
430 }
431 
CreateJsonObjectFromString(const char * jsonStr)432 cJSON *CreateJsonObjectFromString(const char *jsonStr)
433 {
434     if (jsonStr == NULL) {
435         COMM_LOGE(COMM_UTILS, "parameter is null");
436         return NULL;
437     }
438     int32_t depth = GetCjsonMaxDepth(jsonStr);
439     if (depth > MAX_DEPTH) {
440         COMM_LOGE(COMM_UTILS, "jsonStr depth=%{public}d over 10", depth);
441         return NULL;
442     }
443     return cJSON_Parse(jsonStr);
444 }
445 
GetArrayItemNum(const cJSON * jsonObj)446 int GetArrayItemNum(const cJSON *jsonObj)
447 {
448     if (jsonObj == NULL) {
449         COMM_LOGE(COMM_UTILS, "parameter is null");
450         return 0;
451     }
452     return cJSON_GetArraySize(jsonObj);
453 }
454 
GetArrayItemFromArray(const cJSON * jsonArr,int index)455 cJSON *GetArrayItemFromArray(const cJSON *jsonArr, int index)
456 {
457     if (jsonArr == NULL) {
458         COMM_LOGE(COMM_UTILS, "parameter is null");
459         return NULL;
460     }
461     return cJSON_GetArrayItem(jsonArr, index);
462 }