LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geojson/libjson - json_object.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 498 856 58.2 %
Date: 2024-05-06 13:02:59 Functions: 74 99 74.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
       3             :  * Michael Clark <michael@metaparadigm.com>
       4             :  * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the MIT license. See COPYING for details.
       8             :  *
       9             :  */
      10             : 
      11             : #include "cpl_port.h"
      12             : 
      13             : #include "config.h"
      14             : 
      15             : #include "strerror_override.h"
      16             : 
      17             : #include <assert.h>
      18             : #include <ctype.h>
      19             : #ifdef HAVE_LIMITS_H
      20             : #include <limits.h>
      21             : #endif
      22             : #include <math.h>
      23             : #include <stddef.h>
      24             : #include <stdio.h>
      25             : #include <stdlib.h>
      26             : #include <string.h>
      27             : 
      28             : #include "arraylist.h"
      29             : #include "debug.h"
      30             : #include "json_inttypes.h"
      31             : #include "json_object.h"
      32             : #include "json_object_private.h"
      33             : #include "json_util.h"
      34             : #include "linkhash.h"
      35             : #include "math_compat.h"
      36             : #include "printbuf.h"
      37             : #include "snprintf_compat.h"
      38             : #include "strdup_compat.h"
      39             : 
      40             : #include "cpl_string.h"
      41             : 
      42             : #if SIZEOF_LONG_LONG != SIZEOF_INT64_T
      43             : #error "The long long type isn't 64-bits"
      44             : #endif
      45             : 
      46             : #ifndef SSIZE_T_MAX
      47             : #if SIZEOF_SSIZE_T == SIZEOF_INT
      48             : #define SSIZE_T_MAX INT_MAX
      49             : #elif SIZEOF_SSIZE_T == SIZEOF_LONG
      50             : #define SSIZE_T_MAX LONG_MAX
      51             : #elif SIZEOF_SSIZE_T == SIZEOF_LONG_LONG
      52             : #define SSIZE_T_MAX LLONG_MAX
      53             : #else
      54             : #error Unable to determine size of ssize_t
      55             : #endif
      56             : #endif
      57             : 
      58             : // Don't define this.  It's not thread-safe.
      59             : /* #define REFCOUNT_DEBUG 1 */
      60             : 
      61             : const char *json_hex_chars = "0123456789abcdefABCDEF";
      62             : 
      63             : static void json_object_generic_delete(struct json_object *jso);
      64             : 
      65             : #if defined(_MSC_VER) && (_MSC_VER <= 1800)
      66             : /* VS2013 doesn't know about "inline" */
      67             : #define inline __inline
      68             : #elif defined(AIX_CC)
      69             : #define inline
      70             : #endif
      71             : 
      72             : /*
      73             :  * Helper functions to more safely cast to a particular type of json_object
      74             :  */
      75     4653650 : static inline struct json_object_object *JC_OBJECT(struct json_object *jso)
      76             : {
      77     4653650 :   return (void *)jso;
      78             : }
      79     1078200 : static inline const struct json_object_object *JC_OBJECT_C(const struct json_object *jso)
      80             : {
      81     1078200 :   return (const void *)jso;
      82             : }
      83     1788560 : static inline struct json_object_array *JC_ARRAY(struct json_object *jso)
      84             : {
      85     1788560 :   return (void *)jso;
      86             : }
      87     1675200 : static inline const struct json_object_array *JC_ARRAY_C(const struct json_object *jso)
      88             : {
      89     1675200 :   return (const void *)jso;
      90             : }
      91         934 : static inline struct json_object_boolean *JC_BOOL(struct json_object *jso)
      92             : {
      93         934 :   return (void *)jso;
      94             : }
      95         182 : static inline const struct json_object_boolean *JC_BOOL_C(const struct json_object *jso)
      96             : {
      97         182 :   return (const void *)jso;
      98             : }
      99        1849 : static inline struct json_object_double *JC_DOUBLE(struct json_object *jso)
     100             : {
     101        1849 :   return (void *)jso;
     102             : }
     103      295758 : static inline const struct json_object_double *JC_DOUBLE_C(const struct json_object *jso)
     104             : {
     105      295758 :   return (const void *)jso;
     106             : }
     107       56512 : static inline struct json_object_int *JC_INT(struct json_object *jso)
     108             : {
     109       56512 :   return (void *)jso;
     110             : }
     111      486990 : static inline const struct json_object_int *JC_INT_C(const struct json_object *jso)
     112             : {
     113      486990 :   return (const void *)jso;
     114             : }
     115     1684740 : static inline struct json_object_string *JC_STRING(struct json_object *jso)
     116             : {
     117     1684740 :   return (void *)jso;
     118             : }
     119      407446 : static inline const struct json_object_string *JC_STRING_C(const struct json_object *jso)
     120             : {
     121      407446 :   return (const void *)jso;
     122             : }
     123             : 
     124             : #define JC_CONCAT(a, b) a##b
     125             : #define JC_CONCAT3(a, b, c) a##b##c
     126             : 
     127             : #define JSON_OBJECT_NEW(jtype)                                                           \
     128             :   (struct JC_CONCAT(json_object_, jtype) *)json_object_new(                        \
     129             :       JC_CONCAT(json_type_, jtype), sizeof(struct JC_CONCAT(json_object_, jtype)), \
     130             :       &JC_CONCAT3(json_object_, jtype, _to_json_string))
     131             : 
     132             : static inline struct json_object *json_object_new(enum json_type o_type, size_t alloc_size,
     133             :                                                   json_object_to_json_string_fn *to_json_string);
     134             : 
     135             : static void json_object_object_delete(struct json_object *jso_base);
     136             : static void json_object_string_delete(struct json_object *jso);
     137             : static void json_object_array_delete(struct json_object *jso);
     138             : 
     139             : static json_object_to_json_string_fn json_object_object_to_json_string;
     140             : static json_object_to_json_string_fn json_object_boolean_to_json_string;
     141             : static json_object_to_json_string_fn json_object_double_to_json_string_default;
     142             : static json_object_to_json_string_fn json_object_int_to_json_string;
     143             : static json_object_to_json_string_fn json_object_string_to_json_string;
     144             : static json_object_to_json_string_fn json_object_array_to_json_string;
     145             : static json_object_to_json_string_fn _json_object_userdata_to_json_string;
     146             : 
     147             : #ifndef JSON_NORETURN
     148             : #if defined(_MSC_VER)
     149             : #define JSON_NORETURN __declspec(noreturn)
     150             : #elif defined(__OS400__)
     151             : #define JSON_NORETURN
     152             : #else
     153             : /* 'cold' attribute is for optimization, telling the computer this code
     154             :  * path is unlikely.
     155             :  */
     156             : #define JSON_NORETURN __attribute__((noreturn, cold))
     157             : #endif
     158             : #endif
     159             : /**
     160             :  * Abort and optionally print a message on standard error.
     161             :  * This should be used rather than assert() for unconditional abortion
     162             :  * (in particular for code paths which are never supposed to be run).
     163             :  * */
     164             : JSON_NORETURN static void json_abort(const char *message);
     165             : 
     166             : /* ref count debugging */
     167             : 
     168             : #ifdef REFCOUNT_DEBUG
     169             : 
     170             : static struct lh_table *json_object_table;
     171             : 
     172             : static void json_object_init(void) __attribute__((constructor));
     173             : static void json_object_init(void)
     174             : {
     175             :   MC_DEBUG("json_object_init: creating object table\n");
     176             :   json_object_table = lh_kptr_table_new(128, NULL);
     177             : }
     178             : 
     179             : static void json_object_fini(void) __attribute__((destructor));
     180             : static void json_object_fini(void)
     181             : {
     182             :   struct lh_entry *ent;
     183             :   if (MC_GET_DEBUG())
     184             :   {
     185             :     if (json_object_table->count)
     186             :     {
     187             :       MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
     188             :                json_object_table->count);
     189             :       lh_foreach(json_object_table, ent)
     190             :       {
     191             :         struct json_object *obj = (struct json_object *)lh_entry_v(ent);
     192             :         MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
     193             :       }
     194             :     }
     195             :   }
     196             :   MC_DEBUG("json_object_fini: freeing object table\n");
     197             :   lh_table_free(json_object_table);
     198             : }
     199             : #endif /* REFCOUNT_DEBUG */
     200             : 
     201             : /* helper for accessing the optimized string data component in json_object
     202             :  */
     203      407445 : static inline char *get_string_component_mutable(struct json_object *jso)
     204             : {
     205      407445 :   if (JC_STRING_C(jso)->len < 0)
     206             :   {
     207             :     /* Due to json_object_set_string(), we might have a pointer */
     208           0 :     return JC_STRING(jso)->c_string.pdata;
     209             :   }
     210      407445 :   return JC_STRING(jso)->c_string.idata;
     211             : }
     212      407445 : static inline const char *get_string_component(const struct json_object *jso)
     213             : {
     214      407445 :   return get_string_component_mutable((void *)(uintptr_t)(const void *)jso);
     215             : }
     216             : 
     217             : /* string escaping */
     218             : 
     219      118335 : static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int flags)
     220             : {
     221      118335 :   int pos = 0, start_offset = 0;
     222             :   unsigned char c;
     223     1318780 :   while (len)
     224             :   {
     225     1200440 :     --len;
     226     1200440 :     c = str[pos];
     227     1200440 :     switch (c)
     228             :     {
     229       33945 :     case '\b':
     230             :     case '\n':
     231             :     case '\r':
     232             :     case '\t':
     233             :     case '\f':
     234             :     case '"':
     235             :     case '\\':
     236             :     case '/':
     237       33945 :       if ((flags & JSON_C_TO_STRING_NOSLASHESCAPE) && c == '/')
     238             :       {
     239         920 :         pos++;
     240         920 :         break;
     241             :       }
     242             : 
     243       33025 :       if (pos - start_offset > 0)
     244       32186 :         printbuf_memappend(pb, str + start_offset, pos - start_offset);
     245             : 
     246       33025 :       if (c == '\b')
     247           0 :         printbuf_memappend(pb, "\\b", 2);
     248       33025 :       else if (c == '\n')
     249        7056 :         printbuf_memappend(pb, "\\n", 2);
     250       25969 :       else if (c == '\r')
     251           0 :         printbuf_memappend(pb, "\\r", 2);
     252       25969 :       else if (c == '\t')
     253           0 :         printbuf_memappend(pb, "\\t", 2);
     254       25969 :       else if (c == '\f')
     255           0 :         printbuf_memappend(pb, "\\f", 2);
     256       25969 :       else if (c == '"')
     257       21697 :         printbuf_memappend(pb, "\\\"", 2);
     258        4272 :       else if (c == '\\')
     259         183 :         printbuf_memappend(pb, "\\\\", 2);
     260        4089 :       else if (c == '/')
     261        4089 :         printbuf_memappend(pb, "\\/", 2);
     262             : 
     263       33025 :       start_offset = ++pos;
     264       33025 :       break;
     265     1166500 :     default:
     266     1166500 :       if (c < ' ')
     267             :       {
     268             :         char sbuf[7];
     269           0 :         if (pos - start_offset > 0)
     270           0 :           printbuf_memappend(pb, str + start_offset,
     271             :                              pos - start_offset);
     272           0 :         snprintf(sbuf, sizeof(sbuf), "\\u00%c%c", json_hex_chars[c >> 4],
     273           0 :                  json_hex_chars[c & 0xf]);
     274           0 :         printbuf_memappend_fast(pb, sbuf, (int)sizeof(sbuf) - 1);
     275           0 :         start_offset = ++pos;
     276             :       }
     277             :       else
     278     1166500 :         pos++;
     279             :     }
     280             :   }
     281      118335 :   if (pos - start_offset > 0)
     282      117725 :     printbuf_memappend(pb, str + start_offset, pos - start_offset);
     283      118335 :   return 0;
     284             : }
     285             : 
     286             : /* reference counting */
     287             : 
     288     3411050 : struct json_object *json_object_get(struct json_object *jso)
     289             : {
     290     3411050 :   if (!jso)
     291       53861 :     return jso;
     292             : 
     293             :   // Don't overflow the refcounter.
     294     3357190 :   assert(jso->_ref_count < UINT32_MAX);
     295             : 
     296             : #if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING)
     297             :   __sync_add_and_fetch(&jso->_ref_count, 1);
     298             : #else
     299     3357190 :   ++jso->_ref_count;
     300             : #endif
     301             : 
     302     3357190 :   return jso;
     303             : }
     304             : 
     305     8202620 : int json_object_put(struct json_object *jso)
     306             : {
     307     8202620 :   if (!jso)
     308     2045270 :     return 0;
     309             : 
     310             :   /* Avoid invalid free and crash explicitly instead of (silently)
     311             :    * segfaulting.
     312             :    */
     313     6157350 :   assert(jso->_ref_count > 0);
     314             : 
     315             : #if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING)
     316             :   /* Note: this only allow the refcount to remain correct
     317             :    * when multiple threads are adjusting it.  It is still an error
     318             :    * for a thread to decrement the refcount if it doesn't "own" it,
     319             :    * as that can result in the thread that loses the race to 0
     320             :    * operating on an already-freed object.
     321             :    */
     322             :   if (__sync_sub_and_fetch(&jso->_ref_count, 1) > 0)
     323             :     return 0;
     324             : #else
     325     6157350 :   if (--jso->_ref_count > 0)
     326     3357190 :     return 0;
     327             : #endif
     328             : 
     329     2800160 :   if (jso->_user_delete)
     330       60993 :     jso->_user_delete(jso, jso->_userdata);
     331     2800160 :   switch (jso->o_type)
     332             :   {
     333      441413 :   case json_type_object: json_object_object_delete(jso); break;
     334      359991 :   case json_type_array: json_object_array_delete(jso); break;
     335     1242780 :   case json_type_string: json_object_string_delete(jso); break;
     336      755976 :   default: json_object_generic_delete(jso); break;
     337             :   }
     338     2800160 :   return 1;
     339             : }
     340             : 
     341             : /* generic object construction and destruction parts */
     342             : 
     343     2800160 : static void json_object_generic_delete(struct json_object *jso)
     344             : {
     345             : #ifdef REFCOUNT_DEBUG
     346             :   MC_DEBUG("json_object_delete_%s: %p\n", json_type_to_name(jso->o_type), jso);
     347             :   lh_table_delete(json_object_table, jso);
     348             : #endif /* REFCOUNT_DEBUG */
     349     2800160 :   printbuf_free(jso->_pb);
     350     2800160 :   free(jso);
     351     2800160 : }
     352             : 
     353     2800160 : static inline struct json_object *json_object_new(enum json_type o_type, size_t alloc_size,
     354             :                                                   json_object_to_json_string_fn *to_json_string)
     355             : {
     356             :   struct json_object *jso;
     357             : 
     358     2800160 :   jso = (struct json_object *)malloc(alloc_size);
     359     2800160 :   if (!jso)
     360           0 :     return NULL;
     361             : 
     362     2800160 :   jso->o_type = o_type;
     363     2800160 :   jso->_ref_count = 1;
     364     2800160 :   jso->_to_json_string = to_json_string;
     365     2800160 :   jso->_pb = NULL;
     366     2800160 :   jso->_user_delete = NULL;
     367     2800160 :   jso->_userdata = NULL;
     368             :   //jso->...   // Type-specific fields must be set by caller
     369             : 
     370             : #ifdef REFCOUNT_DEBUG
     371             :   lh_table_insert(json_object_table, jso, jso);
     372             :   MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
     373             : #endif /* REFCOUNT_DEBUG */
     374     2800160 :   return jso;
     375             : }
     376             : 
     377             : /* type checking functions */
     378             : 
     379           0 : int json_object_is_type(const struct json_object *jso, enum json_type type)
     380             : {
     381           0 :   if (!jso)
     382           0 :     return (type == json_type_null);
     383           0 :   return (jso->o_type == type);
     384             : }
     385             : 
     386     5988060 : enum json_type json_object_get_type(const struct json_object *jso)
     387             : {
     388     5988060 :   if (!jso)
     389        1358 :     return json_type_null;
     390     5986700 :   return jso->o_type;
     391             : }
     392             : 
     393       27247 : void *json_object_get_userdata(json_object *jso)
     394             : {
     395       27247 :   return jso ? jso->_userdata : NULL;
     396             : }
     397             : 
     398       91730 : void json_object_set_userdata(json_object *jso, void *userdata, json_object_delete_fn *user_delete)
     399             : {
     400             :   // Can't return failure, so abort if we can't perform the operation.
     401       91730 :   assert(jso != NULL);
     402             : 
     403             :   // First, clean up any previously existing user info
     404       91730 :   if (jso->_user_delete)
     405           0 :     jso->_user_delete(jso, jso->_userdata);
     406             : 
     407       91730 :   jso->_userdata = userdata;
     408       91730 :   jso->_user_delete = user_delete;
     409       91730 : }
     410             : 
     411             : /* set a custom conversion to string */
     412             : 
     413       91730 : void json_object_set_serializer(json_object *jso, json_object_to_json_string_fn *to_string_func,
     414             :                                 void *userdata, json_object_delete_fn *user_delete)
     415             : {
     416       91730 :   json_object_set_userdata(jso, userdata, user_delete);
     417             : 
     418       91730 :   if (to_string_func == NULL)
     419             :   {
     420             :     // Reset to the standard serialization function
     421           0 :     switch (jso->o_type)
     422             :     {
     423           0 :     case json_type_null: jso->_to_json_string = NULL; break;
     424           0 :     case json_type_boolean:
     425           0 :       jso->_to_json_string = &json_object_boolean_to_json_string;
     426           0 :       break;
     427           0 :     case json_type_double:
     428           0 :       jso->_to_json_string = &json_object_double_to_json_string_default;
     429           0 :       break;
     430           0 :     case json_type_int: jso->_to_json_string = &json_object_int_to_json_string; break;
     431           0 :     case json_type_object:
     432           0 :       jso->_to_json_string = &json_object_object_to_json_string;
     433           0 :       break;
     434           0 :     case json_type_array:
     435           0 :       jso->_to_json_string = &json_object_array_to_json_string;
     436           0 :       break;
     437           0 :     case json_type_string:
     438           0 :       jso->_to_json_string = &json_object_string_to_json_string;
     439           0 :       break;
     440             :     }
     441           0 :     return;
     442             :   }
     443             : 
     444       91730 :   jso->_to_json_string = to_string_func;
     445             : }
     446             : 
     447             : /* extended conversion to string */
     448             : 
     449       28815 : const char *json_object_to_json_string_length(struct json_object *jso, int flags, size_t *length)
     450             : {
     451       28815 :   const char *r = NULL;
     452       28815 :   size_t s = 0;
     453             : 
     454       28815 :   if (!jso)
     455             :   {
     456           0 :     s = 4;
     457           0 :     r = "null";
     458             :   }
     459       28815 :   else if ((jso->_pb) || (jso->_pb = printbuf_new()))
     460             :   {
     461       28815 :     printbuf_reset(jso->_pb);
     462             : 
     463       28815 :     if (jso->_to_json_string(jso, jso->_pb, 0, flags) >= 0)
     464             :     {
     465       28815 :       s = (size_t)jso->_pb->bpos;
     466       28815 :       r = jso->_pb->buf;
     467             :     }
     468             :   }
     469             : 
     470       28815 :   if (length)
     471           0 :     *length = s;
     472       28815 :   return r;
     473             : }
     474             : 
     475       28815 : const char *json_object_to_json_string_ext(struct json_object *jso, int flags)
     476             : {
     477       28815 :   return json_object_to_json_string_length(jso, flags, NULL);
     478             : }
     479             : 
     480             : /* backwards-compatible conversion to string */
     481             : 
     482        9019 : const char *json_object_to_json_string(struct json_object *jso)
     483             : {
     484        9019 :   return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
     485             : }
     486             : 
     487      164290 : static void indent(struct printbuf *pb, int level, int flags)
     488             : {
     489      164290 :   if (flags & JSON_C_TO_STRING_PRETTY)
     490             :   {
     491       82007 :     if (flags & JSON_C_TO_STRING_PRETTY_TAB)
     492             :     {
     493           0 :       printbuf_memset(pb, -1, '\t', level);
     494             :     }
     495             :     else
     496             :     {
     497       82007 :       printbuf_memset(pb, -1, ' ', level * 2);
     498             :     }
     499             :   }
     500      164290 : }
     501             : 
     502             : /* json_object_object */
     503             : 
     504       38937 : static int json_object_object_to_json_string(struct json_object *jso, struct printbuf *pb,
     505             :                                              int level, int flags)
     506             : {
     507       38937 :   int had_children = 0;
     508             :   struct json_object_iter iter;
     509             : 
     510       38937 :   printbuf_strappend(pb, "{" /*}*/);
     511       38937 :   if (flags & JSON_C_TO_STRING_PRETTY)
     512       11929 :     printbuf_strappend(pb, "\n");
     513      122751 :   json_object_object_foreachC(jso, iter)
     514             :   {
     515       83814 :     if (had_children)
     516             :     {
     517       52629 :       printbuf_strappend(pb, ",");
     518       52629 :       if (flags & JSON_C_TO_STRING_PRETTY)
     519       31240 :         printbuf_strappend(pb, "\n");
     520             :     }
     521       83814 :     had_children = 1;
     522       83814 :     if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
     523       14424 :       printbuf_strappend(pb, " ");
     524       83814 :     indent(pb, level + 1, flags);
     525       83814 :     printbuf_strappend(pb, "\"");
     526       83814 :     json_escape_str(pb, iter.key, strlen(iter.key), flags);
     527       83814 :     if (flags & JSON_C_TO_STRING_SPACED)
     528       14424 :       printbuf_strappend(pb, "\": ");
     529             :     else
     530       69390 :       printbuf_strappend(pb, "\":");
     531       83814 :     if (iter.val == NULL)
     532        8401 :       printbuf_strappend(pb, "null");
     533       75413 :     else if (iter.val->_to_json_string(iter.val, pb, level + 1, flags) < 0)
     534           0 :       return -1;
     535             :   }
     536       38937 :   if (flags & JSON_C_TO_STRING_PRETTY)
     537             :   {
     538       11929 :     if (had_children)
     539       11165 :       printbuf_strappend(pb, "\n");
     540       11929 :     indent(pb, level, flags);
     541             :   }
     542       38937 :   if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
     543        7664 :     return printbuf_strappend(pb, /*{*/ " }");
     544             :   else
     545       31273 :     return printbuf_strappend(pb, /*{*/ "}");
     546             : }
     547             : 
     548     1400760 : static void json_object_lh_entry_free(struct lh_entry *ent)
     549             : {
     550     1400760 :   if (!ent->k_is_constant)
     551     1400760 :     free(lh_entry_k(ent));
     552     1400760 :   json_object_put((struct json_object *)lh_entry_v(ent));
     553     1400760 : }
     554             : 
     555      441413 : static void json_object_object_delete(struct json_object *jso_base)
     556             : {
     557      441413 :   lh_table_free(JC_OBJECT(jso_base)->c_object);
     558      441413 :   json_object_generic_delete(jso_base);
     559      441413 : }
     560             : 
     561      441413 : struct json_object *json_object_new_object(void)
     562             : {
     563      441413 :   struct json_object_object *jso = JSON_OBJECT_NEW(object);
     564      441413 :   if (!jso)
     565           0 :     return NULL;
     566      441413 :   jso->c_object =
     567      441413 :       lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES, &json_object_lh_entry_free);
     568      441413 :   if (!jso->c_object)
     569             :   {
     570           0 :     json_object_generic_delete(&jso->base);
     571           0 :     errno = ENOMEM;
     572           0 :     return NULL;
     573             :   }
     574      441413 :   return &jso->base;
     575             : }
     576             : 
     577      133696 : struct lh_table *json_object_get_object(const struct json_object *jso)
     578             : {
     579      133696 :   if (!jso)
     580           0 :     return NULL;
     581      133696 :   switch (jso->o_type)
     582             :   {
     583      133690 :   case json_type_object: return JC_OBJECT_C(jso)->c_object;
     584           6 :   default: return NULL;
     585             :   }
     586             : }
     587             : 
     588     1400900 : int json_object_object_add_ex(struct json_object *jso, const char *const key,
     589             :                               struct json_object *const val, const unsigned opts)
     590             : {
     591     1400900 :   struct json_object *existing_value = NULL;
     592             :   struct lh_entry *existing_entry;
     593             :   unsigned long hash;
     594             : 
     595     1400900 :   assert(json_object_get_type(jso) == json_type_object);
     596             : 
     597             :   // We lookup the entry and replace the value, rather than just deleting
     598             :   // and re-adding it, so the existing key remains valid.
     599     1400900 :   hash = lh_get_hash(JC_OBJECT(jso)->c_object, (const void *)key);
     600     1400900 :   existing_entry =
     601     1400900 :       (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW)
     602             :           ? NULL
     603     1400900 :           : lh_table_lookup_entry_w_hash(JC_OBJECT(jso)->c_object, (const void *)key, hash);
     604             : 
     605             :   // The caller must avoid creating loops in the object tree, but do a
     606             :   // quick check anyway to make sure we're not creating a trivial loop.
     607     1400900 :   if (jso == val)
     608           0 :     return -1;
     609             : 
     610     1400900 :   if (!existing_entry)
     611             :   {
     612     1400760 :     const void *const k =
     613     1400760 :         (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ? (const void *)key : strdup(key);
     614     1400760 :     if (k == NULL)
     615           0 :       return -1;
     616     1400760 :     return lh_table_insert_w_hash(JC_OBJECT(jso)->c_object, k, val, hash, opts);
     617             :   }
     618         138 :   existing_value = (json_object *)lh_entry_v(existing_entry);
     619         138 :   if (existing_value)
     620         138 :     json_object_put(existing_value);
     621         138 :   existing_entry->v = val;
     622         138 :   return 0;
     623             : }
     624             : 
     625     1400900 : int json_object_object_add(struct json_object *jso, const char *key, struct json_object *val)
     626             : {
     627     1400900 :   return json_object_object_add_ex(jso, key, val, 0);
     628             : }
     629             : 
     630           3 : int json_object_object_length(const struct json_object *jso)
     631             : {
     632           3 :   assert(json_object_get_type(jso) == json_type_object);
     633           3 :   return lh_table_length(JC_OBJECT_C(jso)->c_object);
     634             : }
     635             : 
     636        1245 : size_t json_c_object_sizeof(void)
     637             : {
     638        1245 :   return sizeof(struct json_object);
     639             : }
     640             : 
     641           0 : struct json_object *json_object_object_get(const struct json_object *jso, const char *key)
     642             : {
     643           0 :   struct json_object *result = NULL;
     644           0 :   json_object_object_get_ex(jso, key, &result);
     645           0 :   return result;
     646             : }
     647             : 
     648      945624 : json_bool json_object_object_get_ex(const struct json_object *jso, const char *key,
     649             :                                     struct json_object **value)
     650             : {
     651      945624 :   if (value != NULL)
     652      945624 :     *value = NULL;
     653             : 
     654      945624 :   if (NULL == jso)
     655         727 :     return 0;
     656             : 
     657      944897 :   switch (jso->o_type)
     658             :   {
     659      944505 :   case json_type_object:
     660      944505 :     return lh_table_lookup_ex(JC_OBJECT_C(jso)->c_object, (const void *)key,
     661             :                               (void **)value);
     662         392 :   default:
     663         392 :     if (value != NULL)
     664         392 :       *value = NULL;
     665         392 :     return 0;
     666             :   }
     667             : }
     668             : 
     669        9676 : void json_object_object_del(struct json_object *jso, const char *key)
     670             : {
     671        9676 :   assert(json_object_get_type(jso) == json_type_object);
     672        9676 :   lh_table_delete(JC_OBJECT(jso)->c_object, key);
     673        9676 : }
     674             : 
     675             : /* json_object_boolean */
     676             : 
     677         934 : static int json_object_boolean_to_json_string(struct json_object *jso, struct printbuf *pb,
     678             :                                               int level, int flags)
     679             : {
     680             :     (void)level;
     681             :     (void)flags;
     682         934 :   if (JC_BOOL(jso)->c_boolean)
     683         693 :     return printbuf_strappend(pb, "true");
     684         241 :   return printbuf_strappend(pb, "false");
     685             : }
     686             : 
     687       37700 : struct json_object *json_object_new_boolean(json_bool b)
     688             : {
     689       37700 :   struct json_object_boolean *jso = JSON_OBJECT_NEW(boolean);
     690       37700 :   if (!jso)
     691           0 :     return NULL;
     692       37700 :   jso->c_boolean = b;
     693       37700 :   return &jso->base;
     694             : }
     695             : 
     696          83 : json_bool json_object_get_boolean(const struct json_object *jso)
     697             : {
     698          83 :   if (!jso)
     699           3 :     return 0;
     700          80 :   switch (jso->o_type)
     701             :   {
     702          79 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
     703           0 :   case json_type_int:
     704           0 :     switch (JC_INT_C(jso)->cint_type)
     705             :     {
     706           0 :     case json_object_int_type_int64: return (JC_INT_C(jso)->cint.c_int64 != 0);
     707           0 :     case json_object_int_type_uint64: return (JC_INT_C(jso)->cint.c_uint64 != 0);
     708           0 :     default: json_abort("invalid cint_type");
     709             :     }
     710           0 :   case json_type_double: return (JC_DOUBLE_C(jso)->c_double != 0);
     711           1 :   case json_type_string: return (JC_STRING_C(jso)->len != 0);
     712           0 :   default: return 0;
     713             :   }
     714             : }
     715             : 
     716           0 : int json_object_set_boolean(struct json_object *jso, json_bool new_value)
     717             : {
     718           0 :   if (!jso || jso->o_type != json_type_boolean)
     719           0 :     return 0;
     720           0 :   JC_BOOL(jso)->c_boolean = new_value;
     721           0 :   return 1;
     722             : }
     723             : 
     724             : /* json_object_int */
     725             : 
     726       27485 : static int json_object_int_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
     727             :                                           int flags)
     728             : {
     729             :     (void)level;
     730             :     (void)flags;
     731             :   /* room for 19 digits, the sign char, and a null term */
     732             :   char sbuf[21];
     733       27485 :   if (JC_INT(jso)->cint_type == json_object_int_type_int64)
     734       27017 :     snprintf(sbuf, sizeof(sbuf), "%" PRId64, JC_INT(jso)->cint.c_int64);
     735             :   else
     736         468 :     snprintf(sbuf, sizeof(sbuf), "%" PRIu64, JC_INT(jso)->cint.c_uint64);
     737       27485 :   return printbuf_memappend(pb, sbuf, (int)strlen(sbuf));
     738             : }
     739             : 
     740       14859 : struct json_object *json_object_new_int(int32_t i)
     741             : {
     742       14859 :   return json_object_new_int64(i);
     743             : }
     744             : 
     745       22265 : int32_t json_object_get_int(const struct json_object *jso)
     746             : {
     747       22265 :   int64_t cint64=0;
     748             :   double cdouble;
     749             :   enum json_type o_type;
     750             : 
     751       22265 :   if (!jso)
     752           0 :     return 0;
     753             : 
     754       22265 :   o_type = jso->o_type;
     755       22265 :   if (o_type == json_type_int)
     756             :   {
     757       22190 :     const struct json_object_int *jsoint = JC_INT_C(jso);
     758       22190 :     if (jsoint->cint_type == json_object_int_type_int64)
     759             :     {
     760       22190 :       cint64 = jsoint->cint.c_int64;
     761             :     }
     762             :     else
     763             :     {
     764           0 :       if (jsoint->cint.c_uint64 >= INT64_MAX)
     765           0 :         cint64 = INT64_MAX;
     766             :       else
     767           0 :         cint64 = (int64_t)jsoint->cint.c_uint64;
     768             :     }
     769             :   }
     770          75 :   else if (o_type == json_type_string)
     771             :   {
     772             :     /*
     773             :      * Parse strings into 64-bit numbers, then use the
     774             :      * 64-to-32-bit number handling below.
     775             :      */
     776           1 :     if (json_parse_int64(get_string_component(jso), &cint64) != 0)
     777           1 :       return 0; /* whoops, it didn't work. */
     778           0 :     o_type = json_type_int;
     779             :   }
     780             : 
     781       22264 :   switch (o_type)
     782             :   {
     783       22190 :   case json_type_int:
     784             :     /* Make sure we return the correct values for out of range numbers. */
     785       22190 :     if (cint64 <= INT32_MIN)
     786           0 :       return INT32_MIN;
     787       22190 :     if (cint64 >= INT32_MAX)
     788           0 :       return INT32_MAX;
     789       22190 :     return (int32_t)cint64;
     790           0 :   case json_type_double:
     791           0 :     cdouble = JC_DOUBLE_C(jso)->c_double;
     792           0 :     if (cdouble <= INT32_MIN)
     793           0 :       return INT32_MIN;
     794           0 :     if (cdouble >= INT32_MAX)
     795           0 :       return INT32_MAX;
     796           0 :     return (int32_t)cdouble;
     797          74 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
     798           0 :   default: return 0;
     799             :   }
     800             : }
     801             : 
     802           0 : int json_object_set_int(struct json_object *jso, int new_value)
     803             : {
     804           0 :   return json_object_set_int64(jso, (int64_t)new_value);
     805             : }
     806             : 
     807      341422 : struct json_object *json_object_new_int64(int64_t i)
     808             : {
     809      341422 :   struct json_object_int *jso = JSON_OBJECT_NEW(int);
     810      341422 :   if (!jso)
     811           0 :     return NULL;
     812      341422 :   jso->cint.c_int64 = i;
     813      341422 :   jso->cint_type = json_object_int_type_int64;
     814      341422 :   return &jso->base;
     815             : }
     816             : 
     817         470 : struct json_object *json_object_new_uint64(uint64_t i)
     818             : {
     819         470 :   struct json_object_int *jso = JSON_OBJECT_NEW(int);
     820         470 :   if (!jso)
     821           0 :     return NULL;
     822         470 :   jso->cint.c_uint64 = i;
     823         470 :   jso->cint_type = json_object_int_type_uint64;
     824         470 :   return &jso->base;
     825             : }
     826             : 
     827       35919 : int64_t json_object_get_int64(const struct json_object *jso)
     828             : {
     829             :   int64_t cint;
     830             : 
     831       35919 :   if (!jso)
     832           0 :     return 0;
     833       35919 :   switch (jso->o_type)
     834             :   {
     835       35886 :   case json_type_int:
     836             :   {
     837       35886 :     const struct json_object_int *jsoint = JC_INT_C(jso);
     838       35886 :     switch (jsoint->cint_type)
     839             :     {
     840       35881 :     case json_object_int_type_int64: return jsoint->cint.c_int64;
     841           5 :     case json_object_int_type_uint64:
     842           5 :       if (jsoint->cint.c_uint64 >= INT64_MAX)
     843           2 :         return INT64_MAX;
     844           3 :       return (int64_t)jsoint->cint.c_uint64;
     845           0 :     default: json_abort("invalid cint_type");
     846             :     }
     847             :   }
     848           1 :   case json_type_double:
     849             :     // INT64_MAX can't be exactly represented as a double
     850             :     // so cast to tell the compiler it's ok to round up.
     851           1 :     if (JC_DOUBLE_C(jso)->c_double >= (double)INT64_MAX)
     852           0 :       return INT64_MAX;
     853           1 :     if (JC_DOUBLE_C(jso)->c_double <= INT64_MIN)
     854           0 :       return INT64_MIN;
     855           1 :     return (int64_t)JC_DOUBLE_C(jso)->c_double;
     856          21 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
     857          11 :   case json_type_string:
     858          11 :     if (json_parse_int64(get_string_component(jso), &cint) == 0)
     859          11 :       return cint;
     860             :     /* FALLTHRU */
     861           0 :   default: return 0;
     862             :   }
     863             : }
     864             : 
     865           0 : uint64_t json_object_get_uint64(const struct json_object *jso)
     866             : {
     867             :   uint64_t cuint;
     868             : 
     869           0 :   if (!jso)
     870           0 :     return 0;
     871           0 :   switch (jso->o_type)
     872             :   {
     873           0 :   case json_type_int:
     874             :   {
     875           0 :     const struct json_object_int *jsoint = JC_INT_C(jso);
     876           0 :     switch (jsoint->cint_type)
     877             :     {
     878           0 :     case json_object_int_type_int64:
     879           0 :       if (jsoint->cint.c_int64 < 0)
     880           0 :         return 0;
     881           0 :       return (uint64_t)jsoint->cint.c_int64;
     882           0 :     case json_object_int_type_uint64: return jsoint->cint.c_uint64;
     883           0 :     default: json_abort("invalid cint_type");
     884             :     }
     885             :   }
     886           0 :   case json_type_double:
     887             :     // UINT64_MAX can't be exactly represented as a double
     888             :     // so cast to tell the compiler it's ok to round up.
     889           0 :     if (JC_DOUBLE_C(jso)->c_double >= (double)UINT64_MAX)
     890           0 :       return UINT64_MAX;
     891           0 :     if (JC_DOUBLE_C(jso)->c_double < 0)
     892           0 :       return 0;
     893           0 :     return (uint64_t)JC_DOUBLE_C(jso)->c_double;
     894           0 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
     895           0 :   case json_type_string:
     896           0 :     if (json_parse_uint64(get_string_component(jso), &cuint) == 0)
     897           0 :       return cuint;
     898             :     /* FALLTHRU */
     899           0 :   default: return 0;
     900             :   }
     901             : }
     902             : 
     903           0 : int json_object_set_int64(struct json_object *jso, int64_t new_value)
     904             : {
     905           0 :   if (!jso || jso->o_type != json_type_int)
     906           0 :     return 0;
     907           0 :   JC_INT(jso)->cint.c_int64 = new_value;
     908           0 :   JC_INT(jso)->cint_type = json_object_int_type_int64;
     909           0 :   return 1;
     910             : }
     911             : 
     912           0 : int json_object_set_uint64(struct json_object *jso, uint64_t new_value)
     913             : {
     914           0 :   if (!jso || jso->o_type != json_type_int)
     915           0 :     return 0;
     916           0 :   JC_INT(jso)->cint.c_uint64 = new_value;
     917           0 :   JC_INT(jso)->cint_type = json_object_int_type_uint64;
     918           0 :   return 1;
     919             : }
     920             : 
     921           0 : int json_object_int_inc(struct json_object *jso, int64_t val)
     922             : {
     923             :   struct json_object_int *jsoint;
     924           0 :   if (!jso || jso->o_type != json_type_int)
     925           0 :     return 0;
     926           0 :   jsoint = JC_INT(jso);
     927           0 :   switch (jsoint->cint_type)
     928             :   {
     929           0 :   case json_object_int_type_int64:
     930           0 :     if (val > 0 && jsoint->cint.c_int64 > INT64_MAX - val)
     931             :     {
     932           0 :       jsoint->cint.c_uint64 = (uint64_t)jsoint->cint.c_int64 + (uint64_t)val;
     933           0 :       jsoint->cint_type = json_object_int_type_uint64;
     934             :     }
     935           0 :     else if (val < 0 && jsoint->cint.c_int64 < INT64_MIN - val)
     936             :     {
     937           0 :       jsoint->cint.c_int64 = INT64_MIN;
     938             :     }
     939             :     else
     940             :     {
     941           0 :       jsoint->cint.c_int64 += val;
     942             :     }
     943           0 :     return 1;
     944           0 :   case json_object_int_type_uint64:
     945           0 :     if (val > 0 && jsoint->cint.c_uint64 > UINT64_MAX - (uint64_t)val)
     946             :     {
     947           0 :       jsoint->cint.c_uint64 = UINT64_MAX;
     948             :     }
     949           0 :     else if (val < 0 && jsoint->cint.c_uint64 < (uint64_t)(-val))
     950             :     {
     951           0 :       jsoint->cint.c_int64 = (int64_t)jsoint->cint.c_uint64 + val;
     952           0 :       jsoint->cint_type = json_object_int_type_int64;
     953             :     }
     954           0 :     else if (val < 0 && jsoint->cint.c_uint64 >= (uint64_t)(-val))
     955             :     {
     956           0 :       jsoint->cint.c_uint64 -= (uint64_t)(-val);
     957             :     }
     958             :     else
     959             :     {
     960           0 :       jsoint->cint.c_uint64 += val;
     961             :     }
     962           0 :     return 1;
     963           0 :   default: json_abort("invalid cint_type");
     964             :   }
     965             : }
     966             : 
     967             : /* json_object_double */
     968             : 
     969             : #if defined(HAVE___THREAD)
     970             : // i.e. __thread or __declspec(thread)
     971             : static SPEC___THREAD char *tls_serialization_float_format = NULL;
     972             : #endif
     973             : static char *global_serialization_float_format = NULL;
     974             : 
     975           0 : int json_c_set_serialization_double_format(const char *double_format, int global_or_thread)
     976             : {
     977           0 :   if (global_or_thread == JSON_C_OPTION_GLOBAL)
     978             :   {
     979             : #if defined(HAVE___THREAD)
     980             :     if (tls_serialization_float_format)
     981             :     {
     982             :       free(tls_serialization_float_format);
     983             :       tls_serialization_float_format = NULL;
     984             :     }
     985             : #endif
     986           0 :     if (global_serialization_float_format)
     987           0 :       free(global_serialization_float_format);
     988           0 :     global_serialization_float_format = double_format ? strdup(double_format) : NULL;
     989             :   }
     990           0 :   else if (global_or_thread == JSON_C_OPTION_THREAD)
     991             :   {
     992             : #if defined(HAVE___THREAD)
     993             :     if (tls_serialization_float_format)
     994             :     {
     995             :       free(tls_serialization_float_format);
     996             :       tls_serialization_float_format = NULL;
     997             :     }
     998             :     tls_serialization_float_format = double_format ? strdup(double_format) : NULL;
     999             : #else
    1000           0 :     _json_c_set_last_err("json_c_set_option: not compiled with __thread support\n");
    1001           0 :     return -1;
    1002             : #endif
    1003             :   }
    1004             :   else
    1005             :   {
    1006           0 :     _json_c_set_last_err("json_c_set_option: invalid global_or_thread value: %d\n",
    1007             :                          global_or_thread);
    1008           0 :     return -1;
    1009             :   }
    1010           0 :   return 0;
    1011             : }
    1012             : 
    1013        1829 : static int json_object_double_to_json_string_format(struct json_object *jso, struct printbuf *pb,
    1014             :                                                     int level, int flags, const char *format)
    1015             : {
    1016             :     (void)level;
    1017        1829 :   struct json_object_double *jsodbl = JC_DOUBLE(jso);
    1018             :   char buf[128], *p, *q;
    1019             :   int size;
    1020             :   /* Although JSON RFC does not support
    1021             :    * NaN or Infinity as numeric values
    1022             :    * ECMA 262 section 9.8.1 defines
    1023             :    * how to handle these cases as strings
    1024             :    */
    1025        1829 :   if (CPLIsNan(jsodbl->c_double))
    1026             :   {
    1027           0 :     size = snprintf(buf, sizeof(buf), "NaN");
    1028             :   }
    1029        1829 :   else if (CPLIsInf(jsodbl->c_double))
    1030             :   {
    1031           0 :     if (jsodbl->c_double > 0)
    1032           0 :       size = snprintf(buf, sizeof(buf), "Infinity");
    1033             :     else
    1034           0 :       size = snprintf(buf, sizeof(buf), "-Infinity");
    1035             :   }
    1036             :   else
    1037             :   {
    1038        1829 :     const char *std_format = "%.17g";
    1039        1829 :     int format_drops_decimals = 0;
    1040        1829 :     int looks_numeric = 0;
    1041             : 
    1042        1829 :     if (!format)
    1043             :     {
    1044             : #if defined(HAVE___THREAD)
    1045             :       if (tls_serialization_float_format)
    1046             :         format = tls_serialization_float_format;
    1047             :       else
    1048             : #endif
    1049        1829 :           if (global_serialization_float_format)
    1050           0 :         format = global_serialization_float_format;
    1051             :       else
    1052        1829 :         format = std_format;
    1053             :     }
    1054        1829 :     size = snprintf(buf, sizeof(buf), format, jsodbl->c_double);
    1055             : 
    1056        1829 :     if (size < 0)
    1057           0 :       return -1;
    1058             : 
    1059        1829 :     p = strchr(buf, ',');
    1060        1829 :     if (p)
    1061           0 :       *p = '.';
    1062             :     else
    1063        1829 :       p = strchr(buf, '.');
    1064             : 
    1065        1829 :     if (format == std_format || strstr(format, ".0f") == NULL)
    1066        1829 :       format_drops_decimals = 1;
    1067             : 
    1068        1829 :     looks_numeric = /* Looks like *some* kind of number */
    1069        1884 :         isdigit((unsigned char)buf[0]) ||
    1070          55 :         (size > 1 && buf[0] == '-' && isdigit((unsigned char)buf[1]));
    1071             : 
    1072        1829 :     if (size < (int)sizeof(buf) - 2 && looks_numeric && !p && /* Has no decimal point */
    1073        1322 :         strchr(buf, 'e') == NULL && /* Not scientific notation */
    1074             :         format_drops_decimals)
    1075             :     {
    1076             :       // Ensure it looks like a float, even if snprintf didn't,
    1077             :       //  unless a custom format is set to omit the decimal.
    1078        1322 :       strcat(buf, ".0");
    1079        1322 :       size += 2;
    1080             :     }
    1081        1829 :     if (p && (flags & JSON_C_TO_STRING_NOZERO))
    1082             :     {
    1083             :       /* last useful digit, always keep 1 zero */
    1084           0 :       p++;
    1085           0 :       for (q = p; *q; q++)
    1086             :       {
    1087           0 :         if (*q != '0')
    1088           0 :           p = q;
    1089             :       }
    1090             :       /* drop trailing zeroes */
    1091           0 :       if (*p != 0)
    1092           0 :         *(++p) = 0;
    1093           0 :       size = (int)(p - buf);
    1094             :     }
    1095             :   }
    1096             :   // although unlikely, snprintf can fail
    1097        1829 :   if (size < 0)
    1098           0 :     return -1;
    1099             : 
    1100        1829 :   if (size >= (int)sizeof(buf))
    1101             :     // The standard formats are guaranteed not to overrun the buffer,
    1102             :     // but if a custom one happens to do so, just silently truncate.
    1103           0 :     size = sizeof(buf) - 1;
    1104        1829 :   printbuf_memappend(pb, buf, size);
    1105        1829 :   return size;
    1106             : }
    1107             : 
    1108        1829 : static int json_object_double_to_json_string_default(struct json_object *jso, struct printbuf *pb,
    1109             :                                                      int level, int flags)
    1110             : {
    1111        1829 :   return json_object_double_to_json_string_format(jso, pb, level, flags, NULL);
    1112             : }
    1113             : 
    1114           0 : int json_object_double_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
    1115             :                                       int flags)
    1116             : {
    1117           0 :   return json_object_double_to_json_string_format(jso, pb, level, flags,
    1118           0 :                                                   (const char *)jso->_userdata);
    1119             : }
    1120             : 
    1121      376384 : struct json_object *json_object_new_double(double d)
    1122             : {
    1123      376384 :   struct json_object_double *jso = JSON_OBJECT_NEW(double);
    1124      376384 :   if (!jso)
    1125           0 :     return NULL;
    1126      376384 :   jso->base._to_json_string = &json_object_double_to_json_string_default;
    1127      376384 :   jso->c_double = d;
    1128      376384 :   return &jso->base;
    1129             : }
    1130             : 
    1131       60993 : struct json_object *json_object_new_double_s(double d, const char *ds)
    1132             : {
    1133             :   char *new_ds;
    1134       60993 :   struct json_object *jso = json_object_new_double(d);
    1135       60993 :   if (!jso)
    1136           0 :     return NULL;
    1137             : 
    1138       60993 :   new_ds = strdup(ds);
    1139       60993 :   if (!new_ds)
    1140             :   {
    1141           0 :     json_object_generic_delete(jso);
    1142           0 :     errno = ENOMEM;
    1143           0 :     return NULL;
    1144             :   }
    1145       60993 :   json_object_set_serializer(jso, _json_object_userdata_to_json_string, new_ds,
    1146             :                              json_object_free_userdata);
    1147       60993 :   return jso;
    1148             : }
    1149             : 
    1150             : /*
    1151             :  * A wrapper around json_object_userdata_to_json_string() used only
    1152             :  * by json_object_new_double_s() just so json_object_set_double() can
    1153             :  * detect when it needs to reset the serializer to the default.
    1154             :  */
    1155        5882 : static int _json_object_userdata_to_json_string(struct json_object *jso, struct printbuf *pb,
    1156             :                                                 int level, int flags)
    1157             : {
    1158        5882 :   return json_object_userdata_to_json_string(jso, pb, level, flags);
    1159             : }
    1160             : 
    1161        5882 : int json_object_userdata_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
    1162             :                                         int flags)
    1163             : {
    1164             :     (void)level;
    1165             :     (void)flags;
    1166        5882 :   int userdata_len = (int)strlen((const char *)jso->_userdata);
    1167        5882 :   printbuf_memappend(pb, (const char *)jso->_userdata, userdata_len);
    1168        5882 :   return userdata_len;
    1169             : }
    1170             : 
    1171       60993 : void json_object_free_userdata(struct json_object *jso, void *userdata)
    1172             : {
    1173             :     (void)jso;
    1174       60993 :   free(userdata);
    1175       60993 : }
    1176             : 
    1177      510268 : double json_object_get_double(const struct json_object *jso)
    1178             : {
    1179             :   double cdouble;
    1180      510268 :   char *errPtr = NULL;
    1181             : 
    1182      510268 :   if (!jso)
    1183          48 :     return 0.0;
    1184      510220 :   switch (jso->o_type)
    1185             :   {
    1186      295755 :   case json_type_double: return JC_DOUBLE_C(jso)->c_double;
    1187      214457 :   case json_type_int:
    1188      214457 :     switch (JC_INT_C(jso)->cint_type)
    1189             :     {
    1190      214457 :     case json_object_int_type_int64: return JC_INT_C(jso)->cint.c_int64;
    1191           0 :     case json_object_int_type_uint64: return JC_INT_C(jso)->cint.c_uint64;
    1192           0 :     default: json_abort("invalid cint_type");
    1193             :     }
    1194           8 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
    1195           0 :   case json_type_string:
    1196           0 :     errno = 0;
    1197           0 :     cdouble = CPLStrtod(get_string_component(jso), &errPtr);
    1198             : 
    1199             :     /* if conversion stopped at the first character, return 0.0 */
    1200           0 :     if (errPtr == get_string_component(jso))
    1201             :     {
    1202           0 :       errno = EINVAL;
    1203           0 :       return 0.0;
    1204             :     }
    1205             : 
    1206             :     /*
    1207             :      * Check that the conversion terminated on something sensible
    1208             :      *
    1209             :      * For example, { "pay" : 123AB } would parse as 123.
    1210             :      */
    1211           0 :     if (*errPtr != '\0')
    1212             :     {
    1213           0 :       errno = EINVAL;
    1214           0 :       return 0.0;
    1215             :     }
    1216             : 
    1217             :     /*
    1218             :      * If strtod encounters a string which would exceed the
    1219             :      * capacity of a double, it returns +/- HUGE_VAL and sets
    1220             :      * errno to ERANGE. But +/- HUGE_VAL is also a valid result
    1221             :      * from a conversion, so we need to check errno.
    1222             :      *
    1223             :      * Underflow also sets errno to ERANGE, but it returns 0 in
    1224             :      * that case, which is what we will return anyway.
    1225             :      *
    1226             :      * See CERT guideline ERR30-C
    1227             :      */
    1228           0 :     if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) && (ERANGE == errno))
    1229           0 :       cdouble = 0.0;
    1230           0 :     return cdouble;
    1231           0 :   default: errno = EINVAL; return 0.0;
    1232             :   }
    1233             : }
    1234             : 
    1235           0 : int json_object_set_double(struct json_object *jso, double new_value)
    1236             : {
    1237           0 :   if (!jso || jso->o_type != json_type_double)
    1238           0 :     return 0;
    1239           0 :   JC_DOUBLE(jso)->c_double = new_value;
    1240           0 :   if (jso->_to_json_string == &_json_object_userdata_to_json_string)
    1241           0 :     json_object_set_serializer(jso, NULL, NULL, NULL);
    1242           0 :   return 1;
    1243             : }
    1244             : 
    1245             : /* json_object_string */
    1246             : 
    1247       34521 : static int json_object_string_to_json_string(struct json_object *jso, struct printbuf *pb,
    1248             :                                              int level, int flags)
    1249             : {
    1250             :     (void)level;
    1251       34521 :   ssize_t len = JC_STRING(jso)->len;
    1252       34521 :   printbuf_strappend(pb, "\"");
    1253       34521 :   json_escape_str(pb, get_string_component(jso), len < 0 ? -(ssize_t)len : len, flags);
    1254       34521 :   printbuf_strappend(pb, "\"");
    1255       34521 :   return 0;
    1256             : }
    1257             : 
    1258     1242780 : static void json_object_string_delete(struct json_object *jso)
    1259             : {
    1260     1242780 :   if (JC_STRING(jso)->len < 0)
    1261           0 :     free(JC_STRING(jso)->c_string.pdata);
    1262     1242780 :   json_object_generic_delete(jso);
    1263     1242780 : }
    1264             : 
    1265     1242780 : static struct json_object *_json_object_new_string(const char *s, const size_t len)
    1266             : {
    1267             :   size_t objsize;
    1268             :   struct json_object_string *jso;
    1269             : 
    1270             :   /*
    1271             :      * Structures           Actual memory layout
    1272             :      * -------------------  --------------------
    1273             :    * [json_object_string  [json_object_string
    1274             :    *  [json_object]        [json_object]
    1275             :      *  ...other fields...   ...other fields...
    1276             :    *  c_string]            len
    1277             :      *                       bytes
    1278             :    *                       of
    1279             :    *                       string
    1280             :    *                       data
    1281             :      *                       \0]
    1282             :    */
    1283     1242780 :   if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1))
    1284           0 :     return NULL;
    1285     1242780 :   objsize = (sizeof(*jso) - sizeof(jso->c_string)) + len + 1;
    1286     1242780 :   if (len < sizeof(void *))
    1287             :     // We need a minimum size to support json_object_set_string() mutability
    1288             :     // so we can stuff a pointer into pdata :(
    1289      288876 :     objsize += sizeof(void *) - len;
    1290             : 
    1291     1242780 :   jso = (struct json_object_string *)json_object_new(json_type_string, objsize,
    1292             :                                                      &json_object_string_to_json_string);
    1293             : 
    1294     1242780 :   if (!jso)
    1295           0 :     return NULL;
    1296     1242780 :   jso->len = len;
    1297             :   char* strdata;
    1298     1242780 :   uintptr_t strdata_addr = (uintptr_t)&(jso->c_string.idata);
    1299     1242780 :   memcpy(&strdata, &(strdata_addr), sizeof(char*));
    1300     1242780 :   memcpy(strdata, s, len);
    1301     1242780 :   strdata[len] = '\0';
    1302     1242780 :   return &jso->base;
    1303             : }
    1304             : 
    1305       49953 : struct json_object *json_object_new_string(const char *s)
    1306             : {
    1307       49953 :   return _json_object_new_string(s, strlen(s));
    1308             : }
    1309             : 
    1310     1192820 : struct json_object *json_object_new_string_len(const char *s, const int len)
    1311             : {
    1312     1192820 :   return _json_object_new_string(s, len);
    1313             : }
    1314             : 
    1315      380977 : const char *json_object_get_string(struct json_object *jso)
    1316             : {
    1317      380977 :   if (!jso)
    1318          24 :     return NULL;
    1319      380953 :   switch (jso->o_type)
    1320             :   {
    1321      372867 :   case json_type_string: return get_string_component(jso);
    1322        8086 :   default: return json_object_to_json_string(jso);
    1323             :   }
    1324             : }
    1325           0 : int json_object_get_string_len(const struct json_object *jso)
    1326             : {
    1327             :   ssize_t len;
    1328           0 :   if (!jso)
    1329           0 :     return 0;
    1330           0 :   switch (jso->o_type)
    1331             :   {
    1332           0 :   case json_type_string:
    1333             :   {
    1334           0 :     len = JC_STRING_C(jso)->len;
    1335           0 :     return (len < 0) ? (int)(-(ssize_t)len) : (int)len;
    1336             :   }
    1337           0 :   default: return 0;
    1338             :   }
    1339             : }
    1340             : 
    1341           0 : static int _json_object_set_string_len(json_object *jso, const char *s, size_t len)
    1342             : {
    1343             :   char *dstbuf;
    1344             :   ssize_t curlen;
    1345             :   ssize_t newlen;
    1346           0 :   if (jso == NULL || jso->o_type != json_type_string)
    1347           0 :     return 0;
    1348             : 
    1349           0 :   if (len >= SSIZE_T_MAX - 1)
    1350             :     // jso->len is a signed ssize_t, so it can't hold the
    1351             :     // full size_t range.
    1352           0 :     return 0;
    1353             : 
    1354           0 :   dstbuf = get_string_component_mutable(jso);
    1355           0 :   curlen = JC_STRING(jso)->len;
    1356           0 :   if (curlen < 0)
    1357           0 :     curlen = -curlen;
    1358           0 :   newlen = len;
    1359             : 
    1360           0 :   if ((ssize_t)len > curlen)
    1361             :   {
    1362             :     // We have no way to return the new ptr from realloc(jso, newlen)
    1363             :     // and we have no way of knowing whether there's extra room available
    1364             :     // so we need to stuff a pointer in to pdata :(
    1365           0 :     dstbuf = (char *)malloc(len + 1);
    1366           0 :     if (dstbuf == NULL)
    1367           0 :       return 0;
    1368           0 :     if (JC_STRING(jso)->len < 0)
    1369           0 :       free(JC_STRING(jso)->c_string.pdata);
    1370           0 :     JC_STRING(jso)->c_string.pdata = dstbuf;
    1371           0 :     newlen = -(ssize_t)len;
    1372             :   }
    1373           0 :   else if (JC_STRING(jso)->len < 0)
    1374             :   {
    1375             :     // We've got enough room in the separate allocated buffer,
    1376             :     // so use it as-is and continue to indicate that pdata is used.
    1377           0 :     newlen = -(ssize_t)len;
    1378             :   }
    1379             : 
    1380           0 :   memcpy(dstbuf, (const void *)s, len);
    1381           0 :   dstbuf[len] = '\0';
    1382           0 :   JC_STRING(jso)->len = newlen;
    1383           0 :   return 1;
    1384             : }
    1385             : 
    1386           0 : int json_object_set_string(json_object *jso, const char *s)
    1387             : {
    1388           0 :   return _json_object_set_string_len(jso, s, strlen(s));
    1389             : }
    1390             : 
    1391           0 : int json_object_set_string_len(json_object *jso, const char *s, int len)
    1392             : {
    1393           0 :   return _json_object_set_string_len(jso, s, len);
    1394             : }
    1395             : 
    1396             : /* json_object_array */
    1397             : 
    1398       26216 : static int json_object_array_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
    1399             :                                             int flags)
    1400             : {
    1401       26216 :   int had_children = 0;
    1402             :   size_t ii;
    1403             : 
    1404       26216 :   printbuf_strappend(pb, "[");
    1405       26216 :   if (flags & JSON_C_TO_STRING_PRETTY)
    1406        8315 :     printbuf_strappend(pb, "\n");
    1407       86448 :   for (ii = 0; ii < json_object_array_length(jso); ii++)
    1408             :   {
    1409             :     struct json_object *val;
    1410       60232 :     if (had_children)
    1411             :     {
    1412       34889 :       printbuf_strappend(pb, ",");
    1413       34889 :       if (flags & JSON_C_TO_STRING_PRETTY)
    1414       11449 :         printbuf_strappend(pb, "\n");
    1415             :     }
    1416       60232 :     had_children = 1;
    1417       60232 :     if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
    1418       32135 :       printbuf_strappend(pb, " ");
    1419       60232 :     indent(pb, level + 1, flags);
    1420       60232 :     val = json_object_array_get_idx(jso, ii);
    1421       60232 :     if (val == NULL)
    1422        1406 :       printbuf_strappend(pb, "null");
    1423       58826 :     else if (val->_to_json_string(val, pb, level + 1, flags) < 0)
    1424           0 :       return -1;
    1425             :   }
    1426       26216 :   if (flags & JSON_C_TO_STRING_PRETTY)
    1427             :   {
    1428        8315 :     if (had_children)
    1429        7909 :       printbuf_strappend(pb, "\n");
    1430        8315 :     indent(pb, level, flags);
    1431             :   }
    1432             : 
    1433       26216 :   if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
    1434       13116 :     return printbuf_strappend(pb, " ]");
    1435       13100 :   return printbuf_strappend(pb, "]");
    1436             : }
    1437             : 
    1438     1280100 : static void json_object_array_entry_free(void *data)
    1439             : {
    1440     1280100 :   json_object_put((struct json_object *)data);
    1441     1280100 : }
    1442             : 
    1443      359991 : static void json_object_array_delete(struct json_object *jso)
    1444             : {
    1445      359991 :   array_list_free(JC_ARRAY(jso)->c_array);
    1446      359991 :   json_object_generic_delete(jso);
    1447      359991 : }
    1448             : 
    1449      359991 : struct json_object *json_object_new_array(void)
    1450             : {
    1451      359991 :   return json_object_new_array_ext(ARRAY_LIST_DEFAULT_SIZE);
    1452             : }
    1453      359991 : struct json_object *json_object_new_array_ext(int initial_size)
    1454             : {
    1455      359991 :   struct json_object_array *jso = JSON_OBJECT_NEW(array);
    1456      359991 :   if (!jso)
    1457           0 :     return NULL;
    1458      359991 :   jso->c_array = array_list_new2(&json_object_array_entry_free, initial_size);
    1459      359991 :   if (jso->c_array == NULL)
    1460             :   {
    1461           0 :     free(jso);
    1462           0 :     return NULL;
    1463             :   }
    1464      359991 :   return &jso->base;
    1465             : }
    1466             : 
    1467           0 : struct array_list *json_object_get_array(const struct json_object *jso)
    1468             : {
    1469           0 :   if (!jso)
    1470           0 :     return NULL;
    1471           0 :   switch (jso->o_type)
    1472             :   {
    1473           0 :   case json_type_array: return JC_ARRAY_C(jso)->c_array;
    1474           0 :   default: return NULL;
    1475             :   }
    1476             : }
    1477             : 
    1478           0 : void json_object_array_sort(struct json_object *jso, int (*sort_fn)(const void *, const void *))
    1479             : {
    1480           0 :   assert(json_object_get_type(jso) == json_type_array);
    1481           0 :   array_list_sort(JC_ARRAY(jso)->c_array, sort_fn);
    1482           0 : }
    1483             : 
    1484           0 : struct json_object *json_object_array_bsearch(const struct json_object *key,
    1485             :                                               const struct json_object *jso,
    1486             :                                               int (*sort_fn)(const void *, const void *))
    1487             : {
    1488             :   struct json_object **result;
    1489             : 
    1490           0 :   assert(json_object_get_type(jso) == json_type_array);
    1491           0 :   result = (struct json_object **)array_list_bsearch((const void **)(void *)&key,
    1492           0 :                                                      JC_ARRAY_C(jso)->c_array, sort_fn);
    1493             : 
    1494           0 :   if (!result)
    1495           0 :     return NULL;
    1496           0 :   return *result;
    1497             : }
    1498             : 
    1499      610304 : size_t json_object_array_length(const struct json_object *jso)
    1500             : {
    1501      610304 :   assert(json_object_get_type(jso) == json_type_array);
    1502      609954 :   return array_list_length(JC_ARRAY_C(jso)->c_array);
    1503             : }
    1504             : 
    1505     1281570 : int json_object_array_add(struct json_object *jso, struct json_object *val)
    1506             : {
    1507     1281570 :   assert(json_object_get_type(jso) == json_type_array);
    1508     1281570 :   return array_list_add(JC_ARRAY(jso)->c_array, val);
    1509             : }
    1510             : 
    1511           0 : int json_object_array_put_idx(struct json_object *jso, size_t idx, struct json_object *val)
    1512             : {
    1513           0 :   assert(json_object_get_type(jso) == json_type_array);
    1514           0 :   return array_list_put_idx(JC_ARRAY(jso)->c_array, idx, val);
    1515             : }
    1516             : 
    1517           0 : int json_object_array_del_idx(struct json_object *jso, size_t idx, size_t count)
    1518             : {
    1519           0 :   assert(json_object_get_type(jso) == json_type_array);
    1520           0 :   return array_list_del_idx(JC_ARRAY(jso)->c_array, idx, count);
    1521             : }
    1522             : 
    1523     1065440 : struct json_object *json_object_array_get_idx(const struct json_object *jso, size_t idx)
    1524             : {
    1525     1065440 :   assert(json_object_get_type(jso) == json_type_array);
    1526     1065440 :   return (struct json_object *)array_list_get_idx(JC_ARRAY_C(jso)->c_array, idx);
    1527             : }
    1528             : 
    1529           0 : static int json_array_equal(struct json_object *jso1, struct json_object *jso2)
    1530             : {
    1531             :   size_t len, i;
    1532             : 
    1533           0 :   len = json_object_array_length(jso1);
    1534           0 :   if (len != json_object_array_length(jso2))
    1535           0 :     return 0;
    1536             : 
    1537           0 :   for (i = 0; i < len; i++)
    1538             :   {
    1539           0 :     if (!json_object_equal(json_object_array_get_idx(jso1, i),
    1540             :                            json_object_array_get_idx(jso2, i)))
    1541           0 :       return 0;
    1542             :   }
    1543           0 :   return 1;
    1544             : }
    1545             : 
    1546      146993 : int json_object_array_shrink(struct json_object *jso, int empty_slots)
    1547             : {
    1548      146993 :   if (empty_slots < 0)
    1549           0 :     json_abort("json_object_array_shrink called with negative empty_slots");
    1550      146993 :   return array_list_shrink(JC_ARRAY(jso)->c_array, empty_slots);
    1551             : }
    1552             : 
    1553           0 : struct json_object *json_object_new_null(void)
    1554             : {
    1555           0 :   return NULL;
    1556             : }
    1557             : 
    1558           0 : static int json_object_all_values_equal(struct json_object *jso1, struct json_object *jso2)
    1559             : {
    1560             :   struct json_object_iter iter;
    1561             :   struct json_object *sub;
    1562             : 
    1563           0 :   assert(json_object_get_type(jso1) == json_type_object);
    1564           0 :   assert(json_object_get_type(jso2) == json_type_object);
    1565             :   /* Iterate over jso1 keys and see if they exist and are equal in jso2 */
    1566           0 :   json_object_object_foreachC(jso1, iter)
    1567             :   {
    1568           0 :     if (!lh_table_lookup_ex(JC_OBJECT(jso2)->c_object, (void *)iter.key,
    1569             :                             (void **)(void *)&sub))
    1570           0 :       return 0;
    1571           0 :     if (!json_object_equal(iter.val, sub))
    1572           0 :       return 0;
    1573             :   }
    1574             : 
    1575             :   /* Iterate over jso2 keys to see if any exist that are not in jso1 */
    1576           0 :   json_object_object_foreachC(jso2, iter)
    1577             :   {
    1578           0 :     if (!lh_table_lookup_ex(JC_OBJECT(jso1)->c_object, (void *)iter.key,
    1579             :                             (void **)(void *)&sub))
    1580           0 :       return 0;
    1581             :   }
    1582             : 
    1583           0 :   return 1;
    1584             : }
    1585             : 
    1586           0 : int json_object_equal(struct json_object *jso1, struct json_object *jso2)
    1587             : {
    1588           0 :   if (jso1 == jso2)
    1589           0 :     return 1;
    1590             : 
    1591           0 :   if (!jso1 || !jso2)
    1592           0 :     return 0;
    1593             : 
    1594           0 :   if (jso1->o_type != jso2->o_type)
    1595           0 :     return 0;
    1596             : 
    1597           0 :   switch (jso1->o_type)
    1598             :   {
    1599           0 :   case json_type_boolean: return (JC_BOOL(jso1)->c_boolean == JC_BOOL(jso2)->c_boolean);
    1600             : 
    1601           0 :   case json_type_double: return (JC_DOUBLE(jso1)->c_double == JC_DOUBLE(jso2)->c_double);
    1602             : 
    1603           0 :   case json_type_int:
    1604             :   {
    1605           0 :     struct json_object_int *int1 = JC_INT(jso1);
    1606           0 :     struct json_object_int *int2 = JC_INT(jso2);
    1607           0 :     if (int1->cint_type == json_object_int_type_int64)
    1608             :     {
    1609           0 :       if (int2->cint_type == json_object_int_type_int64)
    1610           0 :         return (int1->cint.c_int64 == int2->cint.c_int64);
    1611           0 :       if (int1->cint.c_int64 < 0)
    1612           0 :         return 0;
    1613           0 :       return ((uint64_t)int1->cint.c_int64 == int2->cint.c_uint64);
    1614             :     }
    1615             :     // else jso1 is a uint64
    1616           0 :     if (int2->cint_type == json_object_int_type_uint64)
    1617           0 :       return (int1->cint.c_uint64 == int2->cint.c_uint64);
    1618           0 :     if (int2->cint.c_int64 < 0)
    1619           0 :       return 0;
    1620           0 :     return (int1->cint.c_uint64 == (uint64_t)int2->cint.c_int64);
    1621             :   }
    1622             : 
    1623           0 :   case json_type_string:
    1624             :   {
    1625           0 :     return (json_object_get_string_len(jso1) == json_object_get_string_len(jso2) &&
    1626           0 :             memcmp(get_string_component(jso1), get_string_component(jso2),
    1627           0 :                    json_object_get_string_len(jso1)) == 0);
    1628             :   }
    1629             : 
    1630           0 :   case json_type_object: return json_object_all_values_equal(jso1, jso2);
    1631             : 
    1632           0 :   case json_type_array: return json_array_equal(jso1, jso2);
    1633             : 
    1634           0 :   case json_type_null: return 1;
    1635             :   };
    1636             : 
    1637           0 :   return 0;
    1638             : }
    1639             : 
    1640         842 : static int json_object_copy_serializer_data(struct json_object *src, struct json_object *dst)
    1641             : {
    1642         842 :   if (!src->_userdata && !src->_user_delete)
    1643         841 :     return 0;
    1644             : 
    1645           1 :   if (dst->_to_json_string == json_object_userdata_to_json_string ||
    1646           1 :       dst->_to_json_string == _json_object_userdata_to_json_string)
    1647             :   {
    1648           0 :     assert(src->_userdata);
    1649           0 :     dst->_userdata = strdup(src->_userdata);
    1650             :   }
    1651             :   // else if ... other supported serializers ...
    1652             :   else
    1653             :   {
    1654             :         void* func_ptr;
    1655           1 :         memcpy(&func_ptr, &(dst->_to_json_string), sizeof(void*));
    1656           1 :     _json_c_set_last_err(
    1657             :         "json_object_deep_copy: unable to copy unknown serializer data: %p\n",
    1658             :         func_ptr);
    1659           1 :     return -1;
    1660             :   }
    1661           0 :   dst->_user_delete = src->_user_delete;
    1662           0 :   return 0;
    1663             : }
    1664             : 
    1665             : /**
    1666             :  * The default shallow copy implementation.  Simply creates a new object of the same
    1667             :  * type but does *not* copy over _userdata nor retain any custom serializer.
    1668             :  * If custom serializers are in use, json_object_deep_copy() must be passed a shallow copy
    1669             :  * implementation that is aware of how to copy them.
    1670             :  *
    1671             :  * This always returns -1 or 1.  It will never return 2 since it does not copy the serializer.
    1672             :  */
    1673         842 : int json_c_shallow_copy_default(json_object *src, json_object *parent, const char *key,
    1674             :                                 size_t index, json_object **dst)
    1675             : {
    1676             :     (void)parent;
    1677             :     (void)key;
    1678             :     (void)index;
    1679         842 :   switch (src->o_type)
    1680             :   {
    1681           0 :   case json_type_boolean: *dst = json_object_new_boolean(JC_BOOL(src)->c_boolean); break;
    1682             : 
    1683          20 :   case json_type_double: *dst = json_object_new_double(JC_DOUBLE(src)->c_double); break;
    1684             : 
    1685         771 :   case json_type_int:
    1686         771 :     switch (JC_INT(src)->cint_type)
    1687             :     {
    1688         771 :     case json_object_int_type_int64:
    1689         771 :       *dst = json_object_new_int64(JC_INT(src)->cint.c_int64);
    1690         771 :       break;
    1691           0 :     case json_object_int_type_uint64:
    1692           0 :       *dst = json_object_new_uint64(JC_INT(src)->cint.c_uint64);
    1693           0 :       break;
    1694           0 :     default: json_abort("invalid cint_type");
    1695             :     }
    1696         771 :     break;
    1697             : 
    1698          45 :   case json_type_string: *dst = json_object_new_string(get_string_component(src)); break;
    1699             : 
    1700           3 :   case json_type_object: *dst = json_object_new_object(); break;
    1701             : 
    1702           3 :   case json_type_array: *dst = json_object_new_array(); break;
    1703             : 
    1704           0 :   default: errno = EINVAL; return -1;
    1705             :   }
    1706             : 
    1707         842 :   if (!*dst)
    1708             :   {
    1709           0 :     errno = ENOMEM;
    1710           0 :     return -1;
    1711             :   }
    1712         842 :   (*dst)->_to_json_string = src->_to_json_string;
    1713             :   // _userdata and _user_delete are copied later
    1714         842 :   return 1;
    1715             : }
    1716             : 
    1717             : /*
    1718             :  * The actual guts of json_object_deep_copy(), with a few additional args
    1719             :  * needed so we can keep track of where we are within the object tree.
    1720             :  *
    1721             :  * Note: caller is responsible for freeing *dst if this fails and returns -1.
    1722             :  */
    1723         842 : static int json_object_deep_copy_recursive(struct json_object *src, struct json_object *parent,
    1724             :                                            const char *key_in_parent, size_t index_in_parent,
    1725             :                                            struct json_object **dst,
    1726             :                                            json_c_shallow_copy_fn *shallow_copy)
    1727             : {
    1728             :   struct json_object_iter iter;
    1729             :   size_t src_array_len, ii;
    1730             : 
    1731         842 :   int shallow_copy_rc = 0;
    1732         842 :   shallow_copy_rc = shallow_copy(src, parent, key_in_parent, index_in_parent, dst);
    1733             :   /* -1=error, 1=object created ok, 2=userdata set */
    1734         842 :   if (shallow_copy_rc < 1)
    1735             :   {
    1736           0 :     errno = EINVAL;
    1737           0 :     return -1;
    1738             :   }
    1739         842 :   assert(*dst != NULL);
    1740             : 
    1741         842 :   switch (src->o_type)
    1742             :   {
    1743           3 :   case json_type_object:
    1744          15 :     json_object_object_foreachC(src, iter)
    1745             :     {
    1746          12 :       struct json_object *jso = NULL;
    1747             :       /* This handles the `json_type_null` case */
    1748          12 :       if (!iter.val)
    1749           0 :         jso = NULL;
    1750          12 :       else if (json_object_deep_copy_recursive(iter.val, src, iter.key, -1, &jso,
    1751             :                                                shallow_copy) < 0)
    1752             :       {
    1753           0 :         json_object_put(jso);
    1754           0 :         return -1;
    1755             :       }
    1756             : 
    1757          12 :       if (json_object_object_add(*dst, iter.key, jso) < 0)
    1758             :       {
    1759           0 :         json_object_put(jso);
    1760           0 :         return -1;
    1761             :       }
    1762             :     }
    1763           3 :     break;
    1764             : 
    1765           3 :   case json_type_array:
    1766           3 :     src_array_len = json_object_array_length(src);
    1767         771 :     for (ii = 0; ii < src_array_len; ii++)
    1768             :     {
    1769         768 :       struct json_object *jso = NULL;
    1770         768 :       struct json_object *jso1 = json_object_array_get_idx(src, ii);
    1771             :       /* This handles the `json_type_null` case */
    1772         768 :       if (!jso1)
    1773           0 :         jso = NULL;
    1774         768 :       else if (json_object_deep_copy_recursive(jso1, src, NULL, ii, &jso,
    1775             :                                                shallow_copy) < 0)
    1776             :       {
    1777           0 :         json_object_put(jso);
    1778           0 :         return -1;
    1779             :       }
    1780             : 
    1781         768 :       if (json_object_array_add(*dst, jso) < 0)
    1782             :       {
    1783           0 :         json_object_put(jso);
    1784           0 :         return -1;
    1785             :       }
    1786             :     }
    1787           3 :     break;
    1788             : 
    1789         836 :   default:
    1790         836 :     break;
    1791             :     /* else, nothing to do, shallow_copy already did. */
    1792             :   }
    1793             : 
    1794         842 :   if (shallow_copy_rc != 2)
    1795         842 :     return json_object_copy_serializer_data(src, *dst);
    1796             : 
    1797           0 :   return 0;
    1798             : }
    1799             : 
    1800          62 : int json_object_deep_copy(struct json_object *src, struct json_object **dst,
    1801             :                           json_c_shallow_copy_fn *shallow_copy)
    1802             : {
    1803             :   int rc;
    1804             : 
    1805             :   /* Check if arguments are sane ; *dst must not point to a non-NULL object */
    1806          62 :   if (!src || !dst || *dst)
    1807             :   {
    1808           0 :     errno = EINVAL;
    1809           0 :     return -1;
    1810             :   }
    1811             : 
    1812          62 :   if (shallow_copy == NULL)
    1813          62 :     shallow_copy = json_c_shallow_copy_default;
    1814             : 
    1815          62 :   rc = json_object_deep_copy_recursive(src, NULL, NULL, -1, dst, shallow_copy);
    1816          62 :   if (rc < 0)
    1817             :   {
    1818           1 :     json_object_put(*dst);
    1819           1 :     *dst = NULL;
    1820             :   }
    1821             : 
    1822          62 :   return rc;
    1823             : }
    1824             : 
    1825           0 : static void json_abort(const char *message)
    1826             : {
    1827           0 :   if (message != NULL)
    1828           0 :     fprintf(stderr, "json-c aborts with error: %s\n", message);
    1829           0 :   abort();
    1830             : }

Generated by: LCOV version 1.14