Skip to content

Commit

Permalink
Merge pull request armink#20 from yuxuebao/master
Browse files Browse the repository at this point in the history
fix bugs: json array is larger than struct, check size to avoid overw…
  • Loading branch information
armink authored Feb 25, 2021
2 parents 7ba00c0 + 08b07da commit 9cdc3a3
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 142 deletions.
21 changes: 18 additions & 3 deletions cJSON/cJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -3036,13 +3036,28 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)

CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
{
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
int type = a->type & 0xFF;

if ((a == NULL) || (b == NULL) || cJSON_IsInvalid(a))
{
return false;
}

if ((a->type & 0xFF) != (b->type & 0xFF))
{
if (((a->type & 0xFF) == cJSON_Int && (b->type & 0xFF) == cJSON_Number) ||
((b->type & 0xFF) == cJSON_Int && (a->type & 0xFF) == cJSON_Number))
{
type = cJSON_Number;
}
else
{
return false;
}
}

/* check if type is valid */
switch (a->type & 0xFF)
switch (type)
{
case cJSON_Bool:
case cJSON_Int:
Expand All @@ -3064,7 +3079,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
return true;
}

switch (a->type & 0xFF)
switch (type)
{
/* in these cases and equal type is enough */
case cJSON_NULL:
Expand Down
86 changes: 69 additions & 17 deletions demo/generate_s2j_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@
struct_str += ' '.join(line.split())
struct_str = re.sub(r'((?<=\n)|^)[\t]*\/\*.*?\*\/\n?|\/\*.*?\*\/|((?<=\n)|^)[\t]*\/\/[^\n]*\n|\/\/[^\n]*', '',struct_str)

head_str = r"""
#include "inc/mc_usr_def.h"
#include "my_struct_2_json.inc"
#include "my_struct_2_json.h"
#ifdef __cplusplus
extern "C" {
#endif
"""

return_code = ""
#使用typedef进行元素分割,并去除列表中空元素
struct_str_split_list = [x for x in struct_str.split("typedef") if x!=""]
Expand Down Expand Up @@ -205,11 +194,17 @@
file.write(content.strip())
file.close()

head_str = r"""
#include "inc/mc_usr_def.h"
#include "my_struct_2_json.inc"
#include "my_struct_2_json.h"
#ifdef __cplusplus
extern "C" {
#endif
"""

str_return = ""
for i in range(len(struct_name_return.split())):
str_return = str_return + " TEST_S2J_STRUCT(" + struct_name_return.split()[i] + ", 0 , fp);\n"
#print(str_return)
void_main_header = r"""
char file_name[] = "struct_defination.json";
FILE *fp;
Expand All @@ -219,20 +214,77 @@
fprintf(fp,"{\n\t\"struct\": [\n\t\t{\n\t\t\t\"type\": \"void*\",\n\t\t\t\"value\": null\n\t\t}");
"""
void_main_tail = r"""

str_return = ""
str_s2j_test = ""
for i in range(len(struct_name_return.split())):
str_s2j_test = str_s2j_test + " TEST_S2J_STRUCT(" + struct_name_return.split()[i] + ", 0 , fp);\n"
#print(str_s2j_test)

str_s2j_test_tail = r"""
fprintf(fp,"\n\t]\n}");
fclose(fp);
return 0;
}
"""

str_s2j_test2_header = r"""
int s2j_test2(void)
{
char file_name[] = "struct_defination.json";
FILE *fp;
fp = fopen(file_name, "rb");
if (NULL == fp) return 1;
fseek(fp,0L,SEEK_END);
int flen=ftell(fp);
char* p=(char *)malloc(flen+1);
if(p==NULL)
{
fclose(fp);
return 0;
}
fseek(fp,0L,SEEK_SET);
fread(p,flen,1,fp);
p[flen]=0;
printf("\nstruct_defination.json:\n%s\n",p);
cJSON *json_obj =cJSON_Parse(p);
CHECK_NOT_NULL(json_obj)
cJSON *json_struct = cJSON_GetObjectItem(json_obj, "struct");
CHECK_NOT_NULL(json_struct)
int array_size = cJSON_GetArraySize(json_struct);
printf("\nsize:\n%d\n",array_size);
int i = 0; \
"""

str_s2j_test2 = ""
for i in range(len(struct_name_return.split())):
str_s2j_test2 = str_s2j_test2 + " TEST_S2J_JSON(" + struct_name_return.split()[i] + ", array_size);\n"
#print(str_s2j_test2)


void_main_tail = r"""
fclose(fp);
free(p);
return 0;
}
#endif// DEBUGS2J
#ifdef __cplusplus
}
#endif /* end of __cplusplus */
"""
str_return = head_str + return_code + "#ifdef DEBUGS2J \n int s2j_test(void)\n" +" {\n\t" + void_main_header + str_return + void_main_tail
str_return = head_str + return_code + "#ifdef DEBUGS2J \n int s2j_test(void)\n" +" {\n\t" + void_main_header + str_s2j_test + str_s2j_test_tail + str_s2j_test2_header + str_s2j_test2 + void_main_tail
#print(str_return)

error_return = error_print_json2bin + "\n" + "*************************************" + "\n" + error_print_bin2json
Expand Down
2 changes: 2 additions & 0 deletions demo/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#ifdef DEBUGS2J
extern int s2j_test(void);
extern int s2j_test2(void);
#endif// DEBUGS2J

typedef struct {
Expand Down Expand Up @@ -130,6 +131,7 @@ int main(void) {

#ifdef DEBUGS2J
s2j_test();
s2j_test2();
#endif// DEBUGS2J

return 0;
Expand Down
52 changes: 48 additions & 4 deletions demo/my_struct_2_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,61 @@ void *json_to_struct_McOcoBaseOrdrT(cJSON* json_obj)
if (NULL == fp) return 1;
fprintf(fp,"{\n\t\"struct\": [\n\t\t{\n\t\t\t\"type\": \"void*\",\n\t\t\t\"value\": null\n\t\t}");

TEST_S2J_STRUCT(McUsrInfoT, 66 , fp);
TEST_S2J_STRUCT(McBaseOrdrT, 66 , fp);
TEST_S2J_STRUCT(McBaseOrdrArrayT, 66 , fp);
TEST_S2J_STRUCT(McOcoBaseOrdrT, 66 , fp);
TEST_S2J_STRUCT(McUsrInfoT, 0 , fp);
TEST_S2J_STRUCT(McBaseOrdrT, 0 , fp);
TEST_S2J_STRUCT(McBaseOrdrArrayT, 0 , fp);
TEST_S2J_STRUCT(McOcoBaseOrdrT, 0 , fp);

fprintf(fp,"\n\t]\n}");
fclose(fp);
return 0;
}



int s2j_test2(void)
{

char file_name[] = "struct_defination.json";
FILE *fp;

fp = fopen(file_name, "rb");
if (NULL == fp) return 1;

fseek(fp,0L,SEEK_END);
int flen=ftell(fp);
char* p=(char *)malloc(flen+1);
if(p==NULL)
{
fclose(fp);
return 0;
}
fseek(fp,0L,SEEK_SET);
fread(p,flen,1,fp);
p[flen]=0;

printf("\nstruct_defination.json:\n%s\n",p);

cJSON *json_obj =cJSON_Parse(p);
CHECK_NOT_NULL(json_obj)
cJSON *json_struct = cJSON_GetObjectItem(json_obj, "struct");
CHECK_NOT_NULL(json_struct)

int array_size = cJSON_GetArraySize(json_struct);
printf("\nsize:\n%d\n",array_size);
int i = 0; \

TEST_S2J_JSON(McUsrInfoT, array_size);
TEST_S2J_JSON(McBaseOrdrT, array_size);
TEST_S2J_JSON(McBaseOrdrArrayT, array_size);
TEST_S2J_JSON(McOcoBaseOrdrT, array_size);

fclose(fp);
free(p);
return 0;
}


#endif// DEBUGS2J

#ifdef __cplusplus
Expand Down
42 changes: 39 additions & 3 deletions demo/my_struct_2_json.inc
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,58 @@ do\
char* str_json##type = cJSON_Print(json_obj##type); \
printf("s2j:\n%s: %s\n",#type, str_json##type); \
fprintf(file,",\n\t\t{\n\t\t\t\"type\": \"%s\",\n\t\t\t\"value\": %s\n\t\t}", #type, str_json##type); \
type *p_struct_obj##type =(type *)json_to_struct_##type(json_obj##type); \
cJSON *json_obj1##type =cJSON_Parse(str_json##type); \
cJSON_bool json_cmp1##type = cJSON_Compare(json_obj ##type, json_obj1##type, 1); \
printf("%s:json_cmp1:%d\n\n\n",#type, json_cmp1##type); \
type *p_struct_obj##type =(type *)json_to_struct_##type(json_obj1##type); \
int cmp##type = memcmp(p_struct_obj##type, &struct_obj##type, sizeof(type)); \
printf("\n"); \
cJSON *json_obj2##type = struct_to_json_##type(p_struct_obj##type); \
char* str_json2##type = cJSON_Print(json_obj2##type); \
printf("s2j2s2j:\n%s: %s\n",#type, str_json2##type); \
int str_cmp##type = strcmp(str_json##type, str_json2##type); \
printf("\n%s:strcmp:%d\n",#type, str_cmp##type); \
cJSON_bool json_cmp##type = cJSON_Compare(json_obj##type, json_obj2##type, 1); \
printf("%s:json_cmp:%d\n\n\n",#type, json_cmp##type); \
cJSON_bool json_cmp2##type = cJSON_Compare(json_obj##type, json_obj2##type, 1); \
printf("%s:json_cmp2:%d\n\n\n",#type, json_cmp2##type); \
free(str_json##type); \
free(str_json2##type); \
s2j_delete_struct_obj(p_struct_obj##type); \
s2j_delete_json_obj(json_obj##type); \
s2j_delete_json_obj(json_obj1##type); \
s2j_delete_json_obj(json_obj2##type); \


#define TEST_S2J_JSON(type, size) \
cJSON *json_struct_##type = NULL; \
i = 0; \
for (; i < size;i++) { \
cJSON *json_struct_item = cJSON_GetArrayItem(json_struct, i); \
cJSON *json_struct_item_type = cJSON_GetObjectItem(json_struct_item, "type"); \
char* str_type = json_struct_item_type->valuestring; \
if (0 == strcmp(#type, str_type)) { \
json_struct_##type = cJSON_GetObjectItem(json_struct_item, "value"); \
printf("\ntype:%s:\n",#type); \
break; \
} \
} \
if (json_struct_##type != NULL) { \
cJSON * json_obj1##type = json_struct_##type; \
char* str_json1##type = cJSON_Print(json_obj1##type); \
printf("\nj2str:\n%s: %s\n",#type, str_json1##type); \
type *p_struct_obj##type =(type *)json_to_struct_##type(json_obj1##type); \
cJSON *json_obj2##type = struct_to_json_##type(p_struct_obj##type); \
char* str_json2##type = cJSON_Print(json_obj2##type); \
printf("\nj2s2j:\n%s: %s\n",#type, str_json2##type); \
int str_cmp##type = strcmp(str_json1##type, str_json2##type); \
printf("\n%s:strcmp:%d\n",#type, str_cmp##type); \
cJSON_bool json_cmp##type = cJSON_Compare(json_obj1##type, json_obj2##type, 1); \
printf("%s:json_cmp:%d\n\n\n",#type, json_cmp##type); \
free(str_json1##type); \
free(str_json2##type); \
s2j_delete_struct_obj(p_struct_obj##type); \
s2j_delete_json_obj(json_obj1##type); \
s2j_delete_json_obj(json_obj2##type); \
}

#endif// DEBUGS2J

Loading

0 comments on commit 9cdc3a3

Please sign in to comment.