#include "cJSON.h" #include "cst_agent.h" #include #include #include /* JSON-buffer baseline: {"name":"...","arguments":{...}} is executable only * once cJSON can parse the whole object (NOT bounded CST: nothing inside an * unfinished object is ever confirmed). */ int cst_json_try_parse_tool(const char *buf, size_t len, cst_json_tool_t *out) { if (!buf || !out) return 0; memset(out, 0, sizeof(*out)); const char *p = buf, *end = buf + len; while (p < end) { if (*p != '{') { p++; continue; } const char *obj_end = NULL; cJSON *o = cJSON_ParseWithLengthOpts(p, (size_t)(end - p), &obj_end, 0); if (!o) return 0; /* incomplete/invalid: the starvation failure mode */ const cJSON *name = cJSON_GetObjectItemCaseSensitive(o, "name"); const cJSON *args = cJSON_GetObjectItemCaseSensitive(o, "arguments"); int ok = 0; if (cJSON_IsString(name) && args && strlen(name->valuestring) < sizeof(out->name)) { char *a = cJSON_IsString(args) ? NULL : cJSON_PrintUnformatted(args); const char *av = a ? a : (cJSON_IsString(args) ? args->valuestring : ""); if (strlen(av) < sizeof(out->arguments_json)) { snprintf(out->name, sizeof(out->name), "%s", name->valuestring); snprintf(out->arguments_json, sizeof(out->arguments_json), "%s", av); out->ok = ok = 1; } free(a); } cJSON_Delete(o); if (ok) return 1; p = obj_end && obj_end > p ? obj_end : p + 1; } return 0; }