1 /*
2 *
3 * json.c
4 *
5 * pgpool: a language independent connection pool server for PostgreSQL
6 * written by Tatsuo Ishii
7 *
8 * Copyright (c) 2003-2015 PgPool Global Development Group
9 *
10 * Permission to use, copy, modify, and distribute this software and
11 * its documentation for any purpose and without fee is hereby
12 * granted, provided that the above copyright notice appear in all
13 * copies and that both that copyright notice and this permission
14 * notice appear in supporting documentation, and that the name of the
15 * author not be used in advertising or publicity pertaining to
16 * distribution of the software without specific, written prior
17 * permission. The author makes no representations about the
18 * suitability of this software for any purpose. It is provided "as
19 * is" without express or implied warranty.
20 *
21 *
22 * portion copyright
23 * vim: set et ts=3 sw=3 sts=3 ft=c:
24 *
25 * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved.
26 * https://github.com/udp/json-parser
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 *
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 *
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
40 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
43 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
44 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
45 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
47 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
48 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * SUCH DAMAGE.
50 */
51
52 #include "utils/json.h"
53
54 #ifdef _MSC_VER
55 #ifndef _CRT_SECURE_NO_WARNINGS
56 #define _CRT_SECURE_NO_WARNINGS
57 #endif
58 #endif
59
60 const struct _json_value json_value_none;
61 #include "pool.h"
62
63 #include <stdio.h>
64 #include <string.h>
65 #include <ctype.h>
66 #include <math.h>
67
68 #ifndef POOL_PRIVATE
69 #include "utils/palloc.h"
70 #include "utils/memutils.h"
71 #include "utils/elog.h"
72 #else
73 #include "utils/fe_ports.h"
74 #endif
75
76 typedef unsigned int json_uchar;
77
78 static unsigned char
hex_value(json_char c)79 hex_value(json_char c)
80 {
81 if (isdigit(c))
82 return c - '0';
83
84 switch (c)
85 {
86 case 'a':
87 case 'A':
88 return 0x0A;
89 case 'b':
90 case 'B':
91 return 0x0B;
92 case 'c':
93 case 'C':
94 return 0x0C;
95 case 'd':
96 case 'D':
97 return 0x0D;
98 case 'e':
99 case 'E':
100 return 0x0E;
101 case 'f':
102 case 'F':
103 return 0x0F;
104 default:
105 return 0xFF;
106 }
107 }
108
109 typedef struct
110 {
111 unsigned long used_memory;
112
113 unsigned int uint_max;
114 unsigned long ulong_max;
115
116 json_settings settings;
117 int first_pass;
118
119 const json_char *ptr;
120 unsigned int cur_line,
121 cur_col;
122
123 } json_state;
124
125 static void *
default_alloc(size_t size,int zero,void * user_data)126 default_alloc(size_t size, int zero, void *user_data)
127 {
128 return zero ? palloc0(size) : palloc(size);
129 }
130
131 static void
default_free(void * ptr,void * user_data)132 default_free(void *ptr, void *user_data)
133 {
134 pfree(ptr);
135 }
136
137 static void *
json_alloc(json_state * state,unsigned long size,int zero)138 json_alloc(json_state * state, unsigned long size, int zero)
139 {
140 if ((state->ulong_max - state->used_memory) < size)
141 return 0;
142
143 if (state->settings.max_memory
144 && (state->used_memory += size) > state->settings.max_memory)
145 {
146 return 0;
147 }
148
149 return state->settings.mem_alloc(size, zero, state->settings.user_data);
150 }
151
152 static int
new_value(json_state * state,json_value ** top,json_value ** root,json_value ** alloc,json_type type)153 new_value(json_state * state,
154 json_value * *top, json_value * *root, json_value * *alloc,
155 json_type type)
156 {
157 json_value *value;
158 int values_size;
159
160 if (!state->first_pass)
161 {
162 value = *top = *alloc;
163 *alloc = (*alloc)->_reserved.next_alloc;
164
165 if (!*root)
166 *root = value;
167
168 switch (value->type)
169 {
170 case json_array:
171
172 if (value->u.array.length == 0)
173 break;
174
175 if (!(value->u.array.values = (json_value * *) json_alloc
176 (state, value->u.array.length * sizeof(json_value *), 0)))
177 {
178 return 0;
179 }
180
181 value->u.array.length = 0;
182 break;
183
184 case json_object:
185
186 if (value->u.object.length == 0)
187 break;
188
189 values_size = sizeof(*value->u.object.values) * value->u.object.length;
190
191 if (!(value->u.object.values = (json_object_entry *) json_alloc
192 (state, values_size + ((unsigned long) value->u.object.values), 0)))
193 {
194 return 0;
195 }
196
197 value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
198
199 value->u.object.length = 0;
200 break;
201
202 case json_string:
203
204 if (!(value->u.string.ptr = (json_char *) json_alloc
205 (state, (value->u.string.length + 1) * sizeof(json_char), 0)))
206 {
207 return 0;
208 }
209
210 value->u.string.length = 0;
211 break;
212
213 default:
214 break;
215 };
216
217 return 1;
218 }
219
220 if (!(value = (json_value *) json_alloc
221 (state, sizeof(json_value) + state->settings.value_extra, 1)))
222 {
223 return 0;
224 }
225
226 if (!*root)
227 *root = value;
228
229 value->type = type;
230 value->parent = *top;
231
232 #ifdef JSON_TRACK_SOURCE
233 value->line = state->cur_line;
234 value->col = state->cur_col;
235 #endif
236
237 if (*alloc)
238 (*alloc)->_reserved.next_alloc = value;
239
240 *alloc = *top = value;
241
242 return 1;
243 }
244
245 #define whitespace \
246 case '\n': ++ state.cur_line; state.cur_col = 0; \
247 case ' ': case '\t': case '\r'
248
249 #define string_add(b) \
250 do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
251
252 #define line_and_col \
253 state.cur_line, state.cur_col
254
255 static const long
256 flag_next = 1 << 0,
257 flag_reproc = 1 << 1,
258 flag_need_comma = 1 << 2,
259 flag_seek_value = 1 << 3,
260 flag_escaped = 1 << 4,
261 flag_string = 1 << 5,
262 flag_need_colon = 1 << 6,
263 flag_done = 1 << 7,
264 flag_num_negative = 1 << 8,
265 flag_num_zero = 1 << 9,
266 flag_num_e = 1 << 10,
267 flag_num_e_got_sign = 1 << 11,
268 flag_num_e_negative = 1 << 12,
269 flag_line_comment = 1 << 13,
270 flag_block_comment = 1 << 14;
271
272 json_value *
json_parse_ex(json_settings * settings,const json_char * json,size_t length,char * error_buf)273 json_parse_ex(json_settings * settings,
274 const json_char * json,
275 size_t length,
276 char *error_buf)
277 {
278 json_char error[json_error_max];
279 const json_char *end;
280 json_value *top,
281 *root,
282 *alloc = 0;
283 json_state state = {0};
284 long flags;
285 long num_digits = 0,
286 num_e = 0;
287 json_int_t num_fraction = 0;
288
289 /*
290 * Skip UTF-8 BOM
291 */
292 if (length >= 3 && ((unsigned char) json[0]) == 0xEF
293 && ((unsigned char) json[1]) == 0xBB
294 && ((unsigned char) json[2]) == 0xBF)
295 {
296 json += 3;
297 length -= 3;
298 }
299
300 error[0] = '\0';
301 end = (json + length);
302
303 memcpy(&state.settings, settings, sizeof(json_settings));
304
305 if (!state.settings.mem_alloc)
306 state.settings.mem_alloc = default_alloc;
307
308 if (!state.settings.mem_free)
309 state.settings.mem_free = default_free;
310
311 memset(&state.uint_max, 0xFF, sizeof(state.uint_max));
312 memset(&state.ulong_max, 0xFF, sizeof(state.ulong_max));
313
314 state.uint_max -= 8; /* limit of how much can be added before next
315 * check */
316 state.ulong_max -= 8;
317
318 for (state.first_pass = 1; state.first_pass >= 0; --state.first_pass)
319 {
320 json_uchar uchar;
321 unsigned char uc_b1,
322 uc_b2,
323 uc_b3,
324 uc_b4;
325 json_char *string = 0;
326 unsigned int string_length = 0;
327
328 top = root = 0;
329 flags = flag_seek_value;
330
331 state.cur_line = 1;
332
333 for (state.ptr = json;; ++state.ptr)
334 {
335 json_char b = (state.ptr == end ? 0 : *state.ptr);
336
337 if (flags & flag_string)
338 {
339 if (!b)
340 {
341 ereport(DEBUG1,
342 (errmsg("Unexpected EOF in JSON string (at %d:%d)", line_and_col)));
343 goto e_failed;
344 }
345
346 if (string_length > state.uint_max)
347 goto e_overflow;
348
349 if (flags & flag_escaped)
350 {
351 flags &= ~flag_escaped;
352
353 switch (b)
354 {
355 case 'b':
356 string_add('\b');
357 break;
358 case 'f':
359 string_add('\f');
360 break;
361 case 'n':
362 string_add('\n');
363 break;
364 case 'r':
365 string_add('\r');
366 break;
367 case 't':
368 string_add('\t');
369 break;
370 case 'u':
371
372 if (end - state.ptr < 4 ||
373 (uc_b1 = hex_value(*++state.ptr)) == 0xFF ||
374 (uc_b2 = hex_value(*++state.ptr)) == 0xFF ||
375 (uc_b3 = hex_value(*++state.ptr)) == 0xFF ||
376 (uc_b4 = hex_value(*++state.ptr)) == 0xFF)
377 {
378 ereport(DEBUG1,
379 (errmsg("JSON ERROR, invalid character value `%c` (at %d:%d)", b, line_and_col)));
380 goto e_failed;
381 }
382
383 uc_b1 = (uc_b1 << 4) | uc_b2;
384 uc_b2 = (uc_b3 << 4) | uc_b4;
385 uchar = (uc_b1 << 8) | uc_b2;
386
387 if ((uchar & 0xF800) == 0xD800)
388 {
389 json_uchar uchar2;
390
391 if (end - state.ptr < 6 || (*++state.ptr) != '\\' || (*++state.ptr) != 'u' ||
392 (uc_b1 = hex_value(*++state.ptr)) == 0xFF ||
393 (uc_b2 = hex_value(*++state.ptr)) == 0xFF ||
394 (uc_b3 = hex_value(*++state.ptr)) == 0xFF ||
395 (uc_b4 = hex_value(*++state.ptr)) == 0xFF)
396 {
397 ereport(DEBUG1,
398 (errmsg("JSON ERROR, Invalid character value `%c` (at %d:%d)", b, line_and_col)));
399 goto e_failed;
400 }
401
402 uc_b1 = (uc_b1 << 4) | uc_b2;
403 uc_b2 = (uc_b3 << 4) | uc_b4;
404 uchar2 = (uc_b1 << 8) | uc_b2;
405
406 uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
407 }
408
409 if (sizeof(json_char) >= sizeof(json_uchar) || (uchar <= 0x7F))
410 {
411 string_add((json_char) uchar);
412 break;
413 }
414
415 if (uchar <= 0x7FF)
416 {
417 if (state.first_pass)
418 string_length += 2;
419 else
420 {
421 string[string_length++] = 0xC0 | (uchar >> 6);
422 string[string_length++] = 0x80 | (uchar & 0x3F);
423 }
424
425 break;
426 }
427
428 if (uchar <= 0xFFFF)
429 {
430 if (state.first_pass)
431 string_length += 3;
432 else
433 {
434 string[string_length++] = 0xE0 | (uchar >> 12);
435 string[string_length++] = 0x80 | ((uchar >> 6) & 0x3F);
436 string[string_length++] = 0x80 | (uchar & 0x3F);
437 }
438
439 break;
440 }
441
442 if (state.first_pass)
443 string_length += 4;
444 else
445 {
446 string[string_length++] = 0xF0 | (uchar >> 18);
447 string[string_length++] = 0x80 | ((uchar >> 12) & 0x3F);
448 string[string_length++] = 0x80 | ((uchar >> 6) & 0x3F);
449 string[string_length++] = 0x80 | (uchar & 0x3F);
450 }
451
452 break;
453
454 default:
455 string_add(b);
456 };
457
458 continue;
459 }
460
461 if (b == '\\')
462 {
463 flags |= flag_escaped;
464 continue;
465 }
466
467 if (b == '"')
468 {
469 if (!state.first_pass)
470 string[string_length] = 0;
471
472 flags &= ~flag_string;
473 string = 0;
474
475 switch (top->type)
476 {
477 case json_string:
478
479 top->u.string.length = string_length;
480 flags |= flag_next;
481
482 break;
483
484 case json_object:
485
486 if (state.first_pass)
487 (*(json_char * *) & top->u.object.values) += string_length + 1;
488 else
489 {
490 top->u.object.values[top->u.object.length].name
491 = (json_char *) top->_reserved.object_mem;
492
493 top->u.object.values[top->u.object.length].name_length
494 = string_length;
495
496 (*(json_char * *) & top->_reserved.object_mem) += string_length + 1;
497 }
498
499 flags |= flag_seek_value | flag_need_colon;
500 continue;
501
502 default:
503 break;
504 };
505 }
506 else
507 {
508 string_add(b);
509 continue;
510 }
511 }
512
513 if (state.settings.settings & json_enable_comments)
514 {
515 if (flags & (flag_line_comment | flag_block_comment))
516 {
517 if (flags & flag_line_comment)
518 {
519 if (b == '\r' || b == '\n' || !b)
520 {
521 flags &= ~flag_line_comment;
522 --state.ptr; /* so null can be reproc'd */
523 }
524
525 continue;
526 }
527
528 if (flags & flag_block_comment)
529 {
530 if (!b)
531 {
532 ereport(DEBUG1,
533 (errmsg("JSON ERROR, %d:%d: Unexpected EOF in block comment", line_and_col)));
534
535 goto e_failed;
536 }
537
538 if (b == '*' && state.ptr < (end - 1) && state.ptr[1] == '/')
539 {
540 flags &= ~flag_block_comment;
541 ++state.ptr; /* skip closing sequence */
542 }
543
544 continue;
545 }
546 }
547 else if (b == '/')
548 {
549 if (!(flags & (flag_seek_value | flag_done)) && top->type != json_object)
550 {
551 ereport(DEBUG1,
552 (errmsg("JSON ERROR, %d:%d: Comment not allowed here", line_and_col)));
553
554 goto e_failed;
555 }
556
557 if (++state.ptr == end)
558 {
559 ereport(DEBUG1,
560 (errmsg("JSON ERROR, %d:%d: EOF unexpected", line_and_col)));
561
562 goto e_failed;
563 }
564
565 switch (b = *state.ptr)
566 {
567 case '/':
568 flags |= flag_line_comment;
569 continue;
570
571 case '*':
572 flags |= flag_block_comment;
573 continue;
574
575 default:
576 ereport(DEBUG1,
577 (errmsg("JSON ERROR, %d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b)));
578 goto e_failed;
579 };
580 }
581 }
582
583 if (flags & flag_done)
584 {
585 if (!b)
586 break;
587
588 switch (b)
589 {
590 whitespace:
591 continue;
592
593 default:
594 ereport(DEBUG1,
595 (errmsg("JSON ERROR, %d:%d: Trailing garbage: ", state.cur_line, state.cur_col)));
596 goto e_failed;
597 };
598 }
599
600 if (flags & flag_seek_value)
601 {
602 switch (b)
603 {
604 whitespace:
605 continue;
606
607 case ']':
608
609 if (top && top->type == json_array)
610 flags = (flags & ~(flag_need_comma | flag_seek_value)) | flag_next;
611 else
612 {
613 ereport(DEBUG1,
614 (errmsg("%d:%d: Unexpected ]", line_and_col)));
615
616 goto e_failed;
617 }
618
619 break;
620
621 default:
622
623 if (flags & flag_need_comma)
624 {
625 if (b == ',')
626 {
627 flags &= ~flag_need_comma;
628 continue;
629 }
630 else
631 {
632 ereport(DEBUG1,
633 (errmsg("%d:%d: Expected , before %c",
634 state.cur_line, state.cur_col, b)));
635
636 goto e_failed;
637 }
638 }
639
640 if (flags & flag_need_colon)
641 {
642 if (b == ':')
643 {
644 flags &= ~flag_need_colon;
645 continue;
646 }
647 else
648 {
649 ereport(DEBUG1,
650 (errmsg("%d:%d: Expected : before %c",
651 state.cur_line, state.cur_col, b)));
652
653 goto e_failed;
654 }
655 }
656
657 flags &= ~flag_seek_value;
658
659 switch (b)
660 {
661 case '{':
662
663 if (!new_value(&state, &top, &root, &alloc, json_object))
664 goto e_alloc_failure;
665
666 continue;
667
668 case '[':
669
670 if (!new_value(&state, &top, &root, &alloc, json_array))
671 goto e_alloc_failure;
672
673 flags |= flag_seek_value;
674 continue;
675
676 case '"':
677
678 if (!new_value(&state, &top, &root, &alloc, json_string))
679 goto e_alloc_failure;
680
681 flags |= flag_string;
682
683 string = top->u.string.ptr;
684 string_length = 0;
685
686 continue;
687
688 case 't':
689
690 if ((end - state.ptr) < 3 || *(++state.ptr) != 'r' ||
691 *(++state.ptr) != 'u' || *(++state.ptr) != 'e')
692 {
693 goto e_unknown_value;
694 }
695
696 if (!new_value(&state, &top, &root, &alloc, json_boolean))
697 goto e_alloc_failure;
698
699 top->u.boolean = 1;
700
701 flags |= flag_next;
702 break;
703
704 case 'f':
705
706 if ((end - state.ptr) < 4 || *(++state.ptr) != 'a' ||
707 *(++state.ptr) != 'l' || *(++state.ptr) != 's' ||
708 *(++state.ptr) != 'e')
709 {
710 goto e_unknown_value;
711 }
712
713 if (!new_value(&state, &top, &root, &alloc, json_boolean))
714 goto e_alloc_failure;
715
716 flags |= flag_next;
717 break;
718
719 case 'n':
720
721 if ((end - state.ptr) < 3 || *(++state.ptr) != 'u' ||
722 *(++state.ptr) != 'l' || *(++state.ptr) != 'l')
723 {
724 goto e_unknown_value;
725 }
726
727 if (!new_value(&state, &top, &root, &alloc, json_null))
728 goto e_alloc_failure;
729
730 flags |= flag_next;
731 break;
732
733 default:
734
735 if (isdigit(b) || b == '-')
736 {
737 if (!new_value(&state, &top, &root, &alloc, json_integer))
738 goto e_alloc_failure;
739
740 if (!state.first_pass)
741 {
742 while (isdigit(b) || b == '+' || b == '-'
743 || b == 'e' || b == 'E' || b == '.')
744 {
745 if ((++state.ptr) == end)
746 {
747 b = 0;
748 break;
749 }
750
751 b = *state.ptr;
752 }
753
754 flags |= flag_next | flag_reproc;
755 break;
756 }
757
758 flags &= ~(flag_num_negative | flag_num_e |
759 flag_num_e_got_sign | flag_num_e_negative |
760 flag_num_zero);
761
762 num_digits = 0;
763 num_fraction = 0;
764 num_e = 0;
765
766 if (b != '-')
767 {
768 flags |= flag_reproc;
769 break;
770 }
771
772 flags |= flag_num_negative;
773 continue;
774 }
775 else
776 {
777 ereport(DEBUG1,
778 (errmsg("%d:%d: Unexpected %c when seeking value", line_and_col, b)));
779
780 goto e_failed;
781 }
782 };
783 };
784 }
785 else
786 {
787 switch (top->type)
788 {
789 case json_object:
790
791 switch (b)
792 {
793 whitespace:
794 continue;
795
796 case '"':
797
798 if (flags & flag_need_comma)
799 {
800 ereport(DEBUG1,
801 (errmsg("JSON ERROR: %d:%d: Expected , before \"", line_and_col)));
802 goto e_failed;
803 }
804
805 flags |= flag_string;
806
807 string = (json_char *) top->_reserved.object_mem;
808 string_length = 0;
809
810 break;
811
812 case '}':
813
814 flags = (flags & ~flag_need_comma) | flag_next;
815 break;
816
817 case ',':
818
819 if (flags & flag_need_comma)
820 {
821 flags &= ~flag_need_comma;
822 break;
823 }
824
825 default:
826 ereport(DEBUG1,
827 (errmsg("JSON ERROR: %d:%d: Unexpected `%c` in object", line_and_col, b)));
828 goto e_failed;
829 };
830
831 break;
832
833 case json_integer:
834 case json_double:
835
836 if (isdigit(b))
837 {
838 ++num_digits;
839
840 if (top->type == json_integer || flags & flag_num_e)
841 {
842 if (!(flags & flag_num_e))
843 {
844 if (flags & flag_num_zero)
845 {
846 ereport(DEBUG1,
847 (errmsg("JSON ERROR: %d:%d: Unexpected `0` before `%c`", line_and_col, b)));
848 goto e_failed;
849 }
850
851 if (num_digits == 1 && b == '0')
852 flags |= flag_num_zero;
853 }
854 else
855 {
856 flags |= flag_num_e_got_sign;
857 num_e = (num_e * 10) + (b - '0');
858 continue;
859 }
860
861 top->u.integer = (top->u.integer * 10) + (b - '0');
862 continue;
863 }
864
865 num_fraction = (num_fraction * 10) + (b - '0');
866 continue;
867 }
868
869 if (b == '+' || b == '-')
870 {
871 if ((flags & flag_num_e) && !(flags & flag_num_e_got_sign))
872 {
873 flags |= flag_num_e_got_sign;
874
875 if (b == '-')
876 flags |= flag_num_e_negative;
877
878 continue;
879 }
880 }
881 else if (b == '.' && top->type == json_integer)
882 {
883 if (!num_digits)
884 {
885 ereport(DEBUG1,
886 (errmsg("JSON ERROR: %d:%d: Expected digit before `.`", line_and_col)));
887 goto e_failed;
888 }
889
890 top->type = json_double;
891 top->u.dbl = (double) top->u.integer;
892
893 num_digits = 0;
894 continue;
895 }
896
897 if (!(flags & flag_num_e))
898 {
899 if (top->type == json_double)
900 {
901 if (!num_digits)
902 {
903 ereport(DEBUG1,
904 (errmsg("JSON ERROR: %d:%d: Expected digit after `.`", line_and_col)));
905 goto e_failed;
906 }
907
908 top->u.dbl += ((double) num_fraction) / (pow(10.0, (double) num_digits));
909 }
910
911 if (b == 'e' || b == 'E')
912 {
913 flags |= flag_num_e;
914
915 if (top->type == json_integer)
916 {
917 top->type = json_double;
918 top->u.dbl = (double) top->u.integer;
919 }
920
921 num_digits = 0;
922 flags &= ~flag_num_zero;
923
924 continue;
925 }
926 }
927 else
928 {
929 if (!num_digits)
930 {
931 ereport(DEBUG1,
932 (errmsg("JSON ERROR: %d:%d: Expected digit after `e`", line_and_col)));
933 goto e_failed;
934 }
935
936 top->u.dbl *= pow(10.0, (double)
937 (flags & flag_num_e_negative ? -num_e : num_e));
938 }
939
940 if (flags & flag_num_negative)
941 {
942 if (top->type == json_integer)
943 top->u.integer = -top->u.integer;
944 else
945 top->u.dbl = -top->u.dbl;
946 }
947
948 flags |= flag_next | flag_reproc;
949 break;
950
951 default:
952 break;
953 };
954 }
955
956 if (flags & flag_reproc)
957 {
958 flags &= ~flag_reproc;
959 --state.ptr;
960 }
961
962 if (flags & flag_next)
963 {
964 flags = (flags & ~flag_next) | flag_need_comma;
965
966 if (!top->parent)
967 {
968 /* root value done */
969
970 flags |= flag_done;
971 continue;
972 }
973
974 if (top->parent->type == json_array)
975 flags |= flag_seek_value;
976
977 if (!state.first_pass)
978 {
979 json_value *parent = top->parent;
980
981 switch (parent->type)
982 {
983 case json_object:
984
985 parent->u.object.values
986 [parent->u.object.length].value = top;
987
988 break;
989
990 case json_array:
991
992 parent->u.array.values
993 [parent->u.array.length] = top;
994
995 break;
996
997 default:
998 break;
999 };
1000 }
1001
1002 if ((++top->parent->u.array.length) > state.uint_max)
1003 goto e_overflow;
1004
1005 top = top->parent;
1006
1007 continue;
1008 }
1009 }
1010
1011 alloc = root;
1012 }
1013
1014 return root;
1015
1016 e_unknown_value:
1017
1018 ereport(DEBUG1,
1019 (errmsg("JSON ERROR: %d:%d: Unknown value", line_and_col)));
1020 goto e_failed;
1021
1022 e_alloc_failure:
1023
1024 strcpy(error, "Memory allocation failure");
1025 goto e_failed;
1026
1027 e_overflow:
1028
1029 ereport(DEBUG1,
1030 (errmsg("JSON ERROR: %d:%d: Too long (caught overflow)", line_and_col)));
1031 goto e_failed;
1032
1033 e_failed:
1034
1035 if (error_buf)
1036 {
1037 if (*error)
1038 strcpy(error_buf, error);
1039 else
1040 strcpy(error_buf, "Unknown error");
1041 }
1042
1043 if (state.first_pass)
1044 alloc = root;
1045
1046 while (alloc)
1047 {
1048 top = alloc->_reserved.next_alloc;
1049 state.settings.mem_free(alloc, state.settings.user_data);
1050 alloc = top;
1051 }
1052
1053 if (!state.first_pass)
1054 json_value_free_ex(&state.settings, root);
1055
1056 return 0;
1057 }
1058
1059 json_value *
json_parse(const json_char * json,size_t length)1060 json_parse(const json_char * json, size_t length)
1061 {
1062 json_settings settings = {0};
1063
1064 return json_parse_ex(&settings, json, length, 0);
1065 }
1066
1067 void
json_value_free_ex(json_settings * settings,json_value * value)1068 json_value_free_ex(json_settings * settings, json_value * value)
1069 {
1070 json_value *cur_value;
1071
1072 if (!value)
1073 return;
1074
1075 value->parent = 0;
1076
1077 while (value)
1078 {
1079 switch (value->type)
1080 {
1081 case json_array:
1082
1083 if (!value->u.array.length)
1084 {
1085 settings->mem_free(value->u.array.values, settings->user_data);
1086 break;
1087 }
1088
1089 value = value->u.array.values[--value->u.array.length];
1090 continue;
1091
1092 case json_object:
1093
1094 if (!value->u.object.length)
1095 {
1096 settings->mem_free(value->u.object.values, settings->user_data);
1097 break;
1098 }
1099
1100 value = value->u.object.values[--value->u.object.length].value;
1101 continue;
1102
1103 case json_string:
1104
1105 settings->mem_free(value->u.string.ptr, settings->user_data);
1106 break;
1107
1108 default:
1109 break;
1110 };
1111
1112 cur_value = value;
1113 value = value->parent;
1114 settings->mem_free(cur_value, settings->user_data);
1115 }
1116 }
1117
1118 void
json_value_free(json_value * value)1119 json_value_free(json_value * value)
1120 {
1121 json_settings settings = {0};
1122
1123 settings.mem_free = default_free;
1124 json_value_free_ex(&settings, value);
1125 }
1126
1127 /********* pgpool extension:********/
1128
1129 /*
1130 * pgpool extension:
1131 * search node with key from json object
1132 */
1133 json_value *
json_get_value_for_key(json_value * source,const char * key)1134 json_get_value_for_key(json_value * source, const char *key)
1135 {
1136 if (source->type == json_object)
1137 {
1138 int x;
1139
1140 for (x = 0; x < source->u.object.length; x++)
1141 {
1142 if (strcasecmp(source->u.object.values[x].name, key) == 0)
1143 return source->u.object.values[x].value;
1144 }
1145 }
1146 else
1147 ereport(DEBUG1,
1148 (errmsg("JSON ERROR, Passed in json is not object node")));
1149 return NULL;
1150 }
1151
1152 /*
1153 * pgpool extension:
1154 * returns 0 if the integer value is found for the key.
1155 * for all other cases when key or integer value is not found
1156 * function returns -1
1157 */
1158
1159 int
json_get_bool_value_for_key(json_value * source,const char * key,bool * value)1160 json_get_bool_value_for_key(json_value * source, const char *key, bool *value)
1161 {
1162 json_value *jNode;
1163
1164 jNode = json_get_value_for_key(source, key);
1165 if (jNode == NULL)
1166 return -1;
1167 /* for older version compatibility, We use int for encoding bool values */
1168 if (jNode->type == json_integer || jNode->type == json_boolean)
1169 {
1170 *value = jNode->u.integer ? true : false;
1171 }
1172 else
1173 return -1;
1174
1175 return 0;
1176 }
1177
1178
1179 int
json_get_int_value_for_key(json_value * source,const char * key,int * value)1180 json_get_int_value_for_key(json_value * source, const char *key, int *value)
1181 {
1182 json_value *jNode;
1183
1184 jNode = json_get_value_for_key(source, key);
1185 if (jNode == NULL)
1186 return -1;
1187 if (jNode->type != json_integer)
1188 return -1;
1189 *value = jNode->u.integer;
1190 return 0;
1191 }
1192
1193 int
json_get_long_value_for_key(json_value * source,const char * key,long * value)1194 json_get_long_value_for_key(json_value * source, const char *key, long *value)
1195 {
1196 json_value *jNode;
1197
1198 jNode = json_get_value_for_key(source, key);
1199 if (jNode == NULL)
1200 return -1;
1201 if (jNode->type != json_integer)
1202 return -1;
1203 *value = jNode->u.integer;
1204 return 0;
1205 }
1206
1207 /*
1208 * pgpool extension:
1209 * returns string value if found for the key.
1210 * for all other cases when key or string value is not found
1211 * function returns NULL
1212 */
1213
1214 char *
json_get_string_value_for_key(json_value * source,const char * key)1215 json_get_string_value_for_key(json_value * source, const char *key)
1216 {
1217 json_value *jNode;
1218
1219 jNode = json_get_value_for_key(source, key);
1220 if (jNode == NULL)
1221 return NULL;
1222 if (jNode->type != json_string)
1223 return NULL;
1224 return jNode->u.string.ptr;
1225 }
1226