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: 517 858 60.3 %
Date: 2025-10-21 15:59:38 Functions: 75 100 75.0 %

          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     6837470 : static inline struct json_object_object *JC_OBJECT(struct json_object *jso)
      76             : {
      77     6837470 :   return (void *)jso;
      78             : }
      79     2151120 : static inline const struct json_object_object *JC_OBJECT_C(const struct json_object *jso)
      80             : {
      81     2151120 :   return (const void *)jso;
      82             : }
      83     2603330 : static inline struct json_object_array *JC_ARRAY(struct json_object *jso)
      84             : {
      85     2603330 :   return (void *)jso;
      86             : }
      87     2621310 : static inline const struct json_object_array *JC_ARRAY_C(const struct json_object *jso)
      88             : {
      89     2621310 :   return (const void *)jso;
      90             : }
      91       24741 : static inline struct json_object_boolean *JC_BOOL(struct json_object *jso)
      92             : {
      93       24741 :   return (void *)jso;
      94             : }
      95         304 : static inline const struct json_object_boolean *JC_BOOL_C(const struct json_object *jso)
      96             : {
      97         304 :   return (const void *)jso;
      98             : }
      99        3605 : static inline struct json_object_double *JC_DOUBLE(struct json_object *jso)
     100             : {
     101        3605 :   return (void *)jso;
     102             : }
     103      469654 : static inline const struct json_object_double *JC_DOUBLE_C(const struct json_object *jso)
     104             : {
     105      469654 :   return (const void *)jso;
     106             : }
     107      149188 : static inline struct json_object_int *JC_INT(struct json_object *jso)
     108             : {
     109      149188 :   return (void *)jso;
     110             : }
     111      894550 : static inline const struct json_object_int *JC_INT_C(const struct json_object *jso)
     112             : {
     113      894550 :   return (const void *)jso;
     114             : }
     115     2288120 : static inline struct json_object_string *JC_STRING(struct json_object *jso)
     116             : {
     117     2288120 :   return (void *)jso;
     118             : }
     119      607196 : static inline const struct json_object_string *JC_STRING_C(const struct json_object *jso)
     120             : {
     121      607196 :   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      607195 : static inline char *get_string_component_mutable(struct json_object *jso)
     204             : {
     205      607195 :   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      607195 :   return JC_STRING(jso)->c_string.idata;
     211             : }
     212      607195 : static inline const char *get_string_component(const struct json_object *jso)
     213             : {
     214      607195 :   return get_string_component_mutable((void *)(uintptr_t)(const void *)jso);
     215             : }
     216             : 
     217             : /* string escaping */
     218             : 
     219      401987 : static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int flags)
     220             : {
     221      401987 :   int pos = 0, start_offset = 0;
     222             :   unsigned char c;
     223     5578700 :   while (len)
     224             :   {
     225     5176710 :     --len;
     226     5176710 :     c = str[pos];
     227     5176710 :     switch (c)
     228             :     {
     229       55951 :     case '\b':
     230             :     case '\n':
     231             :     case '\r':
     232             :     case '\t':
     233             :     case '\f':
     234             :     case '"':
     235             :     case '\\':
     236             :     case '/':
     237       55951 :       if ((flags & JSON_C_TO_STRING_NOSLASHESCAPE) && c == '/')
     238             :       {
     239        1525 :         pos++;
     240        1525 :         break;
     241             :       }
     242             : 
     243       54426 :       if (pos - start_offset > 0)
     244       50256 :         printbuf_memappend(pb, str + start_offset, pos - start_offset);
     245             : 
     246       54426 :       if (c == '\b')
     247           0 :         printbuf_memappend(pb, "\\b", 2);
     248       54426 :       else if (c == '\n')
     249        9047 :         printbuf_memappend(pb, "\\n", 2);
     250       45379 :       else if (c == '\r')
     251           0 :         printbuf_memappend(pb, "\\r", 2);
     252       45379 :       else if (c == '\t')
     253           0 :         printbuf_memappend(pb, "\\t", 2);
     254       45379 :       else if (c == '\f')
     255           0 :         printbuf_memappend(pb, "\\f", 2);
     256       45379 :       else if (c == '"')
     257       28436 :         printbuf_memappend(pb, "\\\"", 2);
     258       16943 :       else if (c == '\\')
     259         183 :         printbuf_memappend(pb, "\\\\", 2);
     260       16760 :       else if (c == '/')
     261       16760 :         printbuf_memappend(pb, "\\/", 2);
     262             : 
     263       54426 :       start_offset = ++pos;
     264       54426 :       break;
     265     5120760 :     default:
     266     5120760 :       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     5120760 :         pos++;
     279             :     }
     280             :   }
     281      401987 :   if (pos - start_offset > 0)
     282      401268 :     printbuf_memappend(pb, str + start_offset, pos - start_offset);
     283      401987 :   return 0;
     284             : }
     285             : 
     286             : /* reference counting */
     287             : 
     288     5556880 : struct json_object *json_object_get(struct json_object *jso)
     289             : {
     290     5556880 :   if (!jso)
     291      121402 :     return jso;
     292             : 
     293             :   // Don't overflow the refcounter.
     294     5435480 :   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     5435480 :   ++jso->_ref_count;
     300             : #endif
     301             : 
     302     5435480 :   return jso;
     303             : }
     304             : 
     305    12437200 : int json_object_put(struct json_object *jso)
     306             : {
     307    12437200 :   if (!jso)
     308     2952090 :     return 0;
     309             : 
     310             :   /* Avoid invalid free and crash explicitly instead of (silently)
     311             :    * segfaulting.
     312             :    */
     313     9485150 :   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     9485150 :   if (--jso->_ref_count > 0)
     326     5435480 :     return 0;
     327             : #endif
     328             : 
     329     4049670 :   if (jso->_user_delete)
     330      210131 :     jso->_user_delete(jso, jso->_userdata);
     331     4049670 :   switch (jso->o_type)
     332             :   {
     333      584729 :   case json_type_object: json_object_object_delete(jso); break;
     334      551742 :   case json_type_array: json_object_array_delete(jso); break;
     335     1534110 :   case json_type_string: json_object_string_delete(jso); break;
     336     1379090 :   default: json_object_generic_delete(jso); break;
     337             :   }
     338     4049670 :   return 1;
     339             : }
     340             : 
     341             : /* generic object construction and destruction parts */
     342             : 
     343     4049670 : 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     4049670 :   printbuf_free(jso->_pb);
     350     4049670 :   free(jso);
     351     4049670 : }
     352             : 
     353     4049670 : 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     4049670 :   jso = (struct json_object *)malloc(alloc_size);
     359     4049670 :   if (!jso)
     360           0 :     return NULL;
     361             : 
     362     4049670 :   jso->o_type = o_type;
     363     4049670 :   jso->_ref_count = 1;
     364     4049670 :   jso->_to_json_string = to_json_string;
     365     4049670 :   jso->_pb = NULL;
     366     4049670 :   jso->_user_delete = NULL;
     367     4049670 :   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     4049670 :   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     8723980 : enum json_type json_object_get_type(const struct json_object *jso)
     387             : {
     388     8723980 :   if (!jso)
     389        1396 :     return json_type_null;
     390     8722590 :   return jso->o_type;
     391             : }
     392             : 
     393       37506 : void *json_object_get_userdata(json_object *jso)
     394             : {
     395       37506 :   return jso ? jso->_userdata : NULL;
     396             : }
     397             : 
     398      251166 : 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      251166 :   assert(jso != NULL);
     402             : 
     403             :   // First, clean up any previously existing user info
     404      251166 :   if (jso->_user_delete)
     405           0 :     jso->_user_delete(jso, jso->_userdata);
     406             : 
     407      251166 :   jso->_userdata = userdata;
     408      251166 :   jso->_user_delete = user_delete;
     409      251166 : }
     410             : 
     411             : /* set a custom conversion to string */
     412             : 
     413      251166 : 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      251166 :   json_object_set_userdata(jso, userdata, user_delete);
     417             : 
     418      251166 :   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      251166 :   jso->_to_json_string = to_string_func;
     445             : }
     446             : 
     447             : /* extended conversion to string */
     448             : 
     449       58253 : const char *json_object_to_json_string_length(struct json_object *jso, int flags, size_t *length)
     450             : {
     451       58253 :   const char *r = NULL;
     452       58253 :   size_t s = 0;
     453             : 
     454       58253 :   if (!jso)
     455             :   {
     456           6 :     s = 4;
     457           6 :     r = "null";
     458             :   }
     459       58247 :   else if ((jso->_pb) || (jso->_pb = printbuf_new()))
     460             :   {
     461       58247 :     printbuf_reset(jso->_pb);
     462             : 
     463       58247 :     if (jso->_to_json_string(jso, jso->_pb, 0, flags) >= 0)
     464             :     {
     465       58247 :       s = (size_t)jso->_pb->bpos;
     466       58247 :       r = jso->_pb->buf;
     467             :     }
     468             :   }
     469             : 
     470       58253 :   if (length)
     471           0 :     *length = s;
     472       58253 :   return r;
     473             : }
     474             : 
     475       58253 : const char *json_object_to_json_string_ext(struct json_object *jso, int flags)
     476             : {
     477       58253 :   return json_object_to_json_string_length(jso, flags, NULL);
     478             : }
     479             : 
     480             : /* backwards-compatible conversion to string */
     481             : 
     482       24628 : const char *json_object_to_json_string(struct json_object *jso)
     483             : {
     484       24628 :   return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
     485             : }
     486             : 
     487      603157 : static void indent(struct printbuf *pb, int level, int flags)
     488             : {
     489      603157 :   if (flags & JSON_C_TO_STRING_PRETTY)
     490             :   {
     491      467151 :     if (flags & JSON_C_TO_STRING_PRETTY_TAB)
     492             :     {
     493           0 :       printbuf_memset(pb, -1, '\t', level);
     494             :     }
     495             :     else
     496             :     {
     497      467151 :       printbuf_memset(pb, -1, ' ', level * 2);
     498             :     }
     499             :   }
     500      603157 : }
     501             : 
     502             : /* json_object_object */
     503             : 
     504       79855 : static int json_object_object_to_json_string(struct json_object *jso, struct printbuf *pb,
     505             :                                              int level, int flags)
     506             : {
     507       79855 :   int had_children = 0;
     508             :   struct json_object_iter iter;
     509             : 
     510       79855 :   printbuf_strappend(pb, "{" /*}*/);
     511       79855 :   if (flags & JSON_C_TO_STRING_PRETTY)
     512       37572 :     printbuf_strappend(pb, "\n");
     513      335025 :   json_object_object_foreachC(jso, iter)
     514             :   {
     515      255170 :     if (had_children)
     516             :     {
     517      188787 :       printbuf_strappend(pb, ",");
     518      188787 :       if (flags & JSON_C_TO_STRING_PRETTY)
     519      157079 :         printbuf_strappend(pb, "\n");
     520             :     }
     521      255170 :     had_children = 1;
     522      255170 :     if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
     523       18596 :       printbuf_strappend(pb, " ");
     524      255170 :     indent(pb, level + 1, flags);
     525      255170 :     printbuf_strappend(pb, "\"");
     526      255170 :     json_escape_str(pb, iter.key, strlen(iter.key), flags);
     527      255170 :     if (flags & JSON_C_TO_STRING_SPACED)
     528       18596 :       printbuf_strappend(pb, "\": ");
     529             :     else
     530      236574 :       printbuf_strappend(pb, "\":");
     531      255170 :     if (iter.val == NULL)
     532       13024 :       printbuf_strappend(pb, "null");
     533      242146 :     else if (iter.val->_to_json_string(iter.val, pb, level + 1, flags) < 0)
     534           0 :       return -1;
     535             :   }
     536       79855 :   if (flags & JSON_C_TO_STRING_PRETTY)
     537             :   {
     538       37572 :     if (had_children)
     539       36653 :       printbuf_strappend(pb, "\n");
     540       37572 :     indent(pb, level, flags);
     541             :   }
     542       79855 :   if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
     543        9183 :     return printbuf_strappend(pb, /*{*/ " }");
     544             :   else
     545       70672 :     return printbuf_strappend(pb, /*{*/ "}");
     546             : }
     547             : 
     548     2079530 : static void json_object_lh_entry_free(struct lh_entry *ent)
     549             : {
     550     2079530 :   if (!ent->k_is_constant)
     551     2079530 :     free(lh_entry_k(ent));
     552     2079530 :   json_object_put((struct json_object *)lh_entry_v(ent));
     553     2079530 : }
     554             : 
     555      584729 : static void json_object_object_delete(struct json_object *jso_base)
     556             : {
     557      584729 :   lh_table_free(JC_OBJECT(jso_base)->c_object);
     558      584729 :   json_object_generic_delete(jso_base);
     559      584729 : }
     560             : 
     561      584729 : struct json_object *json_object_new_object(void)
     562             : {
     563      584729 :   struct json_object_object *jso = JSON_OBJECT_NEW(object);
     564      584729 :   if (!jso)
     565           0 :     return NULL;
     566      584729 :   jso->c_object =
     567      584729 :       lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES, &json_object_lh_entry_free);
     568      584729 :   if (!jso->c_object)
     569             :   {
     570           0 :     json_object_generic_delete(&jso->base);
     571           0 :     errno = ENOMEM;
     572           0 :     return NULL;
     573             :   }
     574      584729 :   return &jso->base;
     575             : }
     576             : 
     577      237867 : struct lh_table *json_object_get_object(const struct json_object *jso)
     578             : {
     579      237867 :   if (!jso)
     580           0 :     return NULL;
     581      237867 :   switch (jso->o_type)
     582             :   {
     583      237861 :   case json_type_object: return JC_OBJECT_C(jso)->c_object;
     584           6 :   default: return NULL;
     585             :   }
     586             : }
     587             : 
     588     2079710 : 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     2079710 :   struct json_object *existing_value = NULL;
     592             :   struct lh_entry *existing_entry;
     593             :   unsigned long hash;
     594             : 
     595     2079710 :   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     2079710 :   hash = lh_get_hash(JC_OBJECT(jso)->c_object, (const void *)key);
     600     2079710 :   existing_entry =
     601     2079710 :       (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW)
     602             :           ? NULL
     603     2079710 :           : 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     2079710 :   if (jso == val)
     608           0 :     return -1;
     609             : 
     610     2079710 :   if (!existing_entry)
     611             :   {
     612     2079530 :     const void *const k =
     613     2079530 :         (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ? (const void *)key : strdup(key);
     614     2079530 :     if (k == NULL)
     615           0 :       return -1;
     616     2079530 :     return lh_table_insert_w_hash(JC_OBJECT(jso)->c_object, k, val, hash, opts);
     617             :   }
     618         172 :   existing_value = (json_object *)lh_entry_v(existing_entry);
     619         172 :   if (existing_value)
     620         172 :     json_object_put(existing_value);
     621         172 :   existing_entry->v = val;
     622         172 :   return 0;
     623             : }
     624             : 
     625     2079710 : int json_object_object_add(struct json_object *jso, const char *key, struct json_object *val)
     626             : {
     627     2079710 :   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        1591 : size_t json_c_object_sizeof(void)
     637             : {
     638        1591 :   return sizeof(struct json_object);
     639             : }
     640             : 
     641           0 : static void ignore_return_bool_value(json_bool b)
     642             : {
     643             :     (void)b;
     644           0 : }
     645             : 
     646           0 : struct json_object *json_object_object_get(const struct json_object *jso, const char *key)
     647             : {
     648           0 :   struct json_object *result = NULL;
     649           0 :   ignore_return_bool_value(json_object_object_get_ex(jso, key, &result));
     650           0 :   return result;
     651             : }
     652             : 
     653     1914600 : json_bool json_object_object_get_ex(const struct json_object *jso, const char *key,
     654             :                                     struct json_object **value)
     655             : {
     656     1914600 :   if (value != NULL)
     657     1914600 :     *value = NULL;
     658             : 
     659     1914600 :   if (NULL == jso)
     660         923 :     return 0;
     661             : 
     662     1913680 :   switch (jso->o_type)
     663             :   {
     664     1913250 :   case json_type_object:
     665     1913250 :     return lh_table_lookup_ex(JC_OBJECT_C(jso)->c_object, (const void *)key,
     666             :                               (void **)value);
     667         424 :   default:
     668         424 :     if (value != NULL)
     669         424 :       *value = NULL;
     670         424 :     return 0;
     671             :   }
     672             : }
     673             : 
     674       13794 : void json_object_object_del(struct json_object *jso, const char *key)
     675             : {
     676       13794 :   assert(json_object_get_type(jso) == json_type_object);
     677       13794 :   lh_table_delete(JC_OBJECT(jso)->c_object, key);
     678       13794 : }
     679             : 
     680             : /* json_object_boolean */
     681             : 
     682       24741 : static int json_object_boolean_to_json_string(struct json_object *jso, struct printbuf *pb,
     683             :                                               int level, int flags)
     684             : {
     685             :     (void)level;
     686             :     (void)flags;
     687       24741 :   if (JC_BOOL(jso)->c_boolean)
     688        9145 :     return printbuf_strappend(pb, "true");
     689       15596 :   return printbuf_strappend(pb, "false");
     690             : }
     691             : 
     692       63699 : struct json_object *json_object_new_boolean(json_bool b)
     693             : {
     694       63699 :   struct json_object_boolean *jso = JSON_OBJECT_NEW(boolean);
     695       63699 :   if (!jso)
     696           0 :     return NULL;
     697       63699 :   jso->c_boolean = b;
     698       63699 :   return &jso->base;
     699             : }
     700             : 
     701         205 : json_bool json_object_get_boolean(const struct json_object *jso)
     702             : {
     703         205 :   if (!jso)
     704           3 :     return 0;
     705         202 :   switch (jso->o_type)
     706             :   {
     707         201 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
     708           0 :   case json_type_int:
     709           0 :     switch (JC_INT_C(jso)->cint_type)
     710             :     {
     711           0 :     case json_object_int_type_int64: return (JC_INT_C(jso)->cint.c_int64 != 0);
     712           0 :     case json_object_int_type_uint64: return (JC_INT_C(jso)->cint.c_uint64 != 0);
     713           0 :     default: json_abort("invalid cint_type");
     714             :     }
     715           0 :   case json_type_double: return (JC_DOUBLE_C(jso)->c_double != 0);
     716           1 :   case json_type_string: return (JC_STRING_C(jso)->len != 0);
     717           0 :   default: return 0;
     718             :   }
     719             : }
     720             : 
     721           0 : int json_object_set_boolean(struct json_object *jso, json_bool new_value)
     722             : {
     723           0 :   if (!jso || jso->o_type != json_type_boolean)
     724           0 :     return 0;
     725           0 :   JC_BOOL(jso)->c_boolean = new_value;
     726           0 :   return 1;
     727             : }
     728             : 
     729             : /* json_object_int */
     730             : 
     731       73563 : static int json_object_int_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
     732             :                                           int flags)
     733             : {
     734             :     (void)level;
     735             :     (void)flags;
     736             :   /* room for 19 digits, the sign char, and a null term */
     737             :   char sbuf[21];
     738       73563 :   if (JC_INT(jso)->cint_type == json_object_int_type_int64)
     739       72680 :     snprintf(sbuf, sizeof(sbuf), "%" PRId64, JC_INT(jso)->cint.c_int64);
     740             :   else
     741         883 :     snprintf(sbuf, sizeof(sbuf), "%" PRIu64, JC_INT(jso)->cint.c_uint64);
     742       73563 :   return printbuf_memappend(pb, sbuf, (int)strlen(sbuf));
     743             : }
     744             : 
     745       31692 : struct json_object *json_object_new_int(int32_t i)
     746             : {
     747       31692 :   return json_object_new_int64(i);
     748             : }
     749             : 
     750      214127 : int32_t json_object_get_int(const struct json_object *jso)
     751             : {
     752      214127 :   int64_t cint64=0;
     753             :   double cdouble;
     754             :   enum json_type o_type;
     755             : 
     756      214127 :   if (!jso)
     757           0 :     return 0;
     758             : 
     759      214127 :   o_type = jso->o_type;
     760      214127 :   if (o_type == json_type_int)
     761             :   {
     762      214049 :     const struct json_object_int *jsoint = JC_INT_C(jso);
     763      214049 :     if (jsoint->cint_type == json_object_int_type_int64)
     764             :     {
     765      214049 :       cint64 = jsoint->cint.c_int64;
     766             :     }
     767             :     else
     768             :     {
     769           0 :       if (jsoint->cint.c_uint64 >= INT64_MAX)
     770           0 :         cint64 = INT64_MAX;
     771             :       else
     772           0 :         cint64 = (int64_t)jsoint->cint.c_uint64;
     773             :     }
     774             :   }
     775          78 :   else if (o_type == json_type_string)
     776             :   {
     777             :     /*
     778             :      * Parse strings into 64-bit numbers, then use the
     779             :      * 64-to-32-bit number handling below.
     780             :      */
     781           3 :     if (json_parse_int64(get_string_component(jso), &cint64) != 0)
     782           1 :       return 0; /* whoops, it didn't work. */
     783           2 :     o_type = json_type_int;
     784             :   }
     785             : 
     786      214126 :   switch (o_type)
     787             :   {
     788      214051 :   case json_type_int:
     789             :     /* Make sure we return the correct values for out of range numbers. */
     790      214051 :     if (cint64 <= INT32_MIN)
     791           0 :       return INT32_MIN;
     792      214051 :     if (cint64 >= INT32_MAX)
     793           0 :       return INT32_MAX;
     794      214051 :     return (int32_t)cint64;
     795           1 :   case json_type_double:
     796           1 :     cdouble = JC_DOUBLE_C(jso)->c_double;
     797           1 :     if (cdouble <= INT32_MIN)
     798           0 :       return INT32_MIN;
     799           1 :     if (cdouble >= INT32_MAX)
     800           0 :       return INT32_MAX;
     801           1 :     return (int32_t)cdouble;
     802          74 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
     803           0 :   default: return 0;
     804             :   }
     805             : }
     806             : 
     807           0 : int json_object_set_int(struct json_object *jso, int new_value)
     808             : {
     809           0 :   return json_object_set_int64(jso, (int64_t)new_value);
     810             : }
     811             : 
     812      676892 : struct json_object *json_object_new_int64(int64_t i)
     813             : {
     814      676892 :   struct json_object_int *jso = JSON_OBJECT_NEW(int);
     815      676892 :   if (!jso)
     816           0 :     return NULL;
     817      676892 :   jso->cint.c_int64 = i;
     818      676892 :   jso->cint_type = json_object_int_type_int64;
     819      676892 :   return &jso->base;
     820             : }
     821             : 
     822         875 : struct json_object *json_object_new_uint64(uint64_t i)
     823             : {
     824         875 :   struct json_object_int *jso = JSON_OBJECT_NEW(int);
     825         875 :   if (!jso)
     826           0 :     return NULL;
     827         875 :   jso->cint.c_uint64 = i;
     828         875 :   jso->cint_type = json_object_int_type_uint64;
     829         875 :   return &jso->base;
     830             : }
     831             : 
     832      100596 : int64_t json_object_get_int64(const struct json_object *jso)
     833             : {
     834             :   int64_t cint;
     835             : 
     836      100596 :   if (!jso)
     837           0 :     return 0;
     838      100596 :   switch (jso->o_type)
     839             :   {
     840      100563 :   case json_type_int:
     841             :   {
     842      100563 :     const struct json_object_int *jsoint = JC_INT_C(jso);
     843      100563 :     switch (jsoint->cint_type)
     844             :     {
     845      100552 :     case json_object_int_type_int64: return jsoint->cint.c_int64;
     846          11 :     case json_object_int_type_uint64:
     847          11 :       if (jsoint->cint.c_uint64 >= INT64_MAX)
     848           8 :         return INT64_MAX;
     849           3 :       return (int64_t)jsoint->cint.c_uint64;
     850           0 :     default: json_abort("invalid cint_type");
     851             :     }
     852             :   }
     853           1 :   case json_type_double:
     854             :     // INT64_MAX can't be exactly represented as a double
     855             :     // so cast to tell the compiler it's ok to round up.
     856           1 :     if (JC_DOUBLE_C(jso)->c_double >= (double)INT64_MAX)
     857           0 :       return INT64_MAX;
     858           1 :     if (JC_DOUBLE_C(jso)->c_double <= INT64_MIN)
     859           0 :       return INT64_MIN;
     860           1 :     return (int64_t)JC_DOUBLE_C(jso)->c_double;
     861          21 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
     862          11 :   case json_type_string:
     863          11 :     if (json_parse_int64(get_string_component(jso), &cint) == 0)
     864          11 :       return cint;
     865             :     /* FALLTHRU */
     866           0 :   default: return 0;
     867             :   }
     868             : }
     869             : 
     870           0 : uint64_t json_object_get_uint64(const struct json_object *jso)
     871             : {
     872             :   uint64_t cuint;
     873             : 
     874           0 :   if (!jso)
     875           0 :     return 0;
     876           0 :   switch (jso->o_type)
     877             :   {
     878           0 :   case json_type_int:
     879             :   {
     880           0 :     const struct json_object_int *jsoint = JC_INT_C(jso);
     881           0 :     switch (jsoint->cint_type)
     882             :     {
     883           0 :     case json_object_int_type_int64:
     884           0 :       if (jsoint->cint.c_int64 < 0)
     885           0 :         return 0;
     886           0 :       return (uint64_t)jsoint->cint.c_int64;
     887           0 :     case json_object_int_type_uint64: return jsoint->cint.c_uint64;
     888           0 :     default: json_abort("invalid cint_type");
     889             :     }
     890             :   }
     891           0 :   case json_type_double:
     892             :     // UINT64_MAX can't be exactly represented as a double
     893             :     // so cast to tell the compiler it's ok to round up.
     894           0 :     if (JC_DOUBLE_C(jso)->c_double >= (double)UINT64_MAX)
     895           0 :       return UINT64_MAX;
     896           0 :     if (JC_DOUBLE_C(jso)->c_double < 0)
     897           0 :       return 0;
     898           0 :     return (uint64_t)JC_DOUBLE_C(jso)->c_double;
     899           0 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
     900           0 :   case json_type_string:
     901           0 :     if (json_parse_uint64(get_string_component(jso), &cuint) == 0)
     902           0 :       return cuint;
     903             :     /* FALLTHRU */
     904           0 :   default: return 0;
     905             :   }
     906             : }
     907             : 
     908           0 : int json_object_set_int64(struct json_object *jso, int64_t new_value)
     909             : {
     910           0 :   if (!jso || jso->o_type != json_type_int)
     911           0 :     return 0;
     912           0 :   JC_INT(jso)->cint.c_int64 = new_value;
     913           0 :   JC_INT(jso)->cint_type = json_object_int_type_int64;
     914           0 :   return 1;
     915             : }
     916             : 
     917           0 : int json_object_set_uint64(struct json_object *jso, uint64_t new_value)
     918             : {
     919           0 :   if (!jso || jso->o_type != json_type_int)
     920           0 :     return 0;
     921           0 :   JC_INT(jso)->cint.c_uint64 = new_value;
     922           0 :   JC_INT(jso)->cint_type = json_object_int_type_uint64;
     923           0 :   return 1;
     924             : }
     925             : 
     926           0 : int json_object_int_inc(struct json_object *jso, int64_t val)
     927             : {
     928             :   struct json_object_int *jsoint;
     929           0 :   if (!jso || jso->o_type != json_type_int)
     930           0 :     return 0;
     931           0 :   jsoint = JC_INT(jso);
     932           0 :   switch (jsoint->cint_type)
     933             :   {
     934           0 :   case json_object_int_type_int64:
     935           0 :     if (val > 0 && jsoint->cint.c_int64 > INT64_MAX - val)
     936             :     {
     937           0 :       jsoint->cint.c_uint64 = (uint64_t)jsoint->cint.c_int64 + (uint64_t)val;
     938           0 :       jsoint->cint_type = json_object_int_type_uint64;
     939             :     }
     940           0 :     else if (val < 0 && jsoint->cint.c_int64 < INT64_MIN - val)
     941             :     {
     942           0 :       jsoint->cint.c_int64 = INT64_MIN;
     943             :     }
     944             :     else
     945             :     {
     946           0 :       jsoint->cint.c_int64 += val;
     947             :     }
     948           0 :     return 1;
     949           0 :   case json_object_int_type_uint64:
     950           0 :     if (val > 0 && jsoint->cint.c_uint64 > UINT64_MAX - (uint64_t)val)
     951             :     {
     952           0 :       jsoint->cint.c_uint64 = UINT64_MAX;
     953             :     }
     954           0 :     else if (val < 0 && jsoint->cint.c_uint64 < (uint64_t)(-val))
     955             :     {
     956           0 :       jsoint->cint.c_int64 = (int64_t)jsoint->cint.c_uint64 + val;
     957           0 :       jsoint->cint_type = json_object_int_type_int64;
     958             :     }
     959           0 :     else if (val < 0 && jsoint->cint.c_uint64 >= (uint64_t)(-val))
     960             :     {
     961           0 :       jsoint->cint.c_uint64 -= (uint64_t)(-val);
     962             :     }
     963             :     else
     964             :     {
     965           0 :       jsoint->cint.c_uint64 += val;
     966             :     }
     967           0 :     return 1;
     968           0 :   default: json_abort("invalid cint_type");
     969             :   }
     970             : }
     971             : 
     972             : /* json_object_double */
     973             : 
     974             : #if defined(HAVE___THREAD)
     975             : // i.e. __thread or __declspec(thread)
     976             : static SPEC___THREAD char *tls_serialization_float_format = NULL;
     977             : #endif
     978             : static char *global_serialization_float_format = NULL;
     979             : 
     980           0 : int json_c_set_serialization_double_format(const char *double_format, int global_or_thread)
     981             : {
     982           0 :   if (global_or_thread == JSON_C_OPTION_GLOBAL)
     983             :   {
     984             : #if defined(HAVE___THREAD)
     985             :     if (tls_serialization_float_format)
     986             :     {
     987             :       free(tls_serialization_float_format);
     988             :       tls_serialization_float_format = NULL;
     989             :     }
     990             : #endif
     991           0 :     if (global_serialization_float_format)
     992           0 :       free(global_serialization_float_format);
     993           0 :     global_serialization_float_format = double_format ? strdup(double_format) : NULL;
     994             :   }
     995           0 :   else if (global_or_thread == JSON_C_OPTION_THREAD)
     996             :   {
     997             : #if defined(HAVE___THREAD)
     998             :     if (tls_serialization_float_format)
     999             :     {
    1000             :       free(tls_serialization_float_format);
    1001             :       tls_serialization_float_format = NULL;
    1002             :     }
    1003             :     tls_serialization_float_format = double_format ? strdup(double_format) : NULL;
    1004             : #else
    1005           0 :     _json_c_set_last_err("json_c_set_option: not compiled with __thread support\n");
    1006           0 :     return -1;
    1007             : #endif
    1008             :   }
    1009             :   else
    1010             :   {
    1011           0 :     _json_c_set_last_err("json_c_set_option: invalid global_or_thread value: %d\n",
    1012             :                          global_or_thread);
    1013           0 :     return -1;
    1014             :   }
    1015           0 :   return 0;
    1016             : }
    1017             : 
    1018        3584 : static int json_object_double_to_json_string_format(struct json_object *jso, struct printbuf *pb,
    1019             :                                                     int level, int flags, const char *format)
    1020             : {
    1021             :     (void)level;
    1022        3584 :   struct json_object_double *jsodbl = JC_DOUBLE(jso);
    1023             :   char buf[128], *p, *q;
    1024             :   int size;
    1025             :   /* Although JSON RFC does not support
    1026             :    * NaN or Infinity as numeric values
    1027             :    * ECMA 262 section 9.8.1 defines
    1028             :    * how to handle these cases as strings
    1029             :    */
    1030        3584 :   if (isnan(jsodbl->c_double))
    1031             :   {
    1032           0 :     size = snprintf(buf, sizeof(buf), "NaN");
    1033             :   }
    1034        3584 :   else if (isinf(jsodbl->c_double))
    1035             :   {
    1036           6 :     if (jsodbl->c_double > 0)
    1037           6 :       size = snprintf(buf, sizeof(buf), "Infinity");
    1038             :     else
    1039           0 :       size = snprintf(buf, sizeof(buf), "-Infinity");
    1040             :   }
    1041             :   else
    1042             :   {
    1043        3578 :     const char *std_format = "%.17g";
    1044        3578 :     int format_drops_decimals = 0;
    1045        3578 :     int looks_numeric = 0;
    1046             : 
    1047        3578 :     if (!format)
    1048             :     {
    1049             : #if defined(HAVE___THREAD)
    1050             :       if (tls_serialization_float_format)
    1051             :         format = tls_serialization_float_format;
    1052             :       else
    1053             : #endif
    1054        3578 :           if (global_serialization_float_format)
    1055           0 :         format = global_serialization_float_format;
    1056             :       else
    1057        3578 :         format = std_format;
    1058             :     }
    1059        3578 :     size = snprintf(buf, sizeof(buf), format, jsodbl->c_double);
    1060             : 
    1061        3578 :     if (size < 0)
    1062           0 :       return -1;
    1063             : 
    1064        3578 :     p = strchr(buf, ',');
    1065        3578 :     if (p)
    1066           0 :       *p = '.';
    1067             :     else
    1068        3578 :       p = strchr(buf, '.');
    1069             : 
    1070        3578 :     if (format == std_format || strstr(format, ".0f") == NULL)
    1071        3578 :       format_drops_decimals = 1;
    1072             : 
    1073        3578 :     looks_numeric = /* Looks like *some* kind of number */
    1074        4191 :         isdigit((unsigned char)buf[0]) ||
    1075         613 :         (size > 1 && buf[0] == '-' && isdigit((unsigned char)buf[1]));
    1076             : 
    1077        3578 :     if (size < (int)sizeof(buf) - 2 && looks_numeric && !p && /* Has no decimal point */
    1078        2162 :         strchr(buf, 'e') == NULL && /* Not scientific notation */
    1079             :         format_drops_decimals)
    1080             :     {
    1081             :       // Ensure it looks like a float, even if snprintf didn't,
    1082             :       //  unless a custom format is set to omit the decimal.
    1083        2162 :       strcat(buf, ".0");
    1084        2162 :       size += 2;
    1085             :     }
    1086        3578 :     if (p && (flags & JSON_C_TO_STRING_NOZERO))
    1087             :     {
    1088             :       /* last useful digit, always keep 1 zero */
    1089           0 :       p++;
    1090           0 :       for (q = p; *q; q++)
    1091             :       {
    1092           0 :         if (*q != '0')
    1093           0 :           p = q;
    1094             :       }
    1095             :       /* drop trailing zeroes */
    1096           0 :       if (*p != 0)
    1097           0 :         *(++p) = 0;
    1098           0 :       size = (int)(p - buf);
    1099             :     }
    1100             :   }
    1101             :   // although unlikely, snprintf can fail
    1102        3584 :   if (size < 0)
    1103           0 :     return -1;
    1104             : 
    1105        3584 :   if (size >= (int)sizeof(buf))
    1106             :     // The standard formats are guaranteed not to overrun the buffer,
    1107             :     // but if a custom one happens to do so, just silently truncate.
    1108           0 :     size = sizeof(buf) - 1;
    1109        3584 :   printbuf_memappend(pb, buf, size);
    1110        3584 :   return size;
    1111             : }
    1112             : 
    1113        3584 : static int json_object_double_to_json_string_default(struct json_object *jso, struct printbuf *pb,
    1114             :                                                      int level, int flags)
    1115             : {
    1116        3584 :   return json_object_double_to_json_string_format(jso, pb, level, flags, NULL);
    1117             : }
    1118             : 
    1119           0 : int json_object_double_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
    1120             :                                       int flags)
    1121             : {
    1122           0 :   return json_object_double_to_json_string_format(jso, pb, level, flags,
    1123           0 :                                                   (const char *)jso->_userdata);
    1124             : }
    1125             : 
    1126      637620 : struct json_object *json_object_new_double(double d)
    1127             : {
    1128      637620 :   struct json_object_double *jso = JSON_OBJECT_NEW(double);
    1129      637620 :   if (!jso)
    1130           0 :     return NULL;
    1131      637620 :   jso->base._to_json_string = &json_object_double_to_json_string_default;
    1132      637620 :   jso->c_double = d;
    1133      637620 :   return &jso->base;
    1134             : }
    1135             : 
    1136      210131 : struct json_object *json_object_new_double_s(double d, const char *ds)
    1137             : {
    1138             :   char *new_ds;
    1139      210131 :   struct json_object *jso = json_object_new_double(d);
    1140      210131 :   if (!jso)
    1141           0 :     return NULL;
    1142             : 
    1143      210131 :   new_ds = strdup(ds);
    1144      210131 :   if (!new_ds)
    1145             :   {
    1146           0 :     json_object_generic_delete(jso);
    1147           0 :     errno = ENOMEM;
    1148           0 :     return NULL;
    1149             :   }
    1150      210131 :   json_object_set_serializer(jso, _json_object_userdata_to_json_string, new_ds,
    1151             :                              json_object_free_userdata);
    1152      210131 :   return jso;
    1153             : }
    1154             : 
    1155             : /*
    1156             :  * A wrapper around json_object_userdata_to_json_string() used only
    1157             :  * by json_object_new_double_s() just so json_object_set_double() can
    1158             :  * detect when it needs to reset the serializer to the default.
    1159             :  */
    1160       77105 : static int _json_object_userdata_to_json_string(struct json_object *jso, struct printbuf *pb,
    1161             :                                                 int level, int flags)
    1162             : {
    1163       77105 :   return json_object_userdata_to_json_string(jso, pb, level, flags);
    1164             : }
    1165             : 
    1166       77105 : int json_object_userdata_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
    1167             :                                         int flags)
    1168             : {
    1169             :     (void)level;
    1170             :     (void)flags;
    1171       77105 :   int userdata_len = (int)strlen((const char *)jso->_userdata);
    1172       77105 :   printbuf_memappend(pb, (const char *)jso->_userdata, userdata_len);
    1173       77105 :   return userdata_len;
    1174             : }
    1175             : 
    1176      210131 : void json_object_free_userdata(struct json_object *jso, void *userdata)
    1177             : {
    1178             :     (void)jso;
    1179      210131 :   free(userdata);
    1180      210131 : }
    1181             : 
    1182      759676 : double json_object_get_double(const struct json_object *jso)
    1183             : {
    1184             :   double cdouble;
    1185      759676 :   char *errPtr = NULL;
    1186             : 
    1187      759676 :   if (!jso)
    1188          48 :     return 0.0;
    1189      759628 :   switch (jso->o_type)
    1190             :   {
    1191      469650 :   case json_type_double: return JC_DOUBLE_C(jso)->c_double;
    1192      289969 :   case json_type_int:
    1193      289969 :     switch (JC_INT_C(jso)->cint_type)
    1194             :     {
    1195      289969 :     case json_object_int_type_int64: return JC_INT_C(jso)->cint.c_int64;
    1196           0 :     case json_object_int_type_uint64: return JC_INT_C(jso)->cint.c_uint64;
    1197           0 :     default: json_abort("invalid cint_type");
    1198             :     }
    1199           8 :   case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
    1200           1 :   case json_type_string:
    1201           1 :     errno = 0;
    1202           1 :     cdouble = CPLStrtod(get_string_component(jso), &errPtr);
    1203             : 
    1204             :     /* if conversion stopped at the first character, return 0.0 */
    1205           1 :     if (errPtr == get_string_component(jso))
    1206             :     {
    1207           0 :       errno = EINVAL;
    1208           0 :       return 0.0;
    1209             :     }
    1210             : 
    1211             :     /*
    1212             :      * Check that the conversion terminated on something sensible
    1213             :      *
    1214             :      * For example, { "pay" : 123AB } would parse as 123.
    1215             :      */
    1216           1 :     if (*errPtr != '\0')
    1217             :     {
    1218           0 :       errno = EINVAL;
    1219           0 :       return 0.0;
    1220             :     }
    1221             : 
    1222             :     /*
    1223             :      * If strtod encounters a string which would exceed the
    1224             :      * capacity of a double, it returns +/- HUGE_VAL and sets
    1225             :      * errno to ERANGE. But +/- HUGE_VAL is also a valid result
    1226             :      * from a conversion, so we need to check errno.
    1227             :      *
    1228             :      * Underflow also sets errno to ERANGE, but it returns 0 in
    1229             :      * that case, which is what we will return anyway.
    1230             :      *
    1231             :      * See CERT guideline ERR30-C
    1232             :      */
    1233           1 :     if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) && (ERANGE == errno))
    1234           0 :       cdouble = 0.0;
    1235           1 :     return cdouble;
    1236           0 :   default: errno = EINVAL; return 0.0;
    1237             :   }
    1238             : }
    1239             : 
    1240           0 : int json_object_set_double(struct json_object *jso, double new_value)
    1241             : {
    1242           0 :   if (!jso || jso->o_type != json_type_double)
    1243           0 :     return 0;
    1244           0 :   JC_DOUBLE(jso)->c_double = new_value;
    1245           0 :   if (jso->_to_json_string == &_json_object_userdata_to_json_string)
    1246           0 :     json_object_set_serializer(jso, NULL, NULL, NULL);
    1247           0 :   return 1;
    1248             : }
    1249             : 
    1250             : /* json_object_string */
    1251             : 
    1252      146817 : static int json_object_string_to_json_string(struct json_object *jso, struct printbuf *pb,
    1253             :                                              int level, int flags)
    1254             : {
    1255             :     (void)level;
    1256      146817 :   ssize_t len = JC_STRING(jso)->len;
    1257      146817 :   printbuf_strappend(pb, "\"");
    1258      146817 :   json_escape_str(pb, get_string_component(jso), len < 0 ? -(ssize_t)len : len, flags);
    1259      146817 :   printbuf_strappend(pb, "\"");
    1260      146817 :   return 0;
    1261             : }
    1262             : 
    1263     1534110 : static void json_object_string_delete(struct json_object *jso)
    1264             : {
    1265     1534110 :   if (JC_STRING(jso)->len < 0)
    1266           0 :     free(JC_STRING(jso)->c_string.pdata);
    1267     1534110 :   json_object_generic_delete(jso);
    1268     1534110 : }
    1269             : 
    1270     1534110 : static struct json_object *_json_object_new_string(const char *s, const size_t len)
    1271             : {
    1272             :   size_t objsize;
    1273             :   struct json_object_string *jso;
    1274             : 
    1275             :   /*
    1276             :      * Structures           Actual memory layout
    1277             :      * -------------------  --------------------
    1278             :    * [json_object_string  [json_object_string
    1279             :    *  [json_object]        [json_object]
    1280             :      *  ...other fields...   ...other fields...
    1281             :    *  c_string]            len
    1282             :      *                       bytes
    1283             :    *                       of
    1284             :    *                       string
    1285             :    *                       data
    1286             :      *                       \0]
    1287             :    */
    1288     1534110 :   if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1))
    1289           0 :     return NULL;
    1290     1534110 :   objsize = (sizeof(*jso) - sizeof(jso->c_string)) + len + 1;
    1291     1534110 :   if (len < sizeof(void *))
    1292             :     // We need a minimum size to support json_object_set_string() mutability
    1293             :     // so we can stuff a pointer into pdata :(
    1294      431473 :     objsize += sizeof(void *) - len;
    1295             : 
    1296     1534110 :   jso = (struct json_object_string *)json_object_new(json_type_string, objsize,
    1297             :                                                      &json_object_string_to_json_string);
    1298             : 
    1299     1534110 :   if (!jso)
    1300           0 :     return NULL;
    1301     1534110 :   jso->len = len;
    1302             :   char* strdata;
    1303     1534110 :   uintptr_t strdata_addr = (uintptr_t)&(jso->c_string.idata);
    1304     1534110 :   memcpy(&strdata, &(strdata_addr), sizeof(char*));
    1305     1534110 :   memcpy(strdata, s, len);
    1306     1534110 :   strdata[len] = '\0';
    1307     1534110 :   return &jso->base;
    1308             : }
    1309             : 
    1310       87535 : struct json_object *json_object_new_string(const char *s)
    1311             : {
    1312       87535 :   return _json_object_new_string(s, strlen(s));
    1313             : }
    1314             : 
    1315     1446580 : struct json_object *json_object_new_string_len(const char *s, const int len)
    1316             : {
    1317     1446580 :   return _json_object_new_string(s, len);
    1318             : }
    1319             : 
    1320      468927 : const char *json_object_get_string(struct json_object *jso)
    1321             : {
    1322      468927 :   if (!jso)
    1323          24 :     return NULL;
    1324      468903 :   switch (jso->o_type)
    1325             :   {
    1326      460295 :   case json_type_string: return get_string_component(jso);
    1327        8608 :   default: return json_object_to_json_string(jso);
    1328             :   }
    1329             : }
    1330           0 : int json_object_get_string_len(const struct json_object *jso)
    1331             : {
    1332             :   ssize_t len;
    1333           0 :   if (!jso)
    1334           0 :     return 0;
    1335           0 :   switch (jso->o_type)
    1336             :   {
    1337           0 :   case json_type_string:
    1338             :   {
    1339           0 :     len = JC_STRING_C(jso)->len;
    1340           0 :     return (len < 0) ? (int)(-(ssize_t)len) : (int)len;
    1341             :   }
    1342           0 :   default: return 0;
    1343             :   }
    1344             : }
    1345             : 
    1346           0 : static int _json_object_set_string_len(json_object *jso, const char *s, size_t len)
    1347             : {
    1348             :   char *dstbuf;
    1349             :   ssize_t curlen;
    1350             :   ssize_t newlen;
    1351           0 :   if (jso == NULL || jso->o_type != json_type_string)
    1352           0 :     return 0;
    1353             : 
    1354           0 :   if (len >= SSIZE_T_MAX - 1)
    1355             :     // jso->len is a signed ssize_t, so it can't hold the
    1356             :     // full size_t range.
    1357           0 :     return 0;
    1358             : 
    1359           0 :   dstbuf = get_string_component_mutable(jso);
    1360           0 :   curlen = JC_STRING(jso)->len;
    1361           0 :   if (curlen < 0)
    1362           0 :     curlen = -curlen;
    1363           0 :   newlen = len;
    1364             : 
    1365           0 :   if ((ssize_t)len > curlen)
    1366             :   {
    1367             :     // We have no way to return the new ptr from realloc(jso, newlen)
    1368             :     // and we have no way of knowing whether there's extra room available
    1369             :     // so we need to stuff a pointer in to pdata :(
    1370           0 :     dstbuf = (char *)malloc(len + 1);
    1371           0 :     if (dstbuf == NULL)
    1372           0 :       return 0;
    1373           0 :     if (JC_STRING(jso)->len < 0)
    1374           0 :       free(JC_STRING(jso)->c_string.pdata);
    1375           0 :     JC_STRING(jso)->c_string.pdata = dstbuf;
    1376           0 :     newlen = -(ssize_t)len;
    1377             :   }
    1378           0 :   else if (JC_STRING(jso)->len < 0)
    1379             :   {
    1380             :     // We've got enough room in the separate allocated buffer,
    1381             :     // so use it as-is and continue to indicate that pdata is used.
    1382           0 :     newlen = -(ssize_t)len;
    1383             :   }
    1384             : 
    1385           0 :   memcpy(dstbuf, (const void *)s, len);
    1386           0 :   dstbuf[len] = '\0';
    1387           0 :   JC_STRING(jso)->len = newlen;
    1388           0 :   return 1;
    1389             : }
    1390             : 
    1391           0 : int json_object_set_string(json_object *jso, const char *s)
    1392             : {
    1393           0 :   return _json_object_set_string_len(jso, s, strlen(s));
    1394             : }
    1395             : 
    1396           0 : int json_object_set_string_len(json_object *jso, const char *s, int len)
    1397             : {
    1398           0 :   return _json_object_set_string_len(jso, s, len);
    1399             : }
    1400             : 
    1401             : /* json_object_array */
    1402             : 
    1403      101726 : static int json_object_array_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
    1404             :                                             int flags)
    1405             : {
    1406      101726 :   int had_children = 0;
    1407             :   size_t ii;
    1408             : 
    1409      101726 :   printbuf_strappend(pb, "[");
    1410      101726 :   if (flags & JSON_C_TO_STRING_PRETTY)
    1411       63512 :     printbuf_strappend(pb, "\n");
    1412      348629 :   for (ii = 0; ii < json_object_array_length(jso); ii++)
    1413             :   {
    1414             :     struct json_object *val;
    1415      246903 :     if (had_children)
    1416             :     {
    1417      150564 :       printbuf_strappend(pb, ",");
    1418      150564 :       if (flags & JSON_C_TO_STRING_PRETTY)
    1419      113703 :         printbuf_strappend(pb, "\n");
    1420             :     }
    1421      246903 :     had_children = 1;
    1422      246903 :     if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
    1423       61208 :       printbuf_strappend(pb, " ");
    1424      246903 :     indent(pb, level + 1, flags);
    1425      246903 :     val = json_object_array_get_idx(jso, ii);
    1426      246903 :     if (val == NULL)
    1427        2394 :       printbuf_strappend(pb, "null");
    1428      244509 :     else if (val->_to_json_string(val, pb, level + 1, flags) < 0)
    1429           0 :       return -1;
    1430             :   }
    1431      101726 :   if (flags & JSON_C_TO_STRING_PRETTY)
    1432             :   {
    1433       63512 :     if (had_children)
    1434       58632 :       printbuf_strappend(pb, "\n");
    1435       63512 :     indent(pb, level, flags);
    1436             :   }
    1437             : 
    1438      101726 :   if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
    1439       31022 :     return printbuf_strappend(pb, " ]");
    1440       70704 :   return printbuf_strappend(pb, "]");
    1441             : }
    1442             : 
    1443     1795920 : static void json_object_array_entry_free(void *data)
    1444             : {
    1445     1795920 :   json_object_put((struct json_object *)data);
    1446     1795920 : }
    1447             : 
    1448      551742 : static void json_object_array_delete(struct json_object *jso)
    1449             : {
    1450      551742 :   array_list_free(JC_ARRAY(jso)->c_array);
    1451      551742 :   json_object_generic_delete(jso);
    1452      551742 : }
    1453             : 
    1454      551742 : struct json_object *json_object_new_array(void)
    1455             : {
    1456      551742 :   return json_object_new_array_ext(ARRAY_LIST_DEFAULT_SIZE);
    1457             : }
    1458      551742 : struct json_object *json_object_new_array_ext(int initial_size)
    1459             : {
    1460      551742 :   struct json_object_array *jso = JSON_OBJECT_NEW(array);
    1461      551742 :   if (!jso)
    1462           0 :     return NULL;
    1463      551742 :   jso->c_array = array_list_new2(&json_object_array_entry_free, initial_size);
    1464      551742 :   if (jso->c_array == NULL)
    1465             :   {
    1466           0 :     free(jso);
    1467           0 :     return NULL;
    1468             :   }
    1469      551742 :   return &jso->base;
    1470             : }
    1471             : 
    1472           0 : struct array_list *json_object_get_array(const struct json_object *jso)
    1473             : {
    1474           0 :   if (!jso)
    1475           0 :     return NULL;
    1476           0 :   switch (jso->o_type)
    1477             :   {
    1478           0 :   case json_type_array: return JC_ARRAY_C(jso)->c_array;
    1479           0 :   default: return NULL;
    1480             :   }
    1481             : }
    1482             : 
    1483           0 : void json_object_array_sort(struct json_object *jso, int (*sort_fn)(const void *, const void *))
    1484             : {
    1485           0 :   assert(json_object_get_type(jso) == json_type_array);
    1486           0 :   array_list_sort(JC_ARRAY(jso)->c_array, sort_fn);
    1487           0 : }
    1488             : 
    1489           0 : struct json_object *json_object_array_bsearch(const struct json_object *key,
    1490             :                                               const struct json_object *jso,
    1491             :                                               int (*sort_fn)(const void *, const void *))
    1492             : {
    1493             :   struct json_object **result;
    1494             : 
    1495           0 :   assert(json_object_get_type(jso) == json_type_array);
    1496           0 :   result = (struct json_object **)array_list_bsearch((const void **)(void *)&key,
    1497           0 :                                                      JC_ARRAY_C(jso)->c_array, sort_fn);
    1498             : 
    1499           0 :   if (!result)
    1500           0 :     return NULL;
    1501           0 :   return *result;
    1502             : }
    1503             : 
    1504     1026270 : size_t json_object_array_length(const struct json_object *jso)
    1505             : {
    1506     1026270 :   assert(json_object_get_type(jso) == json_type_array);
    1507     1026060 :   return array_list_length(JC_ARRAY_C(jso)->c_array);
    1508             : }
    1509             : 
    1510     1798400 : int json_object_array_add(struct json_object *jso, struct json_object *val)
    1511             : {
    1512     1798400 :   assert(json_object_get_type(jso) == json_type_array);
    1513     1798400 :   return array_list_add(JC_ARRAY(jso)->c_array, val);
    1514             : }
    1515             : 
    1516           0 : int json_object_array_put_idx(struct json_object *jso, size_t idx, struct json_object *val)
    1517             : {
    1518           0 :   assert(json_object_get_type(jso) == json_type_array);
    1519           0 :   return array_list_put_idx(JC_ARRAY(jso)->c_array, idx, val);
    1520             : }
    1521             : 
    1522           0 : int json_object_array_del_idx(struct json_object *jso, size_t idx, size_t count)
    1523             : {
    1524           0 :   assert(json_object_get_type(jso) == json_type_array);
    1525           0 :   return array_list_del_idx(JC_ARRAY(jso)->c_array, idx, count);
    1526             : }
    1527             : 
    1528     1595330 : struct json_object *json_object_array_get_idx(const struct json_object *jso, size_t idx)
    1529             : {
    1530     1595330 :   assert(json_object_get_type(jso) == json_type_array);
    1531     1595330 :   return (struct json_object *)array_list_get_idx(JC_ARRAY_C(jso)->c_array, idx);
    1532             : }
    1533             : 
    1534           0 : static int json_array_equal(struct json_object *jso1, struct json_object *jso2)
    1535             : {
    1536             :   size_t len, i;
    1537             : 
    1538           0 :   len = json_object_array_length(jso1);
    1539           0 :   if (len != json_object_array_length(jso2))
    1540           0 :     return 0;
    1541             : 
    1542           0 :   for (i = 0; i < len; i++)
    1543             :   {
    1544           0 :     if (!json_object_equal(json_object_array_get_idx(jso1, i),
    1545             :                            json_object_array_get_idx(jso2, i)))
    1546           0 :       return 0;
    1547             :   }
    1548           0 :   return 1;
    1549             : }
    1550             : 
    1551      253189 : int json_object_array_shrink(struct json_object *jso, int empty_slots)
    1552             : {
    1553      253189 :   if (empty_slots < 0)
    1554           0 :     json_abort("json_object_array_shrink called with negative empty_slots");
    1555      253189 :   return array_list_shrink(JC_ARRAY(jso)->c_array, empty_slots);
    1556             : }
    1557             : 
    1558           4 : struct json_object *json_object_new_null(void)
    1559             : {
    1560           4 :   return NULL;
    1561             : }
    1562             : 
    1563           0 : static int json_object_all_values_equal(struct json_object *jso1, struct json_object *jso2)
    1564             : {
    1565             :   struct json_object_iter iter;
    1566             :   struct json_object *sub;
    1567             : 
    1568           0 :   assert(json_object_get_type(jso1) == json_type_object);
    1569           0 :   assert(json_object_get_type(jso2) == json_type_object);
    1570             :   /* Iterate over jso1 keys and see if they exist and are equal in jso2 */
    1571           0 :   json_object_object_foreachC(jso1, iter)
    1572             :   {
    1573           0 :     if (!lh_table_lookup_ex(JC_OBJECT(jso2)->c_object, (void *)iter.key,
    1574             :                             (void **)(void *)&sub))
    1575           0 :       return 0;
    1576           0 :     if (!json_object_equal(iter.val, sub))
    1577           0 :       return 0;
    1578             :   }
    1579             : 
    1580             :   /* Iterate over jso2 keys to see if any exist that are not in jso1 */
    1581           0 :   json_object_object_foreachC(jso2, iter)
    1582             :   {
    1583           0 :     if (!lh_table_lookup_ex(JC_OBJECT(jso1)->c_object, (void *)iter.key,
    1584             :                             (void **)(void *)&sub))
    1585           0 :       return 0;
    1586             :   }
    1587             : 
    1588           0 :   return 1;
    1589             : }
    1590             : 
    1591           0 : int json_object_equal(struct json_object *jso1, struct json_object *jso2)
    1592             : {
    1593           0 :   if (jso1 == jso2)
    1594           0 :     return 1;
    1595             : 
    1596           0 :   if (!jso1 || !jso2)
    1597           0 :     return 0;
    1598             : 
    1599           0 :   if (jso1->o_type != jso2->o_type)
    1600           0 :     return 0;
    1601             : 
    1602           0 :   switch (jso1->o_type)
    1603             :   {
    1604           0 :   case json_type_boolean: return (JC_BOOL(jso1)->c_boolean == JC_BOOL(jso2)->c_boolean);
    1605             : 
    1606           0 :   case json_type_double: return (JC_DOUBLE(jso1)->c_double == JC_DOUBLE(jso2)->c_double);
    1607             : 
    1608           0 :   case json_type_int:
    1609             :   {
    1610           0 :     struct json_object_int *int1 = JC_INT(jso1);
    1611           0 :     struct json_object_int *int2 = JC_INT(jso2);
    1612           0 :     if (int1->cint_type == json_object_int_type_int64)
    1613             :     {
    1614           0 :       if (int2->cint_type == json_object_int_type_int64)
    1615           0 :         return (int1->cint.c_int64 == int2->cint.c_int64);
    1616           0 :       if (int1->cint.c_int64 < 0)
    1617           0 :         return 0;
    1618           0 :       return ((uint64_t)int1->cint.c_int64 == int2->cint.c_uint64);
    1619             :     }
    1620             :     // else jso1 is a uint64
    1621           0 :     if (int2->cint_type == json_object_int_type_uint64)
    1622           0 :       return (int1->cint.c_uint64 == int2->cint.c_uint64);
    1623           0 :     if (int2->cint.c_int64 < 0)
    1624           0 :       return 0;
    1625           0 :     return (int1->cint.c_uint64 == (uint64_t)int2->cint.c_int64);
    1626             :   }
    1627             : 
    1628           0 :   case json_type_string:
    1629             :   {
    1630           0 :     return (json_object_get_string_len(jso1) == json_object_get_string_len(jso2) &&
    1631           0 :             memcmp(get_string_component(jso1), get_string_component(jso2),
    1632           0 :                    json_object_get_string_len(jso1)) == 0);
    1633             :   }
    1634             : 
    1635           0 :   case json_type_object: return json_object_all_values_equal(jso1, jso2);
    1636             : 
    1637           0 :   case json_type_array: return json_array_equal(jso1, jso2);
    1638             : 
    1639           0 :   case json_type_null: return 1;
    1640             :   };
    1641             : 
    1642           0 :   return 0;
    1643             : }
    1644             : 
    1645        1127 : static int json_object_copy_serializer_data(struct json_object *src, struct json_object *dst)
    1646             : {
    1647        1127 :   if (!src->_userdata && !src->_user_delete)
    1648        1126 :     return 0;
    1649             : 
    1650           1 :   if (dst->_to_json_string == json_object_userdata_to_json_string ||
    1651           1 :       dst->_to_json_string == _json_object_userdata_to_json_string)
    1652             :   {
    1653           0 :     assert(src->_userdata);
    1654           0 :     dst->_userdata = strdup(src->_userdata);
    1655             :   }
    1656             :   // else if ... other supported serializers ...
    1657             :   else
    1658             :   {
    1659             :         void* func_ptr;
    1660           1 :         memcpy(&func_ptr, &(dst->_to_json_string), sizeof(void*));
    1661           1 :     _json_c_set_last_err(
    1662             :         "json_object_deep_copy: unable to copy unknown serializer data: %p\n",
    1663             :         func_ptr);
    1664           1 :     return -1;
    1665             :   }
    1666           0 :   dst->_user_delete = src->_user_delete;
    1667           0 :   return 0;
    1668             : }
    1669             : 
    1670             : /**
    1671             :  * The default shallow copy implementation.  Simply creates a new object of the same
    1672             :  * type but does *not* copy over _userdata nor retain any custom serializer.
    1673             :  * If custom serializers are in use, json_object_deep_copy() must be passed a shallow copy
    1674             :  * implementation that is aware of how to copy them.
    1675             :  *
    1676             :  * This always returns -1 or 1.  It will never return 2 since it does not copy the serializer.
    1677             :  */
    1678        1127 : int json_c_shallow_copy_default(json_object *src, json_object *parent, const char *key,
    1679             :                                 size_t index, json_object **dst)
    1680             : {
    1681             :     (void)parent;
    1682             :     (void)key;
    1683             :     (void)index;
    1684        1127 :   switch (src->o_type)
    1685             :   {
    1686           0 :   case json_type_boolean: *dst = json_object_new_boolean(JC_BOOL(src)->c_boolean); break;
    1687             : 
    1688          21 :   case json_type_double: *dst = json_object_new_double(JC_DOUBLE(src)->c_double); break;
    1689             : 
    1690        1031 :   case json_type_int:
    1691        1031 :     switch (JC_INT(src)->cint_type)
    1692             :     {
    1693        1031 :     case json_object_int_type_int64:
    1694        1031 :       *dst = json_object_new_int64(JC_INT(src)->cint.c_int64);
    1695        1031 :       break;
    1696           0 :     case json_object_int_type_uint64:
    1697           0 :       *dst = json_object_new_uint64(JC_INT(src)->cint.c_uint64);
    1698           0 :       break;
    1699           0 :     default: json_abort("invalid cint_type");
    1700             :     }
    1701        1031 :     break;
    1702             : 
    1703          67 :   case json_type_string: *dst = json_object_new_string(get_string_component(src)); break;
    1704             : 
    1705           4 :   case json_type_object: *dst = json_object_new_object(); break;
    1706             : 
    1707           4 :   case json_type_array: *dst = json_object_new_array(); break;
    1708             : 
    1709           0 :   default: errno = EINVAL; return -1;
    1710             :   }
    1711             : 
    1712        1127 :   if (!*dst)
    1713             :   {
    1714           0 :     errno = ENOMEM;
    1715           0 :     return -1;
    1716             :   }
    1717        1127 :   (*dst)->_to_json_string = src->_to_json_string;
    1718             :   // _userdata and _user_delete are copied later
    1719        1127 :   return 1;
    1720             : }
    1721             : 
    1722             : /*
    1723             :  * The actual guts of json_object_deep_copy(), with a few additional args
    1724             :  * needed so we can keep track of where we are within the object tree.
    1725             :  *
    1726             :  * Note: caller is responsible for freeing *dst if this fails and returns -1.
    1727             :  */
    1728        1127 : static int json_object_deep_copy_recursive(struct json_object *src, struct json_object *parent,
    1729             :                                            const char *key_in_parent, size_t index_in_parent,
    1730             :                                            struct json_object **dst,
    1731             :                                            json_c_shallow_copy_fn *shallow_copy)
    1732             : {
    1733             :   struct json_object_iter iter;
    1734             :   size_t src_array_len, ii;
    1735             : 
    1736        1127 :   int shallow_copy_rc = 0;
    1737        1127 :   shallow_copy_rc = shallow_copy(src, parent, key_in_parent, index_in_parent, dst);
    1738             :   /* -1=error, 1=object created ok, 2=userdata set */
    1739        1127 :   if (shallow_copy_rc < 1)
    1740             :   {
    1741           0 :     errno = EINVAL;
    1742           0 :     return -1;
    1743             :   }
    1744        1127 :   assert(*dst != NULL);
    1745             : 
    1746        1127 :   switch (src->o_type)
    1747             :   {
    1748           4 :   case json_type_object:
    1749          20 :     json_object_object_foreachC(src, iter)
    1750             :     {
    1751          16 :       struct json_object *jso = NULL;
    1752             :       /* This handles the `json_type_null` case */
    1753          16 :       if (!iter.val)
    1754           0 :         jso = NULL;
    1755          16 :       else if (json_object_deep_copy_recursive(iter.val, src, iter.key, -1, &jso,
    1756             :                                                shallow_copy) < 0)
    1757             :       {
    1758           0 :         json_object_put(jso);
    1759           0 :         return -1;
    1760             :       }
    1761             : 
    1762          16 :       if (json_object_object_add(*dst, iter.key, jso) < 0)
    1763             :       {
    1764           0 :         json_object_put(jso);
    1765           0 :         return -1;
    1766             :       }
    1767             :     }
    1768           4 :     break;
    1769             : 
    1770           4 :   case json_type_array:
    1771           4 :     src_array_len = json_object_array_length(src);
    1772        1028 :     for (ii = 0; ii < src_array_len; ii++)
    1773             :     {
    1774        1024 :       struct json_object *jso = NULL;
    1775        1024 :       struct json_object *jso1 = json_object_array_get_idx(src, ii);
    1776             :       /* This handles the `json_type_null` case */
    1777        1024 :       if (!jso1)
    1778           0 :         jso = NULL;
    1779        1024 :       else if (json_object_deep_copy_recursive(jso1, src, NULL, ii, &jso,
    1780             :                                                shallow_copy) < 0)
    1781             :       {
    1782           0 :         json_object_put(jso);
    1783           0 :         return -1;
    1784             :       }
    1785             : 
    1786        1024 :       if (json_object_array_add(*dst, jso) < 0)
    1787             :       {
    1788           0 :         json_object_put(jso);
    1789           0 :         return -1;
    1790             :       }
    1791             :     }
    1792           4 :     break;
    1793             : 
    1794        1119 :   default:
    1795        1119 :     break;
    1796             :     /* else, nothing to do, shallow_copy already did. */
    1797             :   }
    1798             : 
    1799        1127 :   if (shallow_copy_rc != 2)
    1800        1127 :     return json_object_copy_serializer_data(src, *dst);
    1801             : 
    1802           0 :   return 0;
    1803             : }
    1804             : 
    1805          87 : int json_object_deep_copy(struct json_object *src, struct json_object **dst,
    1806             :                           json_c_shallow_copy_fn *shallow_copy)
    1807             : {
    1808             :   int rc;
    1809             : 
    1810             :   /* Check if arguments are sane ; *dst must not point to a non-NULL object */
    1811          87 :   if (!src || !dst || *dst)
    1812             :   {
    1813           0 :     errno = EINVAL;
    1814           0 :     return -1;
    1815             :   }
    1816             : 
    1817          87 :   if (shallow_copy == NULL)
    1818          87 :     shallow_copy = json_c_shallow_copy_default;
    1819             : 
    1820          87 :   rc = json_object_deep_copy_recursive(src, NULL, NULL, -1, dst, shallow_copy);
    1821          87 :   if (rc < 0)
    1822             :   {
    1823           1 :     json_object_put(*dst);
    1824           1 :     *dst = NULL;
    1825             :   }
    1826             : 
    1827          87 :   return rc;
    1828             : }
    1829             : 
    1830           0 : static void json_abort(const char *message)
    1831             : {
    1832           0 :   if (message != NULL)
    1833           0 :     fprintf(stderr, "json-c aborts with error: %s\n", message);
    1834           0 :   abort();
    1835             : }

Generated by: LCOV version 1.14