Greenbone Vulnerability Management Libraries 22.12.2
jsonpull.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
6#include "jsonpull.h"
7
8#include <assert.h>
9
10#define GVM_JSON_CHAR_EOF -1
11#define GVM_JSON_CHAR_ERROR -2
12#define GVM_JSON_CHAR_UNDEFINED -3
13
22gchar *
23gvm_json_string_escape (const char *string, gboolean single_quote)
24{
25 gchar *point;
26 if (string == NULL)
27 return NULL;
28
29 GString *escaped = g_string_sized_new (strlen (string));
30 for (point = (char *) string; *point != 0; point++)
31 {
32 unsigned char character = *point;
33
34 if ((character > 31) && (character != '\\')
35 && (single_quote ? (character != '\'') : (character != '\"')))
36 {
37 g_string_append_c (escaped, character);
38 }
39 else
40 {
41 g_string_append_c (escaped, '\\');
42 switch (*point)
43 {
44 case '\\':
45 case '\'':
46 case '\"':
47 g_string_append_c (escaped, *point);
48 break;
49 case '\b':
50 g_string_append_c (escaped, 'b');
51 break;
52 case '\f':
53 g_string_append_c (escaped, 'f');
54 break;
55 case '\n':
56 g_string_append_c (escaped, 'n');
57 break;
58 case '\r':
59 g_string_append_c (escaped, 'r');
60 break;
61 case '\t':
62 g_string_append_c (escaped, 't');
63 break;
64 default:
65 g_string_append_printf (escaped, "u%04x", character);
66 }
67 }
68 }
69 return g_string_free (escaped, FALSE);
70}
71
82 int depth)
83{
84 gvm_json_path_elem_t *new_elem = g_malloc0 (sizeof (gvm_json_path_elem_t));
85 new_elem->parent_type = parent_type;
86 new_elem->depth = depth;
87 return new_elem;
88}
89
95void
97{
98 g_free (elem->key);
99 g_free (elem);
100}
101
107void
109{
110 memset (event, 0, sizeof (gvm_json_pull_event_t));
111}
112
118void
120{
121 cJSON_free (event->value);
122 if (event->error_message)
123 g_free (event->error_message);
124 memset (event, 0, sizeof (gvm_json_pull_event_t));
125}
126
132void
134{
135 cJSON_free (event->value);
136 if (event->error_message)
137 g_free (event->error_message);
138 memset (event, 0, sizeof (gvm_json_pull_event_t));
139}
140
149void
151 FILE *input_stream, size_t parse_buffer_limit,
152 size_t read_buffer_size)
153{
154 assert (parser);
155 assert (input_stream);
156 memset (parser, 0, sizeof (gvm_json_pull_parser_t));
157
158 if (parse_buffer_limit <= 0)
159 parse_buffer_limit = GVM_JSON_PULL_PARSE_BUFFER_LIMIT;
160
161 if (read_buffer_size <= 0)
162 read_buffer_size = GVM_JSON_PULL_READ_BUFFER_SIZE;
163
164 parser->input_stream = input_stream;
165 parser->path = g_queue_new ();
167 parser->parse_buffer_limit = parse_buffer_limit;
168 parser->parse_buffer = g_string_new ("");
169 parser->read_buffer_size = read_buffer_size;
170 parser->read_buffer = g_malloc0 (read_buffer_size);
172}
173
180void
182{
183 gvm_json_pull_parser_init_full (parser, input_stream, 0, 0);
184}
185
191void
193{
194 assert (parser);
195 g_queue_free_full (parser->path,
196 (GDestroyNotify) gvm_json_pull_path_elem_free);
197 g_string_free (parser->parse_buffer, TRUE);
198 g_free (parser->read_buffer);
199 memset (parser, 0, sizeof (gvm_json_pull_parser_t));
200}
201
207static gchar *
209{
210 return g_strdup_printf ("error reading JSON stream: %s", strerror (errno));
211}
212
222static int
226{
227 if (parser->parse_buffer->len >= parser->parse_buffer_limit)
228 {
229 event->error_message =
230 g_strdup_printf ("%s exceeds size limit of %zu bytes", value_type,
231 parser->parse_buffer_limit);
232 event->type = GVM_JSON_PULL_EVENT_ERROR;
233 return 1;
234 }
235 return 0;
236}
237
245static int
247{
248 parser->read_pos++;
249 if (parser->read_pos < parser->last_read_size)
250 {
251 parser->last_read_char =
252 (unsigned char) parser->read_buffer[parser->read_pos];
253 return parser->last_read_char;
254 }
255 else
256 {
257 parser->read_pos = 0;
258 parser->last_read_size = fread (
259 parser->read_buffer, 1, parser->read_buffer_size, parser->input_stream);
260 if (ferror (parser->input_stream))
262 else if (parser->last_read_size <= 0)
264 else
265 parser->last_read_char =
266 (unsigned char) parser->read_buffer[parser->read_pos];
267 return parser->last_read_char;
268 }
269}
270
282static int
285 const char *value_name,
286 cJSON_bool (*validate_func) (const cJSON *const),
287 cJSON **cjson_value)
288{
289 cJSON *parsed_value = cJSON_Parse (parser->parse_buffer->str);
290 *cjson_value = NULL;
291 if (validate_func (parsed_value) == 0)
292 {
293 event->type = GVM_JSON_PULL_EVENT_ERROR;
294 event->error_message = g_strdup_printf ("error parsing %s", value_name);
295 cJSON_free (parsed_value);
296 return 1;
297 }
298 *cjson_value = parsed_value;
299 return 0;
300}
301
309static void
311 gvm_json_pull_event_t *event, gboolean allow_eof)
312{
313 if (parser->last_read_char == GVM_JSON_CHAR_ERROR)
314 {
315 event->error_message = gvm_json_read_stream_error_str ();
316 event->type = GVM_JSON_PULL_EVENT_ERROR;
317 }
318 else if (allow_eof)
319 event->type = GVM_JSON_PULL_EVENT_EOF;
320 else
321 {
322 event->error_message = g_strdup ("unexpected EOF");
323 event->type = GVM_JSON_PULL_EVENT_ERROR;
324 }
325}
326
338static int
340 gvm_json_pull_event_t *event, gboolean allow_eof)
341{
342 while (g_ascii_isspace (parser->last_read_char))
344 if (parser->last_read_char < 0)
345 {
346 gvm_json_pull_handle_read_end (parser, event, allow_eof);
347 return 1;
348 }
349 return 0;
350}
351
364static int
366 gvm_json_pull_event_t *event, cJSON **cjson_value)
367{
368 gboolean escape_next_char = FALSE;
369 g_string_truncate (parser->parse_buffer, 0);
370 g_string_append_c (parser->parse_buffer, '"');
371 while (gvm_json_pull_parser_next_char (parser) >= 0)
372 {
373 if (gvm_json_pull_check_parse_buffer_size ("string", parser, event))
374 return 1;
375 g_string_append_c (parser->parse_buffer, parser->last_read_char);
376 if (escape_next_char)
377 escape_next_char = FALSE;
378 else if (parser->last_read_char == '\\')
379 escape_next_char = TRUE;
380 else if (parser->last_read_char == '"')
381 break;
382 }
383
384 if (parser->last_read_char < 0)
385 {
386 gvm_json_pull_handle_read_end (parser, event, FALSE);
387 return 1;
388 }
389
391
392 return gvm_json_pull_parse_buffered (parser, event, "string", cJSON_IsString,
393 cjson_value);
394}
395
408static int
410 gvm_json_pull_event_t *event, cJSON **cjson_value)
411{
412 g_string_truncate (parser->parse_buffer, 0);
413 g_string_append_c (parser->parse_buffer, parser->last_read_char);
414 while (gvm_json_pull_parser_next_char (parser) >= 0)
415 {
416 if (gvm_json_pull_check_parse_buffer_size ("number", parser, event))
417 return 1;
418 if (g_ascii_isdigit (parser->last_read_char)
419 || parser->last_read_char == '.' || parser->last_read_char == 'e'
420 || parser->last_read_char == '-' || parser->last_read_char == '+')
421 g_string_append_c (parser->parse_buffer, parser->last_read_char);
422 else
423 break;
424 }
425
426 if (parser->last_read_char == GVM_JSON_CHAR_ERROR)
427 {
428 event->error_message = gvm_json_read_stream_error_str ();
429 event->type = GVM_JSON_PULL_EVENT_ERROR;
430 return 1;
431 }
432
433 return gvm_json_pull_parse_buffered (parser, event, "number", cJSON_IsNumber,
434 cjson_value);
435}
436
449static int
451 gvm_json_pull_event_t *event, const char *keyword)
452{
453 for (size_t i = 0; i < strlen (keyword); i++)
454 {
455 if (parser->last_read_char < 0)
456 {
457 gvm_json_pull_handle_read_end (parser, event, FALSE);
458 return 1;
459 }
460 else if (parser->last_read_char != keyword[i])
461 {
462 event->type = GVM_JSON_PULL_EVENT_ERROR;
463 event->error_message =
464 g_strdup_printf ("misspelled keyword '%s'", keyword);
465 return 1;
466 }
468 }
469 return 0;
470}
471
477static void
479{
480 if (parser->path->length)
482 else
484}
485
497static int
500{
501 if (gvm_json_pull_skip_space (parser, event, FALSE))
502 return 1;
503
504 cJSON *key_cjson = NULL;
505 gchar *key_str;
506 gvm_json_path_elem_t *path_elem;
507
508 switch (parser->last_read_char)
509 {
510 case '"':
511 if (gvm_json_pull_parse_string (parser, event, &key_cjson))
512 return 1;
513 key_str = g_strdup (key_cjson->valuestring);
514 cJSON_free (key_cjson);
515
516 // Expect colon:
517 if (gvm_json_pull_skip_space (parser, event, FALSE))
518 {
519 g_free (key_str);
520 return 1;
521 }
522 if (parser->last_read_char != ':')
523 {
524 event->type = GVM_JSON_PULL_EVENT_ERROR;
525 event->error_message = g_strdup_printf ("expected colon");
526 g_free (key_str);
527 return 1;
528 }
530
531 path_elem = g_queue_peek_tail (parser->path);
532 g_free (path_elem->key);
533 path_elem->key = key_str;
535
536 break;
537 case '}':
538 event->type = GVM_JSON_PULL_EVENT_OBJECT_END;
539 event->value = NULL;
540 gvm_json_pull_path_elem_free (g_queue_pop_tail (parser->path));
543 break;
544 case ']':
545 event->type = GVM_JSON_PULL_EVENT_ERROR;
546 event->error_message = g_strdup ("unexpected closing square bracket");
547 return 1;
548 default:
549 event->type = GVM_JSON_PULL_EVENT_ERROR;
550 event->error_message = g_strdup ("unexpected character");
551 return 1;
552 }
553
554 return 0;
555}
556
568static int
571{
572 if (gvm_json_pull_skip_space (parser, event, FALSE))
573 return 1;
574
575 gvm_json_path_elem_t *path_elem = NULL;
576 switch (parser->last_read_char)
577 {
578 case ',':
579 path_elem = g_queue_peek_tail (parser->path);
580 path_elem->index++;
583 else
586 break;
587 case ']':
588 path_elem = g_queue_peek_tail (parser->path);
589 if (path_elem == NULL
591 {
592 event->type = GVM_JSON_PULL_EVENT_ERROR;
593 event->error_message = g_strdup ("unexpected closing square bracket");
594 return 1;
595 }
596 event->type = GVM_JSON_PULL_EVENT_ARRAY_END;
597 event->value = NULL;
598 gvm_json_pull_path_elem_free (g_queue_pop_tail (parser->path));
601 break;
602 case '}':
603 path_elem = g_queue_peek_tail (parser->path);
604 if (path_elem == NULL
606 {
607 event->type = GVM_JSON_PULL_EVENT_ERROR;
608 event->error_message = g_strdup ("unexpected closing curly brace");
609 return 1;
610 }
611 event->type = GVM_JSON_PULL_EVENT_OBJECT_END;
612 event->value = NULL;
613 gvm_json_pull_path_elem_free (g_queue_pop_tail (parser->path));
616 break;
617 default:
618 event->error_message = g_strdup ("expected comma or end of container");
619 event->type = GVM_JSON_PULL_EVENT_ERROR;
620 return 1;
621 }
622 return 0;
623}
624
636static int
639{
640 if (gvm_json_pull_skip_space (parser, event, FALSE))
641 return 1;
642
643 cJSON *cjson_value = NULL;
644 gvm_json_path_elem_t *path_elem = NULL;
645
646 switch (parser->last_read_char)
647 {
648 case '"':
649 if (gvm_json_pull_parse_string (parser, event, &cjson_value))
650 return 1;
651 event->type = GVM_JSON_PULL_EVENT_STRING;
652 event->value = cjson_value;
654 break;
655 case 'n':
656 if (gvm_json_pull_parse_keyword (parser, event, "null"))
657 return 1;
658 event->type = GVM_JSON_PULL_EVENT_NULL;
659 event->value = cJSON_CreateNull ();
661 break;
662 case 'f':
663 if (gvm_json_pull_parse_keyword (parser, event, "false"))
664 return 1;
665 event->type = GVM_JSON_PULL_EVENT_BOOLEAN;
666 event->value = cJSON_CreateFalse ();
668 break;
669 case 't':
670 if (gvm_json_pull_parse_keyword (parser, event, "true"))
671 return 1;
672 event->type = GVM_JSON_PULL_EVENT_BOOLEAN;
673 event->value = cJSON_CreateTrue ();
675 break;
676 case '[':
678 event->value = NULL;
680 GVM_JSON_PULL_CONTAINER_ARRAY, parser->path->length);
683 break;
684 case ']':
685 path_elem = g_queue_peek_tail (parser->path);
686 if (path_elem == NULL
688 {
689 event->type = GVM_JSON_PULL_EVENT_ERROR;
690 event->error_message = g_strdup ("unexpected closing square bracket");
691 return 1;
692 }
693 event->type = GVM_JSON_PULL_EVENT_ARRAY_END;
694 event->value = NULL;
695 gvm_json_pull_path_elem_free (g_queue_pop_tail (parser->path));
698 break;
699 case '{':
701 event->value = NULL;
703 GVM_JSON_PULL_CONTAINER_OBJECT, parser->path->length);
706 break;
707 case '}':
708 event->type = GVM_JSON_PULL_EVENT_ERROR;
709 event->error_message = g_strdup ("unexpected closing curly brace");
710 return 1;
711 break;
712 default:
713 if (g_ascii_isdigit (parser->last_read_char)
714 || parser->last_read_char == '-')
715 {
716 if (gvm_json_pull_parse_number (parser, event, &cjson_value))
717 return 1;
718 event->type = GVM_JSON_PULL_EVENT_NUMBER;
719 event->value = cjson_value;
721 }
722 else
723 {
724 event->type = GVM_JSON_PULL_EVENT_ERROR;
725 event->error_message = g_strdup ("unexpected character");
726 return 1;
727 }
728 }
729 return 0;
730}
731
740void
743{
744 assert (parser);
745 assert (event);
746
749 {
750 // Handle first read of the stream
751 if (gvm_json_pull_parser_next_char (parser) < 0)
752 {
753 gvm_json_pull_handle_read_end (parser, event, TRUE);
754 return;
755 }
756 }
757 event->path = parser->path;
758
759 // Delayed addition to path after a container start element
760 if (parser->path_add)
761 {
762 g_queue_push_tail (parser->path, parser->path_add);
763 parser->path_add = NULL;
764 }
765
766 // Check for expected end of file
767 if (parser->expect == GVM_JSON_PULL_EXPECT_EOF)
768 {
769 gvm_json_pull_skip_space (parser, event, TRUE);
770
771 if (parser->last_read_char == GVM_JSON_CHAR_ERROR)
772 {
773 event->type = GVM_JSON_PULL_EVENT_ERROR;
774 event->error_message = gvm_json_read_stream_error_str ();
775 }
776 else if (parser->last_read_char != GVM_JSON_CHAR_EOF)
777 {
778 event->type = GVM_JSON_PULL_EVENT_ERROR;
779 event->error_message = g_strdup_printf (
780 "unexpected character at end of file (%d)", parser->last_read_char);
781 return;
782 }
783 return;
784 }
785
786 if (parser->expect == GVM_JSON_PULL_EXPECT_COMMA)
787 {
788 if (gvm_json_pull_parse_comma (parser, event))
789 return;
790 }
791
792 if (parser->expect == GVM_JSON_PULL_EXPECT_KEY)
793 {
794 if (gvm_json_pull_parse_key (parser, event))
795 return;
796 }
797
798 if (parser->expect == GVM_JSON_PULL_EXPECT_VALUE)
799 {
800 gvm_json_pull_parse_value (parser, event);
801 }
802}
803
814cJSON *
816 gchar **error_message)
817{
818 gvm_json_path_elem_t *path_tail = NULL;
819
820 int start_depth;
821 gboolean in_string, escape_next_char, in_expanded_container;
822 cJSON *expanded;
823
824 g_string_truncate (parser->parse_buffer, 0);
825
826 if (error_message)
827 *error_message = NULL;
828
829 // require "path_add" to only allow expansion at start of container
830 if (parser->path_add)
831 {
832 path_tail = parser->path_add;
833 g_queue_push_tail (parser->path, path_tail);
834 parser->path_add = NULL;
835 }
836
837 if (path_tail && path_tail->parent_type == GVM_JSON_PULL_CONTAINER_ARRAY)
838 g_string_append_c (parser->parse_buffer, '[');
839 else if (path_tail
841 g_string_append_c (parser->parse_buffer, '{');
842 else
843 {
844 if (error_message)
845 *error_message =
846 g_strdup ("can only expand after array or object start");
847 return NULL;
848 }
849
850 start_depth = path_tail->depth;
851 in_string = escape_next_char = FALSE;
852 in_expanded_container = TRUE;
853
854 while (parser->last_read_char >= 0 && in_expanded_container)
855 {
856 if (parser->parse_buffer->len >= parser->parse_buffer_limit)
857 {
858 if (error_message)
859 *error_message =
860 g_strdup_printf ("container exceeds size limit of %zu bytes",
861 parser->parse_buffer_limit);
862 return NULL;
863 }
864
865 g_string_append_c (parser->parse_buffer, parser->last_read_char);
866
867 if (escape_next_char)
868 {
869 escape_next_char = FALSE;
870 }
871 else if (in_string)
872 {
873 escape_next_char = (parser->last_read_char == '\\');
874 in_string = (parser->last_read_char != '"');
875 }
876 else
877 {
878 switch (parser->last_read_char)
879 {
880 case '"':
881 in_string = TRUE;
882 break;
883 case '[':
884 path_tail = gvm_json_pull_path_elem_new (
885 GVM_JSON_PULL_CONTAINER_ARRAY, parser->path->length);
886 g_queue_push_tail (parser->path, path_tail);
887 break;
888 case '{':
889 path_tail = gvm_json_pull_path_elem_new (
890 GVM_JSON_PULL_CONTAINER_OBJECT, parser->path->length);
891 g_queue_push_tail (parser->path, path_tail);
892 break;
893 case ']':
894 path_tail = g_queue_pop_tail (parser->path);
896 {
897 if (error_message)
898 *error_message =
899 g_strdup ("unexpected closing square bracket");
900 return NULL;
901 }
902 if (path_tail->depth == start_depth)
903 in_expanded_container = FALSE;
904 break;
905 case '}':
906 path_tail = g_queue_pop_tail (parser->path);
908 {
909 if (error_message)
910 *error_message =
911 g_strdup ("unexpected closing curly brace");
912 return NULL;
913 }
914 if (path_tail->depth == start_depth)
915 in_expanded_container = FALSE;
916 break;
917 }
918 }
920 }
921
922 if (parser->last_read_char == GVM_JSON_CHAR_ERROR)
923 {
924 if (error_message)
925 *error_message = gvm_json_read_stream_error_str ();
926 return NULL;
927 }
928 else if (in_expanded_container && parser->last_read_char == GVM_JSON_CHAR_EOF)
929 {
930 if (error_message)
931 *error_message = g_strdup ("unexpected EOF");
932 return NULL;
933 }
934
935 expanded = cJSON_Parse (parser->parse_buffer->str);
936 g_string_truncate (parser->parse_buffer, 0);
938
939 if (expanded == NULL && error_message)
940 *error_message = g_strdup ("could not parse expanded container");
941
942 return expanded;
943}
944
951static void
953 GString *path_string)
954{
956 {
957 gchar *escaped_key = gvm_json_string_escape (path_elem->key, TRUE);
958 g_string_append_printf (path_string, "['%s']", escaped_key);
959 g_free (escaped_key);
960 }
961 else
962 g_string_append_printf (path_string, "[%d]", path_elem->index);
963}
964
972gchar *
974{
975 GString *path_string = g_string_new ("$");
976 g_queue_foreach (path, (GFunc) gvm_json_path_string_add_elem, path_string);
977 return g_string_free (path_string, FALSE);
978}
static int gvm_json_pull_parse_number(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event, cJSON **cjson_value)
Parses a number in a JSON pull parser.
Definition jsonpull.c:409
void gvm_json_pull_parser_cleanup(gvm_json_pull_parser_t *parser)
Frees the data of a JSON pull parser.
Definition jsonpull.c:192
void gvm_json_pull_parser_init_full(gvm_json_pull_parser_t *parser, FILE *input_stream, size_t parse_buffer_limit, size_t read_buffer_size)
Initializes a JSON pull parser.
Definition jsonpull.c:150
static int gvm_json_pull_parse_string(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event, cJSON **cjson_value)
Parses a string in a JSON pull parser.
Definition jsonpull.c:365
static int gvm_json_pull_skip_space(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event, gboolean allow_eof)
Skips whitespaces in the input stream of a JSON pull parser.
Definition jsonpull.c:339
gchar * gvm_json_string_escape(const char *string, gboolean single_quote)
Escapes a string according to the JSON or JSONPath standard.
Definition jsonpull.c:23
static int gvm_json_pull_parse_comma(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event)
Handles the case that a comma is expected in a JSON pull parser.
Definition jsonpull.c:569
static int gvm_json_pull_parser_next_char(gvm_json_pull_parser_t *parser)
Reads the next character in a pull parser input stream.
Definition jsonpull.c:246
void gvm_json_pull_event_cleanup(gvm_json_pull_event_t *event)
Frees all data of JSON pull event data structure.
Definition jsonpull.c:133
static int gvm_json_pull_parse_value(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event)
Handles the case that a value is expected in a JSON pull parser.
Definition jsonpull.c:637
void gvm_json_pull_parser_next(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event)
Get the next event from a JSON pull parser.
Definition jsonpull.c:741
#define GVM_JSON_CHAR_UNDEFINED
Undefined state.
Definition jsonpull.c:12
void gvm_json_pull_parser_init(gvm_json_pull_parser_t *parser, FILE *input_stream)
Initializes a JSON pull parser with default buffer sizes.
Definition jsonpull.c:181
static int gvm_json_pull_parse_key(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event)
Handles the case that an object key is expected in a JSON pull parser.
Definition jsonpull.c:498
static void gvm_json_pull_handle_read_end(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event, gboolean allow_eof)
Handles error or EOF after reading a character in JSON pull parser.
Definition jsonpull.c:310
gchar * gvm_json_path_to_string(GQueue *path)
Converts a path as used by a JSON pull parser to a JSONPath string.
Definition jsonpull.c:973
#define GVM_JSON_CHAR_ERROR
Error reading file.
Definition jsonpull.c:11
cJSON * gvm_json_pull_expand_container(gvm_json_pull_parser_t *parser, gchar **error_message)
Expands the current array or object of a JSON pull parser.
Definition jsonpull.c:815
static int gvm_json_pull_parse_keyword(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event, const char *keyword)
Parses a keyword value in a JSON pull parser.
Definition jsonpull.c:450
static void gvm_json_path_string_add_elem(gvm_json_path_elem_t *path_elem, GString *path_string)
Appends a string path element to a JSONPath string.
Definition jsonpull.c:952
static int gvm_json_pull_parse_buffered(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event, const char *value_name, cJSON_bool(*validate_func)(const cJSON *const), cJSON **cjson_value)
Tries to parse the buffer content of a JSON pull parser.
Definition jsonpull.c:283
static void parse_value_next_expect(gvm_json_pull_parser_t *parser)
Updates the expectation for a JSON pull parser according to the path.
Definition jsonpull.c:478
#define GVM_JSON_CHAR_EOF
End of file.
Definition jsonpull.c:10
static int gvm_json_pull_check_parse_buffer_size(const char *value_type, gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event)
Checks if the parse buffer limit of a JSON pull parser is reached.
Definition jsonpull.c:223
void gvm_json_pull_path_elem_free(gvm_json_path_elem_t *elem)
Frees a JSON path element.
Definition jsonpull.c:96
gvm_json_path_elem_t * gvm_json_pull_path_elem_new(gvm_json_pull_container_type_t parent_type, int depth)
Creates a new JSON path element.
Definition jsonpull.c:81
void gvm_json_pull_event_init(gvm_json_pull_event_t *event)
Initializes a JSON pull event data structure.
Definition jsonpull.c:108
static gchar * gvm_json_read_stream_error_str()
Generates message for an error that occurred reading the JSON stream.
Definition jsonpull.c:208
void gvm_json_pull_event_reset(gvm_json_pull_event_t *event)
Resets a JSON pull event data structure for reuse.
Definition jsonpull.c:119
#define GVM_JSON_PULL_READ_BUFFER_SIZE
Definition jsonpull.h:79
#define GVM_JSON_PULL_PARSE_BUFFER_LIMIT
Definition jsonpull.h:77
gvm_json_pull_container_type_t
Type of container the parser is currently in.
Definition jsonpull.h:19
@ GVM_JSON_PULL_CONTAINER_OBJECT
Object.
Definition jsonpull.h:22
@ GVM_JSON_PULL_CONTAINER_ARRAY
Array.
Definition jsonpull.h:21
@ GVM_JSON_PULL_EXPECT_VALUE
Expect start of a value.
Definition jsonpull.h:71
@ GVM_JSON_PULL_EXPECT_KEY
Expect start of a key.
Definition jsonpull.h:72
@ GVM_JSON_PULL_EXPECT_EOF
Expect end of file.
Definition jsonpull.h:74
@ GVM_JSON_PULL_EXPECT_COMMA
Expect comma or container end brace.
Definition jsonpull.h:73
@ GVM_JSON_PULL_EVENT_STRING
Definition jsonpull.h:46
@ GVM_JSON_PULL_EVENT_OBJECT_START
Definition jsonpull.h:44
@ GVM_JSON_PULL_EVENT_ERROR
Definition jsonpull.h:51
@ GVM_JSON_PULL_EVENT_NULL
Definition jsonpull.h:49
@ GVM_JSON_PULL_EVENT_EOF
Definition jsonpull.h:50
@ GVM_JSON_PULL_EVENT_NUMBER
Definition jsonpull.h:47
@ GVM_JSON_PULL_EVENT_ARRAY_END
Definition jsonpull.h:43
@ GVM_JSON_PULL_EVENT_OBJECT_END
Definition jsonpull.h:45
@ GVM_JSON_PULL_EVENT_ARRAY_START
Definition jsonpull.h:42
@ GVM_JSON_PULL_EVENT_BOOLEAN
Definition jsonpull.h:48
Path element types for the JSON pull parser.
Definition jsonpull.h:29
int depth
Number of ancestor elements.
Definition jsonpull.h:33
int index
Index of the element within the parent.
Definition jsonpull.h:31
char * key
Key if element is in an object.
Definition jsonpull.h:32
gvm_json_pull_container_type_t parent_type
parent container type
Definition jsonpull.h:30
Event generated by the JSON pull parser.
Definition jsonpull.h:58
gchar * error_message
Error message, NULL on success.
Definition jsonpull.h:62
cJSON * value
Value for non-container value events.
Definition jsonpull.h:61
A json pull parser.
Definition jsonpull.h:85
char * read_buffer
Stream reading buffer.
Definition jsonpull.h:91
size_t read_buffer_size
Size of the stream reading buffer.
Definition jsonpull.h:92
gvm_json_pull_expect_t expect
Current expected token.
Definition jsonpull.h:88
size_t last_read_size
Size of last stream read.
Definition jsonpull.h:93
GString * parse_buffer
Buffer for parsing values and object keys.
Definition jsonpull.h:96
size_t parse_buffer_limit
Maximum parse buffer size.
Definition jsonpull.h:97
gvm_json_path_elem_t * path_add
Path elem to add in next step.
Definition jsonpull.h:87
size_t read_pos
Position in current read.
Definition jsonpull.h:95
GQueue * path
Path to the current value.
Definition jsonpull.h:86
int last_read_char
Character last read from stream.
Definition jsonpull.h:94
FILE * input_stream
Input stream.
Definition jsonpull.h:90