Skip to content

Commit 8d1e1b9

Browse files
update parsers
1 parent 8b084a4 commit 8d1e1b9

File tree

2 files changed

+77
-12
lines changed

2 files changed

+77
-12
lines changed

code/logic/fson.c

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -228,27 +228,60 @@ fossil_media_fson_value_t *fossil_media_fson_parse(const char *json_text, fossil
228228

229229
// Handle nested object
230230
if (strcmp(base_type, "object") == 0 && *json_text == '{') {
231-
val = fossil_media_fson_parse(json_text, NULL);
232-
// Advance json_text past nested object
231+
// Find matching closing brace for nested object
233232
int brace = 1;
233+
const char *obj_start = json_text;
234234
json_text++;
235235
while (*json_text && brace > 0) {
236236
if (*json_text == '{') brace++;
237237
else if (*json_text == '}') brace--;
238238
json_text++;
239239
}
240+
size_t obj_len = json_text - obj_start;
241+
char *obj_buf = (char *)malloc(obj_len + 1);
242+
if (!obj_buf) {
243+
free(key);
244+
free(type);
245+
fossil_media_fson_free(obj);
246+
if (err_out) {
247+
err_out->code = FOSSIL_MEDIA_FSON_ERR_NOMEM;
248+
err_out->position = 0;
249+
snprintf(err_out->message, sizeof(err_out->message), "Out of memory");
250+
}
251+
return NULL;
252+
}
253+
strncpy(obj_buf, obj_start, obj_len);
254+
obj_buf[obj_len] = '\0';
255+
val = fossil_media_fson_parse(obj_buf, NULL);
256+
free(obj_buf);
240257
}
241258
// Handle nested array
242259
else if (strcmp(base_type, "array") == 0 && *json_text == '[') {
243-
val = fossil_media_fson_parse(json_text, NULL);
244-
// Advance json_text past nested array
245260
int bracket = 1;
261+
const char *arr_start = json_text;
246262
json_text++;
247263
while (*json_text && bracket > 0) {
248264
if (*json_text == '[') bracket++;
249265
else if (*json_text == ']') bracket--;
250266
json_text++;
251267
}
268+
size_t arr_len = json_text - arr_start;
269+
char *arr_buf = (char *)malloc(arr_len + 1);
270+
if (!arr_buf) {
271+
free(key);
272+
free(type);
273+
fossil_media_fson_free(obj);
274+
if (err_out) {
275+
err_out->code = FOSSIL_MEDIA_FSON_ERR_NOMEM;
276+
err_out->position = 0;
277+
snprintf(err_out->message, sizeof(err_out->message), "Out of memory");
278+
}
279+
return NULL;
280+
}
281+
strncpy(arr_buf, arr_start, arr_len);
282+
arr_buf[arr_len] = '\0';
283+
val = fossil_media_fson_parse(arr_buf, NULL);
284+
free(arr_buf);
252285
}
253286
// Handle enum
254287
else if (strcmp(base_type, "enum") == 0) {
@@ -609,29 +642,61 @@ fossil_media_fson_value_t *fossil_media_fson_parse(const char *json_text, fossil
609642
break;
610643
}
611644
if (*json_text == '{') {
612-
fossil_media_fson_value_t *item = fossil_media_fson_parse(json_text, NULL);
613-
if (item) {
614-
fossil_media_fson_array_append(arr, item);
615-
}
645+
// Find matching closing brace for nested object
616646
int brace = 1;
647+
const char *obj_start = json_text;
617648
json_text++;
618649
while (*json_text && brace > 0) {
619650
if (*json_text == '{') brace++;
620651
else if (*json_text == '}') brace--;
621652
json_text++;
622653
}
623-
} else if (*json_text == '[') {
624-
fossil_media_fson_value_t *item = fossil_media_fson_parse(json_text, NULL);
654+
size_t obj_len = json_text - obj_start;
655+
char *obj_buf = (char *)malloc(obj_len + 1);
656+
if (!obj_buf) {
657+
fossil_media_fson_free(arr);
658+
if (err_out) {
659+
err_out->code = FOSSIL_MEDIA_FSON_ERR_NOMEM;
660+
err_out->position = 0;
661+
snprintf(err_out->message, sizeof(err_out->message), "Out of memory");
662+
}
663+
return NULL;
664+
}
665+
strncpy(obj_buf, obj_start, obj_len);
666+
obj_buf[obj_len] = '\0';
667+
fossil_media_fson_value_t *item = fossil_media_fson_parse(obj_buf, NULL);
668+
free(obj_buf);
625669
if (item) {
626670
fossil_media_fson_array_append(arr, item);
627671
}
672+
} else if (*json_text == '[') {
673+
// Find matching closing bracket for nested array
628674
int bracket2 = 1;
675+
const char *arr_start = json_text;
629676
json_text++;
630677
while (*json_text && bracket2 > 0) {
631678
if (*json_text == '[') bracket2++;
632679
else if (*json_text == ']') bracket2--;
633680
json_text++;
634681
}
682+
size_t arr_len = json_text - arr_start;
683+
char *arr_buf = (char *)malloc(arr_len + 1);
684+
if (!arr_buf) {
685+
fossil_media_fson_free(arr);
686+
if (err_out) {
687+
err_out->code = FOSSIL_MEDIA_FSON_ERR_NOMEM;
688+
err_out->position = 0;
689+
snprintf(err_out->message, sizeof(err_out->message), "Out of memory");
690+
}
691+
return NULL;
692+
}
693+
strncpy(arr_buf, arr_start, arr_len);
694+
arr_buf[arr_len] = '\0';
695+
fossil_media_fson_value_t *item = fossil_media_fson_parse(arr_buf, NULL);
696+
free(arr_buf);
697+
if (item) {
698+
fossil_media_fson_array_append(arr, item);
699+
}
635700
} else {
636701
// Accept key: type: value
637702
const char *item_start = json_text;

code/logic/json.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,8 @@ static fossil_media_json_value_t *parse_value(ctx_t *c, fossil_media_json_error_
415415
if (!ch) { set_error(err,1,c->i,"Unexpected end of input"); return NULL; }
416416
if (ch == '"') return parse_string(c, err);
417417
if (ch == '-' || (ch >= '0' && ch <= '9')) return parse_number(c, err);
418-
if (ch == '{') return parse_object(c, err);
419-
if (ch == '[') return parse_array(c, err);
418+
if (ch == '{') return parse_object(c, err); // supports nested objects
419+
if (ch == '[') return parse_array(c, err); // supports nested arrays
420420
/* literals */
421421
if (ch == 't' || ch == 'f' || ch == 'n') return parse_literal(c, err);
422422
set_error(err,1,c->i,"Unexpected token '%c'", ch);

0 commit comments

Comments
 (0)