提问人:couscous 提问时间:11/11/2023 最后编辑:couscous 更新时间:11/11/2023 访问量:37
在替换嵌套值时避免 cJSON 解析无限循环中的核心转储
Avoiding core dump in cJSON parse endless loop while replacing nested values
问:
我有一个 cJSON 树,我在其中保存了我在 while 循环中生成的余弦的 x 和 y 值。
它看起来像这样:
"myXY": [{
"x": 2.0110001564025879,
"y": 0.99761265516281128
}]
myXY 是一个数组,我将其添加到 cJSON:“myJSON”,如下所示:
cJSON *myXY = NULL;
myXY = cJSON_AddArrayToObject(myJSON, "myXY");
然后,我通过创建一个对象“myNestedArray”并将其添加到“myXY”来添加值:
cJSON_AddNumberToObject(myNestedArray, "x", pOutput->x);
cJSON_AddNumberToObject(myNestedArray, "y", pOutput->y);
cJSON_AddItemToArray(myXY, myNestedArray);
(pOutput 是我传递给我的“parse_output_to_json”函数的结构。
最后,我将带有 stdout 的“cJSON-string”管道传输到我的第二个程序“receiver.c”。
char *string = cJSON_Print(myJSON);
write(1, string, strlen(string));
到目前为止,一切正常。
现在我想用sinf("x" /*the "x" value in "myXY"*/)
事实证明,这比我想象的要复杂得多:
int main() {
/* variables*/
char buffer[50];
char *string = NULL;
/* master-loop*/
while (1) {
/* cJSON variables*/
cJSON *myNewJSON = NULL;
cJSON *myNewXY = NULL;
cJSON *xValJSON = NULL;
/* parsing the pipe*/
read(0, buffer, 50);
myNewJSON = cJSON_Parse(buffer);
/* adjusting setter parameters*/
myNewXY = cJSON_GetObjectItem(myNewJSON, "myXY");
xValJSON = cJSON_GetArrayItem(myNewXY, 0);
/* setting the new (sin) value*/
cJSON_SetNumberValue(myNewXY, sinf(cJSON_GetNumberValue(xValJSON)));
/* printing the new values*/
string = cJSON_Print(myNewJSON);
write(1, string, strlen(string));
/*avoiding stack overflow?*/
free(string);
cJSON_Delete(myNewJSON);
}
return 0;
}
到目前为止,我的代码编译,打印出第一个值(cos(0)),然后给我一个核心哑巴并停止。喜欢这个:
./cos_generator | ./receiver
{
"myXY": [{
"x": 0,
"y": 1
}]
}Speicherzugriffsfehler (Speicherabzug geschrieben)
编辑:我的 cos_generator.c 代码是:
/* includes*/
#include "cJSON.c"
#include <math.h>
#include <unistd.h>
#define MY_PI 3.141592
/* OutputData struct*/
struct OutputData {
float x;
float y;
};
/*parser-function*/
void parse_output_to_json(cJSON *pJson, struct OutputData *pOutput);
/*main function*/
int main() {
cJSON *myJSON = cJSON_CreateObject(); /* Object is named 'myJSON'*/
/* generator loop*/
while (1) {
static int counter = 0;
float t_s = counter * 0.001f;
float f = 1;
struct OutputData current = {
.x = t_s,
.y = cosf(2 * MY_PI * f * t_s),
};
parse_output_to_json(myJSON, ¤t);
char *string = cJSON_Print(myJSON);
write(1, string, strlen(string));
cJSON_free(string);
usleep(1000);
counter++;
}
cJSON_Delete(myJSON);
/* Return val of main*/
return 0;
}
void parse_output_to_json(cJSON *pJson, struct OutputData *pOutput) {
/* Variables*/
char *string = NULL; /* string to be written to*/
cJSON *myXY = NULL; // cJSON array
size_t index = 0;
/* Add Array 'myXY' to the myJSON*/
myXY = cJSON_AddArrayToObject(pJson, "myXY");
/* Add mySinXY to myNestedArray*/
/* make array object inside the master object??*/
cJSON *myNestedArray = cJSON_CreateObject();
/* add numbers of mySinXY*/
cJSON_AddNumberToObject(myNestedArray, "x", pOutput->x);
cJSON_AddNumberToObject(myNestedArray, "y", pOutput->y);
/* Add item 'myNestedArray' to myXY in myJSON*/
cJSON_AddItemToArray(myXY, myNestedArray);
}
答:
0赞
couscous
11/23/2023
#1
我的代码有多个问题,例如缓冲区长度太短。 在修复所有语法和“愚蠢”错误的同时,仍然存在一个问题:
- 它无法正确解析
与我的同事一起工作了一个小时,得到了以下启示:
即使嵌套的 Array 只包含一个元素,例如“x”只包含整数“1”,你也必须遍历“x”。 我没有找到一种方法来访问“x”。
这完全是从 cJSON 页面上的示例中接管的。
我将解析放入结构中,这应该适用于许多类似的用例:
struct OutputData {
float x;
float y;
};
struct OutputData parseStruct(cJSON *json) {
cJSON *myNewXY = NULL;
cJSON *xValJSON = NULL;
cJSON *yValJSON = NULL;
cJSON *resolution = NULL;
/* adjusting setter parameters*/
myNewXY = cJSON_GetObjectItemCaseSensitive(json, "myXY");
cJSON_ArrayForEach(resolution, myNewXY) {
xValJSON = cJSON_GetObjectItemCaseSensitive(resolution, "x");
yValJSON = cJSON_GetObjectItemCaseSensitive(resolution, "y");
}
struct OutputData result = {
.x = (float)cJSON_GetNumberValue(xValJSON),
.y = (float)cJSON_GetNumberValue(yValJSON),
};
return result;
}
评论
cJSON_Parse()
需要一个正常的以 0 结尾的 C 字符串。你没有给它一个。cJSON_ParseWithLength(string, buffer_length);
cJSON
cJSON_Delete