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