From 27e42e9010acfe11bbf2176116846f3d7d7eab0b Mon Sep 17 00:00:00 2001 From: yukkop Date: Sat, 22 Mar 2025 03:18:34 +0000 Subject: [PATCH] fix: segfalt in json_get_object_item --- package/c/chectic/chectic.c | 9 +++++++ package/c/chectic/chectic.h | 1 + package/c/hmpl/default.nix | 8 +++---- package/c/hmpl/hmpl.c | 47 ++++++++++--------------------------- package/c/hmpl/hmpl.h | 9 ++++--- package/c/hmpl/main.c | 7 +----- 6 files changed, 32 insertions(+), 49 deletions(-) diff --git a/package/c/chectic/chectic.c b/package/c/chectic/chectic.c index dd6c064..e893416 100644 --- a/package/c/chectic/chectic.c +++ b/package/c/chectic/chectic.c @@ -311,13 +311,22 @@ char *json_print(Arena *arena, Json *item) { /* Retrieve an object item by key (case-sensitive) */ Json *json_get_object_item(Json *object, const char *key) { + raise_debug("json get object item for %s", key); if (!object || object->type != JSON_OBJECT) return NULL; Json *child = object->child; while (child) { + raise_debug("child->key: %s, key: %s", child->key, key); if (child->key && strcmp(child->key, key) == 0) return child; child = child->next; } return NULL; } + +//bool json_is_string(const Json * const item) { +// if (item == NULL) { +// return false; +// } +// return item->type == JSON_STRING; +//} diff --git a/package/c/chectic/chectic.h b/package/c/chectic/chectic.h index 4e31278..dbf1f89 100644 --- a/package/c/chectic/chectic.h +++ b/package/c/chectic/chectic.h @@ -8,6 +8,7 @@ #include #include #include +#include // ------------- // -- Helpers -- diff --git a/package/c/hmpl/default.nix b/package/c/hmpl/default.nix index 46272c4..e084aeb 100644 --- a/package/c/hmpl/default.nix +++ b/package/c/hmpl/default.nix @@ -1,4 +1,4 @@ -{ stdenv, gcc, lib, chectic, cjson }: +{ stdenv, gcc, lib, chectic }: stdenv.mkDerivation { pname = "hmpl"; @@ -6,7 +6,7 @@ stdenv.mkDerivation { src = ./.; doCheck = true; - buildInputs = [ chectic cjson ]; + buildInputs = [ chectic ]; buildPhase = '' mkdir -p target @@ -15,7 +15,7 @@ stdenv.mkDerivation { ${gcc}/bin/cc -Wall -Wextra -g \ -std=c99 \ -pedantic -fsanitize=address -c hmpl.c \ - -lchectic -lcjson \ + -lchectic \ -o target/hmpl.o ${gcc}/bin/ar rcs target/libhmpl.a target/hmpl.o @@ -23,7 +23,7 @@ stdenv.mkDerivation { ${gcc}/bin/cc -Wall -Wextra -g \ -pedantic -fsanitize=address main.c \ -Ltarget -lhmpl \ - -lchectic -lcjson -o target/hmpl + -lchectic -o target/hmpl ''; checkPhase = '' ''; diff --git a/package/c/hmpl/hmpl.c b/package/c/hmpl/hmpl.c index 5d6b0fa..2b12b04 100644 --- a/package/c/hmpl/hmpl.c +++ b/package/c/hmpl/hmpl.c @@ -1,52 +1,31 @@ #include "hmpl.h" -Arena *cJSON_global_arena; -size_t last_size = 0; // tracked externally, unsafe but works for simple use - -void *arena_malloc(size_t size) { - void *ptr = arena_alloc(cJSON_global_arena, size); - last_size = size; - return ptr; -} - -void arena_free_stub(void *ptr) { - raise_debug("WARN: cJSON tried to free %p — ignored", ptr); -} - -void init_cjson_with_arenas(Arena *arena) { - cJSON_global_arena = arena; - cJSON_InitHooks(&(cJSON_Hooks){ - .malloc_fn = arena_malloc, - .free_fn = arena_free_stub, - }); -} - -char *eval(Arena *arena, const cJSON * const context, const char * const key) { +char *eval(Arena *arena, const Json * const context, const char * const key) { if (!context || !key) return NULL; char *key_copy = arena_strdup(arena, key); char *token, *rest = key_copy; - cJSON *res = context; + Json *res = context; while ((token = strtok_r(rest, ".", &rest))) { - raise_debug("context: %s; token: %s", cJSON_Print(res), key); - res = cJSON_GetObjectItemCaseSensitive(res, token); + raise_debug("context: %s; token: %s", json_print(arena, res), key); + res = json_get_object_item(res, &token); if (!res) return NULL; } - if (cJSON_IsString(res) && res->valuestring) - return arena_strdup(arena, res->valuestring); - else if (cJSON_IsNumber(res)) { + if (res == JSON_STRING && res->string) + return arena_strdup(arena, res->string); + else if (res == JSON_NUMBER) { char buf[64]; - snprintf(buf, sizeof(buf), "%g", res->valuedouble); + snprintf(buf, sizeof(buf), "%g", res->number); return arena_strdup(arena, buf); } - char *temp = cJSON_PrintUnformatted(res); + char *temp = json_print(arena, res); char *result = arena_strdup(arena, temp); free(temp); return result; } /* Modified: text is passed by reference so we can update it and free old allocations */ -void render_template_placeholders(Arena *arena, char **text_ptr, cJSON *context, const char * const prefix) { +void render_template_placeholders(Arena *arena, char **text_ptr, Json *context, const char * const prefix) { raise_debug("render_template_placeholders"); char start_pattern[256]; snprintf(start_pattern, sizeof(start_pattern), "{{%s", prefix); @@ -86,8 +65,8 @@ void render_template_placeholders(Arena *arena, char **text_ptr, cJSON *context, } } -void render_template_with_arena(Arena *arena, char **text, const cJSON * const context) { - if (!cJSON_IsObject(context)) { +void render_template_with_arena(Arena *arena, char **text, const Json * const context) { + if (context->type != JSON_OBJECT) { raise_exception("Malformed context: context is not json"); exit(1); } @@ -95,7 +74,7 @@ void render_template_with_arena(Arena *arena, char **text, const cJSON * const c render_template_placeholders(arena, text, context, ""); } -void render_template(char **text, const cJSON * const context) { +void render_template(char **text, const Json * const context) { Arena arena = arena_init(1024 * 1024); render_template_with_arena(&arena, text, context); diff --git a/package/c/hmpl/hmpl.h b/package/c/hmpl/hmpl.h index 704ae1d..db83090 100644 --- a/package/c/hmpl/hmpl.h +++ b/package/c/hmpl/hmpl.h @@ -6,17 +6,16 @@ #include #include #include "chectic.h" -#include "cjson/cJSON.h" void init_cjson_with_arenas(Arena *arena); -char *eval(Arena *arena, const cJSON * const context, const char * const key); +char *eval(Arena *arena, const Json * const context, const char * const key); /* Modified: text is passed by reference so we can update it and free old allocations */ -void render_template_placeholders(Arena *arena, char **text_ptr, cJSON *context, const char * const prefix); +void render_template_placeholders(Arena *arena, char **text_ptr, Json *context, const char * const prefix); -void render_template_with_arena(Arena *arena, char **text, const cJSON * const ccontext); +void render_template_with_arena(Arena *arena, char **text, const Json * const ccontext); -void render_template(char **text, const cJSON * const context); +void render_template(char **text, const Json * const context); #endif // EPRINTF_HMPL diff --git a/package/c/hmpl/main.c b/package/c/hmpl/main.c index d95b289..a3a7867 100644 --- a/package/c/hmpl/main.c +++ b/package/c/hmpl/main.c @@ -3,7 +3,6 @@ #include #include #include "chectic.h" -#include "cjson/cJSON.h" #include "hmpl.h" int main(int argc, char *argv[]) { @@ -11,14 +10,12 @@ int main(int argc, char *argv[]) { raise_info("start"); Arena arena = arena_init(1024 * 1024); - Arena arena_for_jsons = arena_init(1024 * 1024); - init_cjson_with_arenas(&arena_for_jsons); raise_info("read the arguments"); char *text = NULL; const char *json_input = (argc > 1 ? argv[1] : "{}"); - cJSON *context = cJSON_Parse(json_input); + Json *context = json_parse(&arena, &json_input); if (!context) { fprintf(stderr, "Error parsing JSON\n"); @@ -33,7 +30,6 @@ int main(int argc, char *argv[]) { ssize_t len = getdelim(&heap_text, &size, '\0', stdin); if (len < 0) { perror("read stdin"); - cJSON_Delete(context); return 1; } text = arena_strdup(&arena, heap_text); @@ -46,6 +42,5 @@ int main(int argc, char *argv[]) { printf("%s", text); arena_free(&arena); - cJSON_Delete(context); return 0; }