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