codeview

A light and fast web based git repository viewer

Log | Files | Refs | README | LICENSE

cJSON.c (92169B)


      1 const char *json_string = "{\"abap\":[\"abap\"],\"ags script\":[\"asc\",\"ash\"],\"ampl\":[\"ampl\"],\"antlr\":[\"g4\"],\"apl\":[\"apl\",\"dyalog\"],\"asp\":[\"asp\",\"asax\",\"ascx\",\"ashx\",\"asmx\",\"aspx\",\"axd\"],\"ats\":[\"dats\",\"hats\",\"sats\"],\"actionscript\":[\"as\"],\"ada\":[\"adb\",\"ada\",\"ads\"],\"agda\":[\"agda\"],\"alloy\":[\"als\"],\"apacheconf\":[\"apacheconf\"],\"apex\":[\"cls\"],\"applescript\":[\"applescript\",\"scpt\"],\"arc\":[\"arc\"],\"arduino\":[\"ino\"],\"asciidoc\":[\"asciidoc\",\"adoc\",\"asc\"],\"aspectj\":[\"aj\"],\"assembly\":[\"asm\",\"a51\",\"nasm\"],\"augeas\":[\"aug\"],\"autohotkey\":[\"ahk\",\"ahkl\"],\"autoit\":[\"au3\"],\"awk\":[\"awk\",\"auk\",\"gawk\",\"mawk\",\"nawk\"],\"batchfile\":[\"bat\",\"cmd\"],\"befunge\":[\"befunge\"],\"bison\":[\"y\"],\"bitbake\":[\"bb\"],\"blitzbasic\":[\"bb\",\"decls\"],\"blitzmax\":[\"bmx\"],\"bluespec\":[\"bsv\"],\"boo\":[\"boo\"],\"brainfuck\":[\"b\",\"bf\"],\"brightscript\":[\"brs\"],\"bro\":[\"bro\"],\"c\":[\"c\",\"cats\",\"h\",\"idc\",\"w\"],\"c#\":[\"cs\",\"cshtml\",\"csx\"],\"c++\":[\"cpp\",\"c++\",\"cc\",\"cp\",\"cxx\",\"h\",\"h++\",\"hh\",\"hpp\",\"hxx\",\"inl\",\"ipp\",\"tcc\",\"tpp\"],\"c-objdump\":[\"c-objdump\"],\"c2hs haskell\":[\"chs\"],\"clips\":[\"clp\"],\"cmake\":[\"cmake\",\"cmake.in\"],\"cobol\":[\"cob\",\"cbl\",\"ccp\",\"cobol\",\"cpy\"],\"css\":[\"css\"],\"cap'n proto\":[\"capnp\"],\"cartocss\":[\"mss\"],\"ceylon\":[\"ceylon\"],\"chapel\":[\"chpl\"],\"chuck\":[\"ck\"],\"cirru\":[\"cirru\"],\"clarion\":[\"clw\"],\"clean\":[\"icl\",\"dcl\"],\"clojure\":[\"clj\",\"boot\",\"cl2\",\"cljc\",\"cljs\",\"cljs.hl\",\"cljscm\",\"cljx\",\"hic\"],\"coffeescript\":[\"coffee\",\"_coffee\",\"cjsx\",\"cson\",\"iced\"],\"coldfusion\":[\"cfm\",\"cfml\"],\"coldfusion cfc\":[\"cfc\"],\"common lisp\":[\"lisp\",\"asd\",\"cl\",\"lsp\",\"ny\",\"podsl\"],\"component pascal\":[\"cp\",\"cps\"],\"cool\":[\"cl\"],\"coq\":[\"coq\",\"v\"],\"cpp-objdump\":[\"cppobjdump\",\"c++-objdump\",\"c++objdump\",\"cpp-objdump\",\"cxx-objdump\"],\"creole\":[\"creole\"],\"crystal\":[\"cr\"],\"cucumber\":[\"feature\"],\"cuda\":[\"cu\",\"cuh\"],\"cycript\":[\"cy\"],\"cython\":[\"pyx\",\"pxd\",\"pxi\"],\"d\":[\"d\",\"di\"],\"d-objdump\":[\"d-objdump\"],\"digital command language\":[\"com\"],\"dm\":[\"dm\"],\"dtrace\":[\"d\"],\"darcs patch\":[\"darcspatch\",\"dpatch\"],\"dart\":[\"dart\"],\"diff\":[\"diff\",\"patch\"],\"dockerfile\":[\"dockerfile\"],\"dogescript\":[\"djs\"],\"dylan\":[\"dylan\",\"dyl\",\"intr\",\"lid\"],\"e\":[\"E\"],\"ecl\":[\"ecl\",\"eclxml\"],\"eagle\":[\"sch\",\"brd\"],\"ecere projects\":[\"epj\"],\"eiffel\":[\"e\"],\"elixir\":[\"ex\",\"exs\"],\"elm\":[\"elm\"],\"emacs lisp\":[\"el\",\"emacs\",\"emacs.desktop\"],\"emberscript\":[\"em\",\"emberscript\"],\"erlang\":[\"erl\",\"es\",\"escript\",\"hrl\"],\"f#\":[\"fs\",\"fsi\",\"fsx\"],\"flux\":[\"fx\",\"flux\"],\"fortran\":[\"f90\",\"f\",\"f03\",\"f08\",\"f77\",\"f95\",\"for\",\"fpp\"],\"factor\":[\"factor\"],\"fancy\":[\"fy\",\"fancypack\"],\"fantom\":[\"fan\"],\"filterscript\":[\"fs\"],\"formatted\":[\"for\"],\"forth\":[\"fth\",\"4th\",\"f\",\"for\",\"forth\",\"fr\",\"frt\",\"fs\"],\"frege\":[\"fr\"],\"g-code\":[\"g\",\"gco\",\"gcode\"],\"gams\":[\"gms\"],\"gap\":[\"g\",\"gap\",\"gd\",\"gi\",\"tst\"],\"gas\":[\"s\"],\"gdscript\":[\"gd\"],\"glsl\":[\"glsl\",\"fp\",\"frag\",\"frg\",\"fs\",\"fshader\",\"geo\",\"geom\",\"glslv\",\"gshader\",\"shader\",\"vert\",\"vrx\",\"vshader\"],\"game maker language\":[\"gml\"],\"genshi\":[\"kid\"],\"gentoo ebuild\":[\"ebuild\"],\"gentoo eclass\":[\"eclass\"],\"gettext catalog\":[\"po\",\"pot\"],\"glyph\":[\"glf\"],\"gnuplot\":[\"gp\",\"gnu\",\"gnuplot\",\"plot\",\"plt\"],\"go\":[\"go\"],\"golo\":[\"golo\"],\"gosu\":[\"gs\",\"gst\",\"gsx\",\"vark\"],\"grace\":[\"grace\"],\"gradle\":[\"gradle\"],\"grammatical framework\":[\"gf\"],\"graph modeling language\":[\"gml\"],\"graphviz (dot)\":[\"dot\",\"gv\"],\"groff\":[\"man\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\"],\"groovy\":[\"groovy\",\"grt\",\"gtpl\",\"gvy\"],\"groovy server pages\":[\"gsp\"],\"html\":[\"html\",\"htm\",\"html.hl\",\"st\",\"xht\",\"xhtml\"],\"html+django\":[\"mustache\",\"jinja\"],\"html+erb\":[\"erb\",\"erb.deface\"],\"html+php\":[\"phtml\"],\"http\":[\"http\"],\"hack\":[\"hh\",\"php\"],\"haml\":[\"haml\",\"haml.deface\"],\"handlebars\":[\"handlebars\",\"hbs\"],\"harbour\":[\"hb\"],\"haskell\":[\"hs\",\"hsc\"],\"haxe\":[\"hx\",\"hxsl\"],\"hy\":[\"hy\"],\"idl\":[\"pro\",\"dlm\"],\"igor pro\":[\"ipf\"],\"ini\":[\"ini\",\"cfg\",\"prefs\",\"pro\",\"properties\"],\"irc log\":[\"irclog\",\"weechatlog\"],\"idris\":[\"idr\",\"lidr\"],\"inform 7\":[\"ni\",\"i7x\"],\"inno setup\":[\"iss\"],\"io\":[\"io\"],\"ioke\":[\"ik\"],\"isabelle\":[\"thy\"],\"j\":[\"ijs\"],\"jflex\":[\"flex\",\"jflex\"],\"json\":[\"json\",\"lock\"],\"json5\":[\"json5\"],\"jsonld\":[\"jsonld\"],\"jsoniq\":[\"jq\"],\"jade\":[\"jade\"],\"jasmin\":[\"j\"],\"java\":[\"java\"],\"java server pages\":[\"jsp\"],\"javascript\":[\"js\",\"_js\",\"bones\",\"es6\",\"frag\",\"gs\",\"jake\",\"jsb\",\"jsfl\",\"jsm\",\"jss\",\"jsx\",\"njs\",\"pac\",\"sjs\",\"ssjs\",\"sublime-build\",\"sublime-commands\",\"sublime-completions\",\"sublime-keymap\",\"sublime-macro\",\"sublime-menu\",\"sublime-mousemap\",\"sublime-project\",\"sublime-settings\",\"sublime-theme\",\"sublime-workspace\",\"sublime_metrics\",\"sublime_session\",\"xsjs\",\"xsjslib\"],\"julia\":[\"jl\"],\"krl\":[\"krl\"],\"kicad\":[\"sch\"],\"kit\":[\"kit\"],\"kotlin\":[\"kt\",\"ktm\",\"kts\"],\"lfe\":[\"lfe\"],\"llvm\":[\"ll\"],\"lolcode\":[\"lol\"],\"lsl\":[\"lsl\"],\"labview\":[\"lvproj\"],\"lasso\":[\"lasso\",\"las\",\"lasso8\",\"lasso9\",\"ldml\"],\"latte\":[\"latte\"],\"lean\":[\"lean\",\"hlean\"],\"less\":[\"less\"],\"lilypond\":[\"ly\",\"ily\"],\"limbo\":[\"b\",\"m\"],\"linker script\":[\"ld\",\"lds\"],\"liquid\":[\"liquid\"],\"literate agda\":[\"lagda\"],\"literate coffeescript\":[\"litcoffee\"],\"literate haskell\":[\"lhs\"],\"livescript\":[\"ls\",\"_ls\"],\"logos\":[\"xm\",\"x\",\"xi\"],\"logtalk\":[\"lgt\",\"logtalk\"],\"lookml\":[\"lookml\"],\"loomscript\":[\"ls\"],\"lua\":[\"lua\",\"fcgi\",\"nse\",\"pd_lua\",\"rbxs\",\"wlua\"],\"m\":[\"mumps\",\"m\"],\"mtml\":[\"mtml\"],\"muf\":[\"muf\",\"m\"],\"makefile\":[\"mak\",\"d\",\"mk\"],\"mako\":[\"mako\",\"mao\"],\"markdown\":[\"md\",\"markdown\",\"mkd\",\"mkdn\",\"mkdown\",\"ron\"],\"mask\":[\"mask\"],\"mathematica\":[\"mathematica\",\"cdf\",\"m\",\"ma\",\"nb\",\"nbp\",\"wl\",\"wlt\"],\"matlab\":[\"matlab\",\"m\"],\"max\":[\"maxpat\",\"maxhelp\",\"maxproj\",\"mxt\",\"pat\"],\"mediawiki\":[\"mediawiki\"],\"mercury\":[\"m\",\"moo\"],\"minid\":[\"minid\"],\"mirah\":[\"druby\",\"duby\",\"mir\",\"mirah\"],\"modelica\":[\"mo\"],\"module management system\":[\"mms\",\"mmk\"],\"monkey\":[\"monkey\"],\"moocode\":[\"moo\"],\"moonscript\":[\"moon\"],\"myghty\":[\"myt\"],\"nl\":[\"nl\"],\"nsis\":[\"nsi\",\"nsh\"],\"nemerle\":[\"n\"],\"netlinx\":[\"axs\",\"axi\"],\"netlinx+erb\":[\"axs.erb\",\"axi.erb\"],\"netlogo\":[\"nlogo\"],\"newlisp\":[\"nl\",\"lisp\",\"lsp\"],\"nginx\":[\"nginxconf\"],\"nimrod\":[\"nim\",\"nimrod\"],\"ninja\":[\"ninja\"],\"nit\":[\"nit\"],\"nix\":[\"nix\"],\"nu\":[\"nu\"],\"numpy\":[\"numpy\",\"numpyw\",\"numsc\"],\"ocaml\":[\"ml\",\"eliom\",\"eliomi\",\"ml4\",\"mli\",\"mll\",\"mly\"],\"objdump\":[\"objdump\"],\"objective-c\":[\"m\",\"h\"],\"objective-c++\":[\"mm\"],\"objective-j\":[\"j\",\"sj\"],\"omgrofl\":[\"omgrofl\"],\"opa\":[\"opa\"],\"opal\":[\"opal\"],\"opencl\":[\"cl\",\"opencl\"],\"openedge abl\":[\"p\",\"cls\"],\"openscad\":[\"scad\"],\"org\":[\"org\"],\"ox\":[\"ox\",\"oxh\",\"oxo\"],\"oxygene\":[\"oxygene\"],\"oz\":[\"oz\"],\"pawn\":[\"pwn\"],\"php\":[\"php\",\"aw\",\"ctp\",\"fcgi\",\"php3\",\"php4\",\"php5\",\"phpt\"],\"plsql\":[\"pls\",\"pkb\",\"pks\",\"plb\",\"plsql\",\"sql\"],\"plpgsql\":[\"sql\"],\"pan\":[\"pan\"],\"papyrus\":[\"psc\"],\"parrot\":[\"parrot\"],\"parrot assembly\":[\"pasm\"],\"parrot internal representation\":[\"pir\"],\"pascal\":[\"pas\",\"dfm\",\"dpr\",\"lpr\",\"pp\"],\"perl\":[\"pl\",\"cgi\",\"fcgi\",\"perl\",\"ph\",\"plx\",\"pm\",\"pod\",\"psgi\",\"t\"],\"perl6\":[\"6pl\",\"6pm\",\"nqp\",\"p6\",\"p6l\",\"p6m\",\"pl\",\"pl6\",\"pm\",\"pm6\",\"t\"],\"piglatin\":[\"pig\"],\"pike\":[\"pike\",\"pmod\"],\"pod\":[\"pod\"],\"pogoscript\":[\"pogo\"],\"postscript\":[\"ps\",\"eps\"],\"powershell\":[\"ps1\",\"psd1\",\"psm1\"],\"processing\":[\"pde\"],\"prolog\":[\"pl\",\"ecl\",\"pro\",\"prolog\"],\"propeller spin\":[\"spin\"],\"protocol buffer\":[\"proto\"],\"public key\":[\"asc\",\"pub\"],\"puppet\":[\"pp\"],\"pure data\":[\"pd\"],\"purebasic\":[\"pb\",\"pbi\"],\"purescript\":[\"purs\"],\"python\":[\"py\",\"cgi\",\"fcgi\",\"gyp\",\"lmi\",\"pyde\",\"pyp\",\"pyt\",\"pyw\",\"tac\",\"wsgi\",\"xpy\"],\"python traceback\":[\"pytb\"],\"qml\":[\"qml\"],\"qmake\":[\"pro\",\"pri\"],\"r\":[\"r\",\"rd\",\"rsx\"],\"raml\":[\"raml\"],\"rdoc\":[\"rdoc\"],\"realbasic\":[\"rbbas\",\"rbfrm\",\"rbmnu\",\"rbres\",\"rbtbar\",\"rbuistate\"],\"rhtml\":[\"rhtml\"],\"rmarkdown\":[\"rmd\"],\"racket\":[\"rkt\",\"rktd\",\"rktl\",\"scrbl\"],\"ragel in ruby host\":[\"rl\"],\"raw token data\":[\"raw\"],\"rebol\":[\"reb\",\"r\",\"r2\",\"r3\",\"rebol\"],\"red\":[\"red\",\"reds\"],\"redcode\":[\"cw\"],\"robotframework\":[\"robot\"],\"rouge\":[\"rg\"],\"ruby\":[\"rb\",\"builder\",\"fcgi\",\"gemspec\",\"god\",\"irbrc\",\"jbuilder\",\"mspec\",\"pluginspec\",\"podspec\",\"rabl\",\"rake\",\"rbuild\",\"rbw\",\"rbx\",\"ru\",\"ruby\",\"thor\",\"watchr\"],\"rust\":[\"rs\"],\"sas\":[\"sas\"],\"scss\":[\"scss\"],\"sparql\":[\"sparql\",\"rq\"],\"sqf\":[\"sqf\",\"hqf\"],\"sql\":[\"sql\",\"cql\",\"ddl\",\"prc\",\"tab\",\"udf\",\"viw\"],\"sqlpl\":[\"sql\",\"db2\"],\"ston\":[\"ston\"],\"svg\":[\"svg\"],\"sage\":[\"sage\",\"sagews\"],\"saltstack\":[\"sls\"],\"sass\":[\"sass\"],\"scala\":[\"scala\",\"sbt\",\"sc\"],\"scaml\":[\"scaml\"],\"scheme\":[\"scm\",\"sld\",\"sls\",\"sps\",\"ss\"],\"scilab\":[\"sci\",\"sce\",\"tst\"],\"self\":[\"self\"],\"shell\":[\"sh\",\"bash\",\"bats\",\"cgi\",\"command\",\"fcgi\",\"ksh\",\"tmux\",\"tool\",\"zsh\"],\"shellsession\":[\"sh-session\"],\"shen\":[\"shen\"],\"slash\":[\"sl\"],\"slim\":[\"slim\"],\"smalltalk\":[\"st\",\"cs\"],\"smarty\":[\"tpl\"],\"sourcepawn\":[\"sp\",\"sma\"],\"squirrel\":[\"nut\"],\"standard ml\":[\"ML\",\"fun\",\"sig\",\"sml\"],\"stata\":[\"do\",\"ado\",\"doh\",\"ihlp\",\"mata\",\"matah\",\"sthlp\"],\"stylus\":[\"styl\"],\"supercollider\":[\"scd\",\"sc\"],\"swift\":[\"swift\"],\"systemverilog\":[\"sv\",\"svh\",\"vh\"],\"toml\":[\"toml\"],\"txl\":[\"txl\"],\"tcl\":[\"tcl\",\"adp\",\"tm\"],\"tcsh\":[\"tcsh\",\"csh\"],\"tex\":[\"tex\",\"aux\",\"bbx\",\"bib\",\"cbx\",\"cls\",\"dtx\",\"ins\",\"lbx\",\"ltx\",\"mkii\",\"mkiv\",\"mkvi\",\"sty\",\"toc\"],\"tea\":[\"tea\"],\"text\":[\"txt\",\"fr\"],\"textile\":[\"textile\"],\"thrift\":[\"thrift\"],\"turing\":[\"t\",\"tu\"],\"turtle\":[\"ttl\"],\"twig\":[\"twig\"],\"typescript\":[\"ts\"],\"unified parallel c\":[\"upc\"],\"unrealscript\":[\"uc\"],\"vcl\":[\"vcl\"],\"vhdl\":[\"vhdl\",\"vhd\",\"vhf\",\"vhi\",\"vho\",\"vhs\",\"vht\",\"vhw\"],\"vala\":[\"vala\",\"vapi\"],\"verilog\":[\"v\",\"veo\"],\"viml\":[\"vim\"],\"visual basic\":[\"vb\",\"bas\",\"cls\",\"frm\",\"frx\",\"vba\",\"vbhtml\",\"vbs\"],\"volt\":[\"volt\"],\"web ontology language\":[\"owl\"],\"webidl\":[\"webidl\"],\"xc\":[\"xc\"],\"xml\":[\"xml\",\"ant\",\"axml\",\"ccxml\",\"clixml\",\"cproject\",\"csproj\",\"ct\",\"dita\",\"ditamap\",\"ditaval\",\"dll.config\",\"filters\",\"fsproj\",\"fxml\",\"glade\",\"grxml\",\"ivy\",\"jelly\",\"kml\",\"launch\",\"mm\",\"mxml\",\"nproj\",\"nuspec\",\"odd\",\"osm\",\"plist\",\"pluginspec\",\"ps1xml\",\"psc1\",\"pt\",\"rdf\",\"rss\",\"scxml\",\"srdf\",\"storyboard\",\"stTheme\",\"sublime-snippet\",\"targets\",\"tmCommand\",\"tml\",\"tmLanguage\",\"tmPreferences\",\"tmSnippet\",\"tmTheme\",\"ts\",\"ui\",\"urdf\",\"vbproj\",\"vcxproj\",\"vxml\",\"wsdl\",\"wsf\",\"wxi\",\"wxl\",\"wxs\",\"x3d\",\"xacro\",\"xaml\",\"xib\",\"xlf\",\"xliff\",\"xmi\",\"xml.dist\",\"xsd\",\"xul\",\"zcml\"],\"xproc\":[\"xpl\",\"xproc\"],\"xquery\":[\"xquery\",\"xq\",\"xql\",\"xqm\",\"xqy\"],\"xs\":[\"xs\"],\"xslt\":[\"xslt\",\"xsl\"],\"xojo\":[\"xojo_code\",\"xojo_menu\",\"xojo_report\",\"xojo_script\",\"xojo_toolbar\",\"xojo_window\"],\"xtend\":[\"xtend\"],\"yaml\":[\"yml\",\"reek\",\"rviz\",\"yaml\"],\"zephir\":[\"zep\"],\"zimpl\":[\"zimpl\",\"zmpl\",\"zpl\"],\"desktop\":[\"desktop\",\"desktop.in\"],\"ec\":[\"ec\",\"eh\"],\"edn\":[\"edn\"],\"fish\":[\"fish\"],\"mupad\":[\"mu\"],\"nesc\":[\"nc\"],\"ooc\":[\"ooc\"],\"restructuredtext\":[\"rst\",\"rest\"],\"wisp\":[\"wisp\"],\"xbase\":[\"prg\"]}";
      2 
      3 /*
      4   Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
      5 
      6   Permission is hereby granted, free of charge, to any person obtaining a copy
      7   of this software and associated documentation files (the "Software"), to deal
      8   in the Software without restriction, including without limitation the rights
      9   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10   copies of the Software, and to permit persons to whom the Software is
     11   furnished to do so, subject to the following conditions:
     12 
     13   The above copyright notice and this permission notice shall be included in
     14   all copies or substantial portions of the Software.
     15 
     16   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22   THE SOFTWARE.
     23 */
     24 
     25 /* cJSON */
     26 /* JSON parser in C. */
     27 
     28 /* disable warnings about old C89 functions in MSVC */
     29 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
     30 #define _CRT_SECURE_NO_DEPRECATE
     31 #endif
     32 
     33 #ifdef __GNUC__
     34 #pragma GCC visibility push(default)
     35 #endif
     36 #if defined(_MSC_VER)
     37 #pragma warning (push)
     38 /* disable warning about single line comments in system headers */
     39 #pragma warning (disable : 4001)
     40 #endif
     41 
     42 #include <string.h>
     43 #include <stdio.h>
     44 #include <math.h>
     45 #include <stdlib.h>
     46 #include <limits.h>
     47 #include <ctype.h>
     48 #include <float.h>
     49 
     50 #ifdef ENABLE_LOCALES
     51 #include <locale.h>
     52 #endif
     53 
     54 #if defined(_MSC_VER)
     55 #pragma warning (pop)
     56 #endif
     57 #ifdef __GNUC__
     58 #pragma GCC visibility pop
     59 #endif
     60 
     61 #include "cJSON.h"
     62 
     63 /* define our own boolean type */
     64 #ifdef true
     65 #undef true
     66 #endif
     67 #define true ((cJSON_bool)1)
     68 
     69 #ifdef false
     70 #undef false
     71 #endif
     72 #define false ((cJSON_bool)0)
     73 
     74 /* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */
     75 #ifndef isinf
     76 #define isinf(d) (isnan((d - d)) && !isnan(d))
     77 #endif
     78 #ifndef isnan
     79 #define isnan(d) (d != d)
     80 #endif
     81 
     82 #ifndef NAN
     83 #ifdef _WIN32
     84 #define NAN sqrt(-1.0)
     85 #else
     86 #define NAN 0.0/0.0
     87 #endif
     88 #endif
     89 
     90 typedef struct {
     91     const unsigned char *json;
     92     size_t position;
     93 } error;
     94 static error global_error = { NULL, 0 };
     95 
     96 CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
     97 {
     98     return (const char*) (global_error.json + global_error.position);
     99 }
    100 
    101 CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
    102 {
    103     if (!cJSON_IsString(item))
    104     {
    105         return NULL;
    106     }
    107 
    108     return item->valuestring;
    109 }
    110 
    111 CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
    112 {
    113     if (!cJSON_IsNumber(item))
    114     {
    115         return (double) NAN;
    116     }
    117 
    118     return item->valuedouble;
    119 }
    120 
    121 /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
    122 #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 18)
    123     #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
    124 #endif
    125 
    126 CJSON_PUBLIC(const char*) cJSON_Version(void)
    127 {
    128     static char version[15];
    129     sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
    130 
    131     return version;
    132 }
    133 
    134 /* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
    135 static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
    136 {
    137     if ((string1 == NULL) || (string2 == NULL))
    138     {
    139         return 1;
    140     }
    141 
    142     if (string1 == string2)
    143     {
    144         return 0;
    145     }
    146 
    147     for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
    148     {
    149         if (*string1 == '\0')
    150         {
    151             return 0;
    152         }
    153     }
    154 
    155     return tolower(*string1) - tolower(*string2);
    156 }
    157 
    158 typedef struct internal_hooks
    159 {
    160     void *(CJSON_CDECL *allocate)(size_t size);
    161     void (CJSON_CDECL *deallocate)(void *pointer);
    162     void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
    163 } internal_hooks;
    164 
    165 #if defined(_MSC_VER)
    166 /* work around MSVC error C2322: '...' address of dllimport '...' is not static */
    167 static void * CJSON_CDECL internal_malloc(size_t size)
    168 {
    169     return malloc(size);
    170 }
    171 static void CJSON_CDECL internal_free(void *pointer)
    172 {
    173     free(pointer);
    174 }
    175 static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
    176 {
    177     return realloc(pointer, size);
    178 }
    179 #else
    180 #define internal_malloc malloc
    181 #define internal_free free
    182 #define internal_realloc realloc
    183 #endif
    184 
    185 /* strlen of character literals resolved at compile time */
    186 #define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
    187 
    188 static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
    189 
    190 static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
    191 {
    192     size_t length = 0;
    193     unsigned char *copy = NULL;
    194 
    195     if (string == NULL)
    196     {
    197         return NULL;
    198     }
    199 
    200     length = strlen((const char*)string) + sizeof("");
    201     copy = (unsigned char*)hooks->allocate(length);
    202     if (copy == NULL)
    203     {
    204         return NULL;
    205     }
    206     memcpy(copy, string, length);
    207 
    208     return copy;
    209 }
    210 
    211 CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
    212 {
    213     if (hooks == NULL)
    214     {
    215         /* Reset hooks */
    216         global_hooks.allocate = malloc;
    217         global_hooks.deallocate = free;
    218         global_hooks.reallocate = realloc;
    219         return;
    220     }
    221 
    222     global_hooks.allocate = malloc;
    223     if (hooks->malloc_fn != NULL)
    224     {
    225         global_hooks.allocate = hooks->malloc_fn;
    226     }
    227 
    228     global_hooks.deallocate = free;
    229     if (hooks->free_fn != NULL)
    230     {
    231         global_hooks.deallocate = hooks->free_fn;
    232     }
    233 
    234     /* use realloc only if both free and malloc are used */
    235     global_hooks.reallocate = NULL;
    236     if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
    237     {
    238         global_hooks.reallocate = realloc;
    239     }
    240 }
    241 
    242 /* Internal constructor. */
    243 static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
    244 {
    245     cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
    246     if (node)
    247     {
    248         memset(node, '\0', sizeof(cJSON));
    249     }
    250 
    251     return node;
    252 }
    253 
    254 /* Delete a cJSON structure. */
    255 CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
    256 {
    257     cJSON *next = NULL;
    258     while (item != NULL)
    259     {
    260         next = item->next;
    261         if (!(item->type & cJSON_IsReference) && (item->child != NULL))
    262         {
    263             cJSON_Delete(item->child);
    264         }
    265         if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
    266         {
    267             global_hooks.deallocate(item->valuestring);
    268             item->valuestring = NULL;
    269         }
    270         if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
    271         {
    272             global_hooks.deallocate(item->string);
    273             item->string = NULL;
    274         }
    275         global_hooks.deallocate(item);
    276         item = next;
    277     }
    278 }
    279 
    280 /* get the decimal point character of the current locale */
    281 static unsigned char get_decimal_point(void)
    282 {
    283 #ifdef ENABLE_LOCALES
    284     struct lconv *lconv = localeconv();
    285     return (unsigned char) lconv->decimal_point[0];
    286 #else
    287     return '.';
    288 #endif
    289 }
    290 
    291 typedef struct
    292 {
    293     const unsigned char *content;
    294     size_t length;
    295     size_t offset;
    296     size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
    297     internal_hooks hooks;
    298 } parse_buffer;
    299 
    300 /* check if the given size is left to read in a given parse buffer (starting with 1) */
    301 #define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
    302 /* check if the buffer can be accessed at the given index (starting with 0) */
    303 #define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
    304 #define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
    305 /* get a pointer to the buffer at the position */
    306 #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
    307 
    308 /* Parse the input text to generate a number, and populate the result into item. */
    309 static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
    310 {
    311     double number = 0;
    312     unsigned char *after_end = NULL;
    313     unsigned char number_c_string[64];
    314     unsigned char decimal_point = get_decimal_point();
    315     size_t i = 0;
    316 
    317     if ((input_buffer == NULL) || (input_buffer->content == NULL))
    318     {
    319         return false;
    320     }
    321 
    322     /* copy the number into a temporary buffer and replace '.' with the decimal point
    323      * of the current locale (for strtod)
    324      * This also takes care of '\0' not necessarily being available for marking the end of the input */
    325     for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
    326     {
    327         switch (buffer_at_offset(input_buffer)[i])
    328         {
    329             case '0':
    330             case '1':
    331             case '2':
    332             case '3':
    333             case '4':
    334             case '5':
    335             case '6':
    336             case '7':
    337             case '8':
    338             case '9':
    339             case '+':
    340             case '-':
    341             case 'e':
    342             case 'E':
    343                 number_c_string[i] = buffer_at_offset(input_buffer)[i];
    344                 break;
    345 
    346             case '.':
    347                 number_c_string[i] = decimal_point;
    348                 break;
    349 
    350             default:
    351                 goto loop_end;
    352         }
    353     }
    354 loop_end:
    355     number_c_string[i] = '\0';
    356 
    357     number = strtod((const char*)number_c_string, (char**)&after_end);
    358     if (number_c_string == after_end)
    359     {
    360         return false; /* parse_error */
    361     }
    362 
    363     item->valuedouble = number;
    364 
    365     /* use saturation in case of overflow */
    366     if (number >= INT_MAX)
    367     {
    368         item->valueint = INT_MAX;
    369     }
    370     else if (number <= (double)INT_MIN)
    371     {
    372         item->valueint = INT_MIN;
    373     }
    374     else
    375     {
    376         item->valueint = (int)number;
    377     }
    378 
    379     item->type = cJSON_Number;
    380 
    381     input_buffer->offset += (size_t)(after_end - number_c_string);
    382     return true;
    383 }
    384 
    385 /* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
    386 CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
    387 {
    388     if (number >= INT_MAX)
    389     {
    390         object->valueint = INT_MAX;
    391     }
    392     else if (number <= (double)INT_MIN)
    393     {
    394         object->valueint = INT_MIN;
    395     }
    396     else
    397     {
    398         object->valueint = (int)number;
    399     }
    400 
    401     return object->valuedouble = number;
    402 }
    403 
    404 /* Note: when passing a NULL valuestring, cJSON_SetValuestring treats this as an error and return NULL */
    405 CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
    406 {
    407     char *copy = NULL;
    408     size_t v1_len;
    409     size_t v2_len;
    410     /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
    411     if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
    412     {
    413         return NULL;
    414     }
    415     /* return NULL if the object is corrupted or valuestring is NULL */
    416     if (object->valuestring == NULL || valuestring == NULL)
    417     {
    418         return NULL;
    419     }
    420 
    421     v1_len = strlen(valuestring);
    422     v2_len = strlen(object->valuestring);
    423 
    424     if (v1_len <= v2_len)
    425     {
    426         /* strcpy does not handle overlapping string: [X1, X2] [Y1, Y2] => X2 < Y1 or Y2 < X1 */
    427         if (!( valuestring + v1_len < object->valuestring || object->valuestring + v2_len < valuestring ))
    428         {
    429             return NULL;
    430         }
    431         strcpy(object->valuestring, valuestring);
    432         return object->valuestring;
    433     }
    434     copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks);
    435     if (copy == NULL)
    436     {
    437         return NULL;
    438     }
    439     if (object->valuestring != NULL)
    440     {
    441         cJSON_free(object->valuestring);
    442     }
    443     object->valuestring = copy;
    444 
    445     return copy;
    446 }
    447 
    448 typedef struct
    449 {
    450     unsigned char *buffer;
    451     size_t length;
    452     size_t offset;
    453     size_t depth; /* current nesting depth (for formatted printing) */
    454     cJSON_bool noalloc;
    455     cJSON_bool format; /* is this print a formatted print */
    456     internal_hooks hooks;
    457 } printbuffer;
    458 
    459 /* realloc printbuffer if necessary to have at least "needed" bytes more */
    460 static unsigned char* ensure(printbuffer * const p, size_t needed)
    461 {
    462     unsigned char *newbuffer = NULL;
    463     size_t newsize = 0;
    464 
    465     if ((p == NULL) || (p->buffer == NULL))
    466     {
    467         return NULL;
    468     }
    469 
    470     if ((p->length > 0) && (p->offset >= p->length))
    471     {
    472         /* make sure that offset is valid */
    473         return NULL;
    474     }
    475 
    476     if (needed > INT_MAX)
    477     {
    478         /* sizes bigger than INT_MAX are currently not supported */
    479         return NULL;
    480     }
    481 
    482     needed += p->offset + 1;
    483     if (needed <= p->length)
    484     {
    485         return p->buffer + p->offset;
    486     }
    487 
    488     if (p->noalloc) {
    489         return NULL;
    490     }
    491 
    492     /* calculate new buffer size */
    493     if (needed > (INT_MAX / 2))
    494     {
    495         /* overflow of int, use INT_MAX if possible */
    496         if (needed <= INT_MAX)
    497         {
    498             newsize = INT_MAX;
    499         }
    500         else
    501         {
    502             return NULL;
    503         }
    504     }
    505     else
    506     {
    507         newsize = needed * 2;
    508     }
    509 
    510     if (p->hooks.reallocate != NULL)
    511     {
    512         /* reallocate with realloc if available */
    513         newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
    514         if (newbuffer == NULL)
    515         {
    516             p->hooks.deallocate(p->buffer);
    517             p->length = 0;
    518             p->buffer = NULL;
    519 
    520             return NULL;
    521         }
    522     }
    523     else
    524     {
    525         /* otherwise reallocate manually */
    526         newbuffer = (unsigned char*)p->hooks.allocate(newsize);
    527         if (!newbuffer)
    528         {
    529             p->hooks.deallocate(p->buffer);
    530             p->length = 0;
    531             p->buffer = NULL;
    532 
    533             return NULL;
    534         }
    535 
    536         memcpy(newbuffer, p->buffer, p->offset + 1);
    537         p->hooks.deallocate(p->buffer);
    538     }
    539     p->length = newsize;
    540     p->buffer = newbuffer;
    541 
    542     return newbuffer + p->offset;
    543 }
    544 
    545 /* calculate the new length of the string in a printbuffer and update the offset */
    546 static void update_offset(printbuffer * const buffer)
    547 {
    548     const unsigned char *buffer_pointer = NULL;
    549     if ((buffer == NULL) || (buffer->buffer == NULL))
    550     {
    551         return;
    552     }
    553     buffer_pointer = buffer->buffer + buffer->offset;
    554 
    555     buffer->offset += strlen((const char*)buffer_pointer);
    556 }
    557 
    558 /* securely comparison of floating-point variables */
    559 static cJSON_bool compare_double(double a, double b)
    560 {
    561     double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
    562     return (fabs(a - b) <= maxVal * DBL_EPSILON);
    563 }
    564 
    565 /* Render the number nicely from the given item into a string. */
    566 static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
    567 {
    568     unsigned char *output_pointer = NULL;
    569     double d = item->valuedouble;
    570     int length = 0;
    571     size_t i = 0;
    572     unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */
    573     unsigned char decimal_point = get_decimal_point();
    574     double test = 0.0;
    575 
    576     if (output_buffer == NULL)
    577     {
    578         return false;
    579     }
    580 
    581     /* This checks for NaN and Infinity */
    582     if (isnan(d) || isinf(d))
    583     {
    584         length = sprintf((char*)number_buffer, "null");
    585     }
    586     else if(d == (double)item->valueint)
    587     {
    588         length = sprintf((char*)number_buffer, "%d", item->valueint);
    589     }
    590     else
    591     {
    592         /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
    593         length = sprintf((char*)number_buffer, "%1.15g", d);
    594 
    595         /* Check whether the original double can be recovered */
    596         if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
    597         {
    598             /* If not, print with 17 decimal places of precision */
    599             length = sprintf((char*)number_buffer, "%1.17g", d);
    600         }
    601     }
    602 
    603     /* sprintf failed or buffer overrun occurred */
    604     if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
    605     {
    606         return false;
    607     }
    608 
    609     /* reserve appropriate space in the output */
    610     output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
    611     if (output_pointer == NULL)
    612     {
    613         return false;
    614     }
    615 
    616     /* copy the printed number to the output and replace locale
    617      * dependent decimal point with '.' */
    618     for (i = 0; i < ((size_t)length); i++)
    619     {
    620         if (number_buffer[i] == decimal_point)
    621         {
    622             output_pointer[i] = '.';
    623             continue;
    624         }
    625 
    626         output_pointer[i] = number_buffer[i];
    627     }
    628     output_pointer[i] = '\0';
    629 
    630     output_buffer->offset += (size_t)length;
    631 
    632     return true;
    633 }
    634 
    635 /* parse 4 digit hexadecimal number */
    636 static unsigned parse_hex4(const unsigned char * const input)
    637 {
    638     unsigned int h = 0;
    639     size_t i = 0;
    640 
    641     for (i = 0; i < 4; i++)
    642     {
    643         /* parse digit */
    644         if ((input[i] >= '0') && (input[i] <= '9'))
    645         {
    646             h += (unsigned int) input[i] - '0';
    647         }
    648         else if ((input[i] >= 'A') && (input[i] <= 'F'))
    649         {
    650             h += (unsigned int) 10 + input[i] - 'A';
    651         }
    652         else if ((input[i] >= 'a') && (input[i] <= 'f'))
    653         {
    654             h += (unsigned int) 10 + input[i] - 'a';
    655         }
    656         else /* invalid */
    657         {
    658             return 0;
    659         }
    660 
    661         if (i < 3)
    662         {
    663             /* shift left to make place for the next nibble */
    664             h = h << 4;
    665         }
    666     }
    667 
    668     return h;
    669 }
    670 
    671 /* converts a UTF-16 literal to UTF-8
    672  * A literal can be one or two sequences of the form \uXXXX */
    673 static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
    674 {
    675     long unsigned int codepoint = 0;
    676     unsigned int first_code = 0;
    677     const unsigned char *first_sequence = input_pointer;
    678     unsigned char utf8_length = 0;
    679     unsigned char utf8_position = 0;
    680     unsigned char sequence_length = 0;
    681     unsigned char first_byte_mark = 0;
    682 
    683     if ((input_end - first_sequence) < 6)
    684     {
    685         /* input ends unexpectedly */
    686         goto fail;
    687     }
    688 
    689     /* get the first utf16 sequence */
    690     first_code = parse_hex4(first_sequence + 2);
    691 
    692     /* check that the code is valid */
    693     if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
    694     {
    695         goto fail;
    696     }
    697 
    698     /* UTF16 surrogate pair */
    699     if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
    700     {
    701         const unsigned char *second_sequence = first_sequence + 6;
    702         unsigned int second_code = 0;
    703         sequence_length = 12; /* \uXXXX\uXXXX */
    704 
    705         if ((input_end - second_sequence) < 6)
    706         {
    707             /* input ends unexpectedly */
    708             goto fail;
    709         }
    710 
    711         if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
    712         {
    713             /* missing second half of the surrogate pair */
    714             goto fail;
    715         }
    716 
    717         /* get the second utf16 sequence */
    718         second_code = parse_hex4(second_sequence + 2);
    719         /* check that the code is valid */
    720         if ((second_code < 0xDC00) || (second_code > 0xDFFF))
    721         {
    722             /* invalid second half of the surrogate pair */
    723             goto fail;
    724         }
    725 
    726 
    727         /* calculate the unicode codepoint from the surrogate pair */
    728         codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
    729     }
    730     else
    731     {
    732         sequence_length = 6; /* \uXXXX */
    733         codepoint = first_code;
    734     }
    735 
    736     /* encode as UTF-8
    737      * takes at maximum 4 bytes to encode:
    738      * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
    739     if (codepoint < 0x80)
    740     {
    741         /* normal ascii, encoding 0xxxxxxx */
    742         utf8_length = 1;
    743     }
    744     else if (codepoint < 0x800)
    745     {
    746         /* two bytes, encoding 110xxxxx 10xxxxxx */
    747         utf8_length = 2;
    748         first_byte_mark = 0xC0; /* 11000000 */
    749     }
    750     else if (codepoint < 0x10000)
    751     {
    752         /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
    753         utf8_length = 3;
    754         first_byte_mark = 0xE0; /* 11100000 */
    755     }
    756     else if (codepoint <= 0x10FFFF)
    757     {
    758         /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
    759         utf8_length = 4;
    760         first_byte_mark = 0xF0; /* 11110000 */
    761     }
    762     else
    763     {
    764         /* invalid unicode codepoint */
    765         goto fail;
    766     }
    767 
    768     /* encode as utf8 */
    769     for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
    770     {
    771         /* 10xxxxxx */
    772         (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
    773         codepoint >>= 6;
    774     }
    775     /* encode first byte */
    776     if (utf8_length > 1)
    777     {
    778         (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
    779     }
    780     else
    781     {
    782         (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
    783     }
    784 
    785     *output_pointer += utf8_length;
    786 
    787     return sequence_length;
    788 
    789 fail:
    790     return 0;
    791 }
    792 
    793 /* Parse the input text into an unescaped cinput, and populate item. */
    794 static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
    795 {
    796     const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
    797     const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
    798     unsigned char *output_pointer = NULL;
    799     unsigned char *output = NULL;
    800 
    801     /* not a string */
    802     if (buffer_at_offset(input_buffer)[0] != '\"')
    803     {
    804         goto fail;
    805     }
    806 
    807     {
    808         /* calculate approximate size of the output (overestimate) */
    809         size_t allocation_length = 0;
    810         size_t skipped_bytes = 0;
    811         while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
    812         {
    813             /* is escape sequence */
    814             if (input_end[0] == '\\')
    815             {
    816                 if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
    817                 {
    818                     /* prevent buffer overflow when last input character is a backslash */
    819                     goto fail;
    820                 }
    821                 skipped_bytes++;
    822                 input_end++;
    823             }
    824             input_end++;
    825         }
    826         if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
    827         {
    828             goto fail; /* string ended unexpectedly */
    829         }
    830 
    831         /* This is at most how much we need for the output */
    832         allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
    833         output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
    834         if (output == NULL)
    835         {
    836             goto fail; /* allocation failure */
    837         }
    838     }
    839 
    840     output_pointer = output;
    841     /* loop through the string literal */
    842     while (input_pointer < input_end)
    843     {
    844         if (*input_pointer != '\\')
    845         {
    846             *output_pointer++ = *input_pointer++;
    847         }
    848         /* escape sequence */
    849         else
    850         {
    851             unsigned char sequence_length = 2;
    852             if ((input_end - input_pointer) < 1)
    853             {
    854                 goto fail;
    855             }
    856 
    857             switch (input_pointer[1])
    858             {
    859                 case 'b':
    860                     *output_pointer++ = '\b';
    861                     break;
    862                 case 'f':
    863                     *output_pointer++ = '\f';
    864                     break;
    865                 case 'n':
    866                     *output_pointer++ = '\n';
    867                     break;
    868                 case 'r':
    869                     *output_pointer++ = '\r';
    870                     break;
    871                 case 't':
    872                     *output_pointer++ = '\t';
    873                     break;
    874                 case '\"':
    875                 case '\\':
    876                 case '/':
    877                     *output_pointer++ = input_pointer[1];
    878                     break;
    879 
    880                 /* UTF-16 literal */
    881                 case 'u':
    882                     sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
    883                     if (sequence_length == 0)
    884                     {
    885                         /* failed to convert UTF16-literal to UTF-8 */
    886                         goto fail;
    887                     }
    888                     break;
    889 
    890                 default:
    891                     goto fail;
    892             }
    893             input_pointer += sequence_length;
    894         }
    895     }
    896 
    897     /* zero terminate the output */
    898     *output_pointer = '\0';
    899 
    900     item->type = cJSON_String;
    901     item->valuestring = (char*)output;
    902 
    903     input_buffer->offset = (size_t) (input_end - input_buffer->content);
    904     input_buffer->offset++;
    905 
    906     return true;
    907 
    908 fail:
    909     if (output != NULL)
    910     {
    911         input_buffer->hooks.deallocate(output);
    912         output = NULL;
    913     }
    914 
    915     if (input_pointer != NULL)
    916     {
    917         input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
    918     }
    919 
    920     return false;
    921 }
    922 
    923 /* Render the cstring provided to an escaped version that can be printed. */
    924 static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
    925 {
    926     const unsigned char *input_pointer = NULL;
    927     unsigned char *output = NULL;
    928     unsigned char *output_pointer = NULL;
    929     size_t output_length = 0;
    930     /* numbers of additional characters needed for escaping */
    931     size_t escape_characters = 0;
    932 
    933     if (output_buffer == NULL)
    934     {
    935         return false;
    936     }
    937 
    938     /* empty string */
    939     if (input == NULL)
    940     {
    941         output = ensure(output_buffer, sizeof("\"\""));
    942         if (output == NULL)
    943         {
    944             return false;
    945         }
    946         strcpy((char*)output, "\"\"");
    947 
    948         return true;
    949     }
    950 
    951     /* set "flag" to 1 if something needs to be escaped */
    952     for (input_pointer = input; *input_pointer; input_pointer++)
    953     {
    954         switch (*input_pointer)
    955         {
    956             case '\"':
    957             case '\\':
    958             case '\b':
    959             case '\f':
    960             case '\n':
    961             case '\r':
    962             case '\t':
    963                 /* one character escape sequence */
    964                 escape_characters++;
    965                 break;
    966             default:
    967                 if (*input_pointer < 32)
    968                 {
    969                     /* UTF-16 escape sequence uXXXX */
    970                     escape_characters += 5;
    971                 }
    972                 break;
    973         }
    974     }
    975     output_length = (size_t)(input_pointer - input) + escape_characters;
    976 
    977     output = ensure(output_buffer, output_length + sizeof("\"\""));
    978     if (output == NULL)
    979     {
    980         return false;
    981     }
    982 
    983     /* no characters have to be escaped */
    984     if (escape_characters == 0)
    985     {
    986         output[0] = '\"';
    987         memcpy(output + 1, input, output_length);
    988         output[output_length + 1] = '\"';
    989         output[output_length + 2] = '\0';
    990 
    991         return true;
    992     }
    993 
    994     output[0] = '\"';
    995     output_pointer = output + 1;
    996     /* copy the string */
    997     for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
    998     {
    999         if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
   1000         {
   1001             /* normal character, copy */
   1002             *output_pointer = *input_pointer;
   1003         }
   1004         else
   1005         {
   1006             /* character needs to be escaped */
   1007             *output_pointer++ = '\\';
   1008             switch (*input_pointer)
   1009             {
   1010                 case '\\':
   1011                     *output_pointer = '\\';
   1012                     break;
   1013                 case '\"':
   1014                     *output_pointer = '\"';
   1015                     break;
   1016                 case '\b':
   1017                     *output_pointer = 'b';
   1018                     break;
   1019                 case '\f':
   1020                     *output_pointer = 'f';
   1021                     break;
   1022                 case '\n':
   1023                     *output_pointer = 'n';
   1024                     break;
   1025                 case '\r':
   1026                     *output_pointer = 'r';
   1027                     break;
   1028                 case '\t':
   1029                     *output_pointer = 't';
   1030                     break;
   1031                 default:
   1032                     /* escape and print as unicode codepoint */
   1033                     sprintf((char*)output_pointer, "u%04x", *input_pointer);
   1034                     output_pointer += 4;
   1035                     break;
   1036             }
   1037         }
   1038     }
   1039     output[output_length + 1] = '\"';
   1040     output[output_length + 2] = '\0';
   1041 
   1042     return true;
   1043 }
   1044 
   1045 /* Invoke print_string_ptr (which is useful) on an item. */
   1046 static cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
   1047 {
   1048     return print_string_ptr((unsigned char*)item->valuestring, p);
   1049 }
   1050 
   1051 /* Predeclare these prototypes. */
   1052 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);
   1053 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);
   1054 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);
   1055 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);
   1056 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);
   1057 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);
   1058 
   1059 /* Utility to jump whitespace and cr/lf */
   1060 static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
   1061 {
   1062     if ((buffer == NULL) || (buffer->content == NULL))
   1063     {
   1064         return NULL;
   1065     }
   1066 
   1067     if (cannot_access_at_index(buffer, 0))
   1068     {
   1069         return buffer;
   1070     }
   1071 
   1072     while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
   1073     {
   1074        buffer->offset++;
   1075     }
   1076 
   1077     if (buffer->offset == buffer->length)
   1078     {
   1079         buffer->offset--;
   1080     }
   1081 
   1082     return buffer;
   1083 }
   1084 
   1085 /* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
   1086 static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
   1087 {
   1088     if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
   1089     {
   1090         return NULL;
   1091     }
   1092 
   1093     if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
   1094     {
   1095         buffer->offset += 3;
   1096     }
   1097 
   1098     return buffer;
   1099 }
   1100 
   1101 CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
   1102 {
   1103     size_t buffer_length;
   1104 
   1105     if (NULL == value)
   1106     {
   1107         return NULL;
   1108     }
   1109 
   1110     /* Adding null character size due to require_null_terminated. */
   1111     buffer_length = strlen(value) + sizeof("");
   1112 
   1113     return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated);
   1114 }
   1115 
   1116 /* Parse an object - create a new root, and populate. */
   1117 CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)
   1118 {
   1119     parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
   1120     cJSON *item = NULL;
   1121 
   1122     /* reset error position */
   1123     global_error.json = NULL;
   1124     global_error.position = 0;
   1125 
   1126     if (value == NULL || 0 == buffer_length)
   1127     {
   1128         goto fail;
   1129     }
   1130 
   1131     buffer.content = (const unsigned char*)value;
   1132     buffer.length = buffer_length;
   1133     buffer.offset = 0;
   1134     buffer.hooks = global_hooks;
   1135 
   1136     item = cJSON_New_Item(&global_hooks);
   1137     if (item == NULL) /* memory fail */
   1138     {
   1139         goto fail;
   1140     }
   1141 
   1142     if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
   1143     {
   1144         /* parse failure. ep is set. */
   1145         goto fail;
   1146     }
   1147 
   1148     /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
   1149     if (require_null_terminated)
   1150     {
   1151         buffer_skip_whitespace(&buffer);
   1152         if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
   1153         {
   1154             goto fail;
   1155         }
   1156     }
   1157     if (return_parse_end)
   1158     {
   1159         *return_parse_end = (const char*)buffer_at_offset(&buffer);
   1160     }
   1161 
   1162     return item;
   1163 
   1164 fail:
   1165     if (item != NULL)
   1166     {
   1167         cJSON_Delete(item);
   1168     }
   1169 
   1170     if (value != NULL)
   1171     {
   1172         error local_error;
   1173         local_error.json = (const unsigned char*)value;
   1174         local_error.position = 0;
   1175 
   1176         if (buffer.offset < buffer.length)
   1177         {
   1178             local_error.position = buffer.offset;
   1179         }
   1180         else if (buffer.length > 0)
   1181         {
   1182             local_error.position = buffer.length - 1;
   1183         }
   1184 
   1185         if (return_parse_end != NULL)
   1186         {
   1187             *return_parse_end = (const char*)local_error.json + local_error.position;
   1188         }
   1189 
   1190         global_error = local_error;
   1191     }
   1192 
   1193     return NULL;
   1194 }
   1195 
   1196 /* Default options for cJSON_Parse */
   1197 CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
   1198 {
   1199     return cJSON_ParseWithOpts(value, 0, 0);
   1200 }
   1201 
   1202 CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length)
   1203 {
   1204     return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0);
   1205 }
   1206 
   1207 #define cjson_min(a, b) (((a) < (b)) ? (a) : (b))
   1208 
   1209 static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
   1210 {
   1211     static const size_t default_buffer_size = 256;
   1212     printbuffer buffer[1];
   1213     unsigned char *printed = NULL;
   1214 
   1215     memset(buffer, 0, sizeof(buffer));
   1216 
   1217     /* create buffer */
   1218     buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
   1219     buffer->length = default_buffer_size;
   1220     buffer->format = format;
   1221     buffer->hooks = *hooks;
   1222     if (buffer->buffer == NULL)
   1223     {
   1224         goto fail;
   1225     }
   1226 
   1227     /* print the value */
   1228     if (!print_value(item, buffer))
   1229     {
   1230         goto fail;
   1231     }
   1232     update_offset(buffer);
   1233 
   1234     /* check if reallocate is available */
   1235     if (hooks->reallocate != NULL)
   1236     {
   1237         printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
   1238         if (printed == NULL) {
   1239             goto fail;
   1240         }
   1241         buffer->buffer = NULL;
   1242     }
   1243     else /* otherwise copy the JSON over to a new buffer */
   1244     {
   1245         printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
   1246         if (printed == NULL)
   1247         {
   1248             goto fail;
   1249         }
   1250         memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
   1251         printed[buffer->offset] = '\0'; /* just to be sure */
   1252 
   1253         /* free the buffer */
   1254         hooks->deallocate(buffer->buffer);
   1255         buffer->buffer = NULL;
   1256     }
   1257 
   1258     return printed;
   1259 
   1260 fail:
   1261     if (buffer->buffer != NULL)
   1262     {
   1263         hooks->deallocate(buffer->buffer);
   1264         buffer->buffer = NULL;
   1265     }
   1266 
   1267     if (printed != NULL)
   1268     {
   1269         hooks->deallocate(printed);
   1270         printed = NULL;
   1271     }
   1272 
   1273     return NULL;
   1274 }
   1275 
   1276 /* Render a cJSON item/entity/structure to text. */
   1277 CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
   1278 {
   1279     return (char*)print(item, true, &global_hooks);
   1280 }
   1281 
   1282 CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
   1283 {
   1284     return (char*)print(item, false, &global_hooks);
   1285 }
   1286 
   1287 CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
   1288 {
   1289     printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
   1290 
   1291     if (prebuffer < 0)
   1292     {
   1293         return NULL;
   1294     }
   1295 
   1296     p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
   1297     if (!p.buffer)
   1298     {
   1299         return NULL;
   1300     }
   1301 
   1302     p.length = (size_t)prebuffer;
   1303     p.offset = 0;
   1304     p.noalloc = false;
   1305     p.format = fmt;
   1306     p.hooks = global_hooks;
   1307 
   1308     if (!print_value(item, &p))
   1309     {
   1310         global_hooks.deallocate(p.buffer);
   1311         p.buffer = NULL;
   1312         return NULL;
   1313     }
   1314 
   1315     return (char*)p.buffer;
   1316 }
   1317 
   1318 CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)
   1319 {
   1320     printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
   1321 
   1322     if ((length < 0) || (buffer == NULL))
   1323     {
   1324         return false;
   1325     }
   1326 
   1327     p.buffer = (unsigned char*)buffer;
   1328     p.length = (size_t)length;
   1329     p.offset = 0;
   1330     p.noalloc = true;
   1331     p.format = format;
   1332     p.hooks = global_hooks;
   1333 
   1334     return print_value(item, &p);
   1335 }
   1336 
   1337 /* Parser core - when encountering text, process appropriately. */
   1338 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
   1339 {
   1340     if ((input_buffer == NULL) || (input_buffer->content == NULL))
   1341     {
   1342         return false; /* no input */
   1343     }
   1344 
   1345     /* parse the different types of values */
   1346     /* null */
   1347     if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
   1348     {
   1349         item->type = cJSON_NULL;
   1350         input_buffer->offset += 4;
   1351         return true;
   1352     }
   1353     /* false */
   1354     if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
   1355     {
   1356         item->type = cJSON_False;
   1357         input_buffer->offset += 5;
   1358         return true;
   1359     }
   1360     /* true */
   1361     if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
   1362     {
   1363         item->type = cJSON_True;
   1364         item->valueint = 1;
   1365         input_buffer->offset += 4;
   1366         return true;
   1367     }
   1368     /* string */
   1369     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
   1370     {
   1371         return parse_string(item, input_buffer);
   1372     }
   1373     /* number */
   1374     if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))
   1375     {
   1376         return parse_number(item, input_buffer);
   1377     }
   1378     /* array */
   1379     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
   1380     {
   1381         return parse_array(item, input_buffer);
   1382     }
   1383     /* object */
   1384     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
   1385     {
   1386         return parse_object(item, input_buffer);
   1387     }
   1388 
   1389     return false;
   1390 }
   1391 
   1392 /* Render a value to text. */
   1393 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
   1394 {
   1395     unsigned char *output = NULL;
   1396 
   1397     if ((item == NULL) || (output_buffer == NULL))
   1398     {
   1399         return false;
   1400     }
   1401 
   1402     switch ((item->type) & 0xFF)
   1403     {
   1404         case cJSON_NULL:
   1405             output = ensure(output_buffer, 5);
   1406             if (output == NULL)
   1407             {
   1408                 return false;
   1409             }
   1410             strcpy((char*)output, "null");
   1411             return true;
   1412 
   1413         case cJSON_False:
   1414             output = ensure(output_buffer, 6);
   1415             if (output == NULL)
   1416             {
   1417                 return false;
   1418             }
   1419             strcpy((char*)output, "false");
   1420             return true;
   1421 
   1422         case cJSON_True:
   1423             output = ensure(output_buffer, 5);
   1424             if (output == NULL)
   1425             {
   1426                 return false;
   1427             }
   1428             strcpy((char*)output, "true");
   1429             return true;
   1430 
   1431         case cJSON_Number:
   1432             return print_number(item, output_buffer);
   1433 
   1434         case cJSON_Raw:
   1435         {
   1436             size_t raw_length = 0;
   1437             if (item->valuestring == NULL)
   1438             {
   1439                 return false;
   1440             }
   1441 
   1442             raw_length = strlen(item->valuestring) + sizeof("");
   1443             output = ensure(output_buffer, raw_length);
   1444             if (output == NULL)
   1445             {
   1446                 return false;
   1447             }
   1448             memcpy(output, item->valuestring, raw_length);
   1449             return true;
   1450         }
   1451 
   1452         case cJSON_String:
   1453             return print_string(item, output_buffer);
   1454 
   1455         case cJSON_Array:
   1456             return print_array(item, output_buffer);
   1457 
   1458         case cJSON_Object:
   1459             return print_object(item, output_buffer);
   1460 
   1461         default:
   1462             return false;
   1463     }
   1464 }
   1465 
   1466 /* Build an array from input text. */
   1467 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
   1468 {
   1469     cJSON *head = NULL; /* head of the linked list */
   1470     cJSON *current_item = NULL;
   1471 
   1472     if (input_buffer->depth >= CJSON_NESTING_LIMIT)
   1473     {
   1474         return false; /* to deeply nested */
   1475     }
   1476     input_buffer->depth++;
   1477 
   1478     if (buffer_at_offset(input_buffer)[0] != '[')
   1479     {
   1480         /* not an array */
   1481         goto fail;
   1482     }
   1483 
   1484     input_buffer->offset++;
   1485     buffer_skip_whitespace(input_buffer);
   1486     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
   1487     {
   1488         /* empty array */
   1489         goto success;
   1490     }
   1491 
   1492     /* check if we skipped to the end of the buffer */
   1493     if (cannot_access_at_index(input_buffer, 0))
   1494     {
   1495         input_buffer->offset--;
   1496         goto fail;
   1497     }
   1498 
   1499     /* step back to character in front of the first element */
   1500     input_buffer->offset--;
   1501     /* loop through the comma separated array elements */
   1502     do
   1503     {
   1504         /* allocate next item */
   1505         cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
   1506         if (new_item == NULL)
   1507         {
   1508             goto fail; /* allocation failure */
   1509         }
   1510 
   1511         /* attach next item to list */
   1512         if (head == NULL)
   1513         {
   1514             /* start the linked list */
   1515             current_item = head = new_item;
   1516         }
   1517         else
   1518         {
   1519             /* add to the end and advance */
   1520             current_item->next = new_item;
   1521             new_item->prev = current_item;
   1522             current_item = new_item;
   1523         }
   1524 
   1525         /* parse next value */
   1526         input_buffer->offset++;
   1527         buffer_skip_whitespace(input_buffer);
   1528         if (!parse_value(current_item, input_buffer))
   1529         {
   1530             goto fail; /* failed to parse value */
   1531         }
   1532         buffer_skip_whitespace(input_buffer);
   1533     }
   1534     while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
   1535 
   1536     if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
   1537     {
   1538         goto fail; /* expected end of array */
   1539     }
   1540 
   1541 success:
   1542     input_buffer->depth--;
   1543 
   1544     if (head != NULL) {
   1545         head->prev = current_item;
   1546     }
   1547 
   1548     item->type = cJSON_Array;
   1549     item->child = head;
   1550 
   1551     input_buffer->offset++;
   1552 
   1553     return true;
   1554 
   1555 fail:
   1556     if (head != NULL)
   1557     {
   1558         cJSON_Delete(head);
   1559     }
   1560 
   1561     return false;
   1562 }
   1563 
   1564 /* Render an array to text */
   1565 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
   1566 {
   1567     unsigned char *output_pointer = NULL;
   1568     size_t length = 0;
   1569     cJSON *current_element = item->child;
   1570 
   1571     if (output_buffer == NULL)
   1572     {
   1573         return false;
   1574     }
   1575 
   1576     /* Compose the output array. */
   1577     /* opening square bracket */
   1578     output_pointer = ensure(output_buffer, 1);
   1579     if (output_pointer == NULL)
   1580     {
   1581         return false;
   1582     }
   1583 
   1584     *output_pointer = '[';
   1585     output_buffer->offset++;
   1586     output_buffer->depth++;
   1587 
   1588     while (current_element != NULL)
   1589     {
   1590         if (!print_value(current_element, output_buffer))
   1591         {
   1592             return false;
   1593         }
   1594         update_offset(output_buffer);
   1595         if (current_element->next)
   1596         {
   1597             length = (size_t) (output_buffer->format ? 2 : 1);
   1598             output_pointer = ensure(output_buffer, length + 1);
   1599             if (output_pointer == NULL)
   1600             {
   1601                 return false;
   1602             }
   1603             *output_pointer++ = ',';
   1604             if(output_buffer->format)
   1605             {
   1606                 *output_pointer++ = ' ';
   1607             }
   1608             *output_pointer = '\0';
   1609             output_buffer->offset += length;
   1610         }
   1611         current_element = current_element->next;
   1612     }
   1613 
   1614     output_pointer = ensure(output_buffer, 2);
   1615     if (output_pointer == NULL)
   1616     {
   1617         return false;
   1618     }
   1619     *output_pointer++ = ']';
   1620     *output_pointer = '\0';
   1621     output_buffer->depth--;
   1622 
   1623     return true;
   1624 }
   1625 
   1626 /* Build an object from the text. */
   1627 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
   1628 {
   1629     cJSON *head = NULL; /* linked list head */
   1630     cJSON *current_item = NULL;
   1631 
   1632     if (input_buffer->depth >= CJSON_NESTING_LIMIT)
   1633     {
   1634         return false; /* to deeply nested */
   1635     }
   1636     input_buffer->depth++;
   1637 
   1638     if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
   1639     {
   1640         goto fail; /* not an object */
   1641     }
   1642 
   1643     input_buffer->offset++;
   1644     buffer_skip_whitespace(input_buffer);
   1645     if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
   1646     {
   1647         goto success; /* empty object */
   1648     }
   1649 
   1650     /* check if we skipped to the end of the buffer */
   1651     if (cannot_access_at_index(input_buffer, 0))
   1652     {
   1653         input_buffer->offset--;
   1654         goto fail;
   1655     }
   1656 
   1657     /* step back to character in front of the first element */
   1658     input_buffer->offset--;
   1659     /* loop through the comma separated array elements */
   1660     do
   1661     {
   1662         /* allocate next item */
   1663         cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
   1664         if (new_item == NULL)
   1665         {
   1666             goto fail; /* allocation failure */
   1667         }
   1668 
   1669         /* attach next item to list */
   1670         if (head == NULL)
   1671         {
   1672             /* start the linked list */
   1673             current_item = head = new_item;
   1674         }
   1675         else
   1676         {
   1677             /* add to the end and advance */
   1678             current_item->next = new_item;
   1679             new_item->prev = current_item;
   1680             current_item = new_item;
   1681         }
   1682 
   1683         if (cannot_access_at_index(input_buffer, 1))
   1684         {
   1685             goto fail; /* nothing comes after the comma */
   1686         }
   1687 
   1688         /* parse the name of the child */
   1689         input_buffer->offset++;
   1690         buffer_skip_whitespace(input_buffer);
   1691         if (!parse_string(current_item, input_buffer))
   1692         {
   1693             goto fail; /* failed to parse name */
   1694         }
   1695         buffer_skip_whitespace(input_buffer);
   1696 
   1697         /* swap valuestring and string, because we parsed the name */
   1698         current_item->string = current_item->valuestring;
   1699         current_item->valuestring = NULL;
   1700 
   1701         if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
   1702         {
   1703             goto fail; /* invalid object */
   1704         }
   1705 
   1706         /* parse the value */
   1707         input_buffer->offset++;
   1708         buffer_skip_whitespace(input_buffer);
   1709         if (!parse_value(current_item, input_buffer))
   1710         {
   1711             goto fail; /* failed to parse value */
   1712         }
   1713         buffer_skip_whitespace(input_buffer);
   1714     }
   1715     while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
   1716 
   1717     if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
   1718     {
   1719         goto fail; /* expected end of object */
   1720     }
   1721 
   1722 success:
   1723     input_buffer->depth--;
   1724 
   1725     if (head != NULL) {
   1726         head->prev = current_item;
   1727     }
   1728 
   1729     item->type = cJSON_Object;
   1730     item->child = head;
   1731 
   1732     input_buffer->offset++;
   1733     return true;
   1734 
   1735 fail:
   1736     if (head != NULL)
   1737     {
   1738         cJSON_Delete(head);
   1739     }
   1740 
   1741     return false;
   1742 }
   1743 
   1744 /* Render an object to text. */
   1745 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
   1746 {
   1747     unsigned char *output_pointer = NULL;
   1748     size_t length = 0;
   1749     cJSON *current_item = item->child;
   1750 
   1751     if (output_buffer == NULL)
   1752     {
   1753         return false;
   1754     }
   1755 
   1756     /* Compose the output: */
   1757     length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
   1758     output_pointer = ensure(output_buffer, length + 1);
   1759     if (output_pointer == NULL)
   1760     {
   1761         return false;
   1762     }
   1763 
   1764     *output_pointer++ = '{';
   1765     output_buffer->depth++;
   1766     if (output_buffer->format)
   1767     {
   1768         *output_pointer++ = '\n';
   1769     }
   1770     output_buffer->offset += length;
   1771 
   1772     while (current_item)
   1773     {
   1774         if (output_buffer->format)
   1775         {
   1776             size_t i;
   1777             output_pointer = ensure(output_buffer, output_buffer->depth);
   1778             if (output_pointer == NULL)
   1779             {
   1780                 return false;
   1781             }
   1782             for (i = 0; i < output_buffer->depth; i++)
   1783             {
   1784                 *output_pointer++ = '\t';
   1785             }
   1786             output_buffer->offset += output_buffer->depth;
   1787         }
   1788 
   1789         /* print key */
   1790         if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
   1791         {
   1792             return false;
   1793         }
   1794         update_offset(output_buffer);
   1795 
   1796         length = (size_t) (output_buffer->format ? 2 : 1);
   1797         output_pointer = ensure(output_buffer, length);
   1798         if (output_pointer == NULL)
   1799         {
   1800             return false;
   1801         }
   1802         *output_pointer++ = ':';
   1803         if (output_buffer->format)
   1804         {
   1805             *output_pointer++ = '\t';
   1806         }
   1807         output_buffer->offset += length;
   1808 
   1809         /* print value */
   1810         if (!print_value(current_item, output_buffer))
   1811         {
   1812             return false;
   1813         }
   1814         update_offset(output_buffer);
   1815 
   1816         /* print comma if not last */
   1817         length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
   1818         output_pointer = ensure(output_buffer, length + 1);
   1819         if (output_pointer == NULL)
   1820         {
   1821             return false;
   1822         }
   1823         if (current_item->next)
   1824         {
   1825             *output_pointer++ = ',';
   1826         }
   1827 
   1828         if (output_buffer->format)
   1829         {
   1830             *output_pointer++ = '\n';
   1831         }
   1832         *output_pointer = '\0';
   1833         output_buffer->offset += length;
   1834 
   1835         current_item = current_item->next;
   1836     }
   1837 
   1838     output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
   1839     if (output_pointer == NULL)
   1840     {
   1841         return false;
   1842     }
   1843     if (output_buffer->format)
   1844     {
   1845         size_t i;
   1846         for (i = 0; i < (output_buffer->depth - 1); i++)
   1847         {
   1848             *output_pointer++ = '\t';
   1849         }
   1850     }
   1851     *output_pointer++ = '}';
   1852     *output_pointer = '\0';
   1853     output_buffer->depth--;
   1854 
   1855     return true;
   1856 }
   1857 
   1858 /* Get Array size/item / object item. */
   1859 CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
   1860 {
   1861     cJSON *child = NULL;
   1862     size_t size = 0;
   1863 
   1864     if (array == NULL)
   1865     {
   1866         return 0;
   1867     }
   1868 
   1869     child = array->child;
   1870 
   1871     while(child != NULL)
   1872     {
   1873         size++;
   1874         child = child->next;
   1875     }
   1876 
   1877     /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
   1878 
   1879     return (int)size;
   1880 }
   1881 
   1882 static cJSON* get_array_item(const cJSON *array, size_t index)
   1883 {
   1884     cJSON *current_child = NULL;
   1885 
   1886     if (array == NULL)
   1887     {
   1888         return NULL;
   1889     }
   1890 
   1891     current_child = array->child;
   1892     while ((current_child != NULL) && (index > 0))
   1893     {
   1894         index--;
   1895         current_child = current_child->next;
   1896     }
   1897 
   1898     return current_child;
   1899 }
   1900 
   1901 CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
   1902 {
   1903     if (index < 0)
   1904     {
   1905         return NULL;
   1906     }
   1907 
   1908     return get_array_item(array, (size_t)index);
   1909 }
   1910 
   1911 static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
   1912 {
   1913     cJSON *current_element = NULL;
   1914 
   1915     if ((object == NULL) || (name == NULL))
   1916     {
   1917         return NULL;
   1918     }
   1919 
   1920     current_element = object->child;
   1921     if (case_sensitive)
   1922     {
   1923         while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
   1924         {
   1925             current_element = current_element->next;
   1926         }
   1927     }
   1928     else
   1929     {
   1930         while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
   1931         {
   1932             current_element = current_element->next;
   1933         }
   1934     }
   1935 
   1936     if ((current_element == NULL) || (current_element->string == NULL)) {
   1937         return NULL;
   1938     }
   1939 
   1940     return current_element;
   1941 }
   1942 
   1943 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
   1944 {
   1945     return get_object_item(object, string, false);
   1946 }
   1947 
   1948 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
   1949 {
   1950     return get_object_item(object, string, true);
   1951 }
   1952 
   1953 CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
   1954 {
   1955     return cJSON_GetObjectItem(object, string) ? 1 : 0;
   1956 }
   1957 
   1958 /* Utility for array list handling. */
   1959 static void suffix_object(cJSON *prev, cJSON *item)
   1960 {
   1961     prev->next = item;
   1962     item->prev = prev;
   1963 }
   1964 
   1965 /* Utility for handling references. */
   1966 static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
   1967 {
   1968     cJSON *reference = NULL;
   1969     if (item == NULL)
   1970     {
   1971         return NULL;
   1972     }
   1973 
   1974     reference = cJSON_New_Item(hooks);
   1975     if (reference == NULL)
   1976     {
   1977         return NULL;
   1978     }
   1979 
   1980     memcpy(reference, item, sizeof(cJSON));
   1981     reference->string = NULL;
   1982     reference->type |= cJSON_IsReference;
   1983     reference->next = reference->prev = NULL;
   1984     return reference;
   1985 }
   1986 
   1987 static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
   1988 {
   1989     cJSON *child = NULL;
   1990 
   1991     if ((item == NULL) || (array == NULL) || (array == item))
   1992     {
   1993         return false;
   1994     }
   1995 
   1996     child = array->child;
   1997     /*
   1998      * To find the last item in array quickly, we use prev in array
   1999      */
   2000     if (child == NULL)
   2001     {
   2002         /* list is empty, start new one */
   2003         array->child = item;
   2004         item->prev = item;
   2005         item->next = NULL;
   2006     }
   2007     else
   2008     {
   2009         /* append to the end */
   2010         if (child->prev)
   2011         {
   2012             suffix_object(child->prev, item);
   2013             array->child->prev = item;
   2014         }
   2015     }
   2016 
   2017     return true;
   2018 }
   2019 
   2020 /* Add item to array/object. */
   2021 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
   2022 {
   2023     return add_item_to_array(array, item);
   2024 }
   2025 
   2026 #if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
   2027     #pragma GCC diagnostic push
   2028 #endif
   2029 #ifdef __GNUC__
   2030 #pragma GCC diagnostic ignored "-Wcast-qual"
   2031 #endif
   2032 /* helper function to cast away const */
   2033 static void* cast_away_const(const void* string)
   2034 {
   2035     return (void*)string;
   2036 }
   2037 #if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
   2038     #pragma GCC diagnostic pop
   2039 #endif
   2040 
   2041 
   2042 static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
   2043 {
   2044     char *new_key = NULL;
   2045     int new_type = cJSON_Invalid;
   2046 
   2047     if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item))
   2048     {
   2049         return false;
   2050     }
   2051 
   2052     if (constant_key)
   2053     {
   2054         new_key = (char*)cast_away_const(string);
   2055         new_type = item->type | cJSON_StringIsConst;
   2056     }
   2057     else
   2058     {
   2059         new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
   2060         if (new_key == NULL)
   2061         {
   2062             return false;
   2063         }
   2064 
   2065         new_type = item->type & ~cJSON_StringIsConst;
   2066     }
   2067 
   2068     if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
   2069     {
   2070         hooks->deallocate(item->string);
   2071     }
   2072 
   2073     item->string = new_key;
   2074     item->type = new_type;
   2075 
   2076     return add_item_to_array(object, item);
   2077 }
   2078 
   2079 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
   2080 {
   2081     return add_item_to_object(object, string, item, &global_hooks, false);
   2082 }
   2083 
   2084 /* Add an item to an object with constant string as key */
   2085 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
   2086 {
   2087     return add_item_to_object(object, string, item, &global_hooks, true);
   2088 }
   2089 
   2090 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
   2091 {
   2092     if (array == NULL)
   2093     {
   2094         return false;
   2095     }
   2096 
   2097     return add_item_to_array(array, create_reference(item, &global_hooks));
   2098 }
   2099 
   2100 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
   2101 {
   2102     if ((object == NULL) || (string == NULL))
   2103     {
   2104         return false;
   2105     }
   2106 
   2107     return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
   2108 }
   2109 
   2110 CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
   2111 {
   2112     cJSON *null = cJSON_CreateNull();
   2113     if (add_item_to_object(object, name, null, &global_hooks, false))
   2114     {
   2115         return null;
   2116     }
   2117 
   2118     cJSON_Delete(null);
   2119     return NULL;
   2120 }
   2121 
   2122 CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)
   2123 {
   2124     cJSON *true_item = cJSON_CreateTrue();
   2125     if (add_item_to_object(object, name, true_item, &global_hooks, false))
   2126     {
   2127         return true_item;
   2128     }
   2129 
   2130     cJSON_Delete(true_item);
   2131     return NULL;
   2132 }
   2133 
   2134 CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)
   2135 {
   2136     cJSON *false_item = cJSON_CreateFalse();
   2137     if (add_item_to_object(object, name, false_item, &global_hooks, false))
   2138     {
   2139         return false_item;
   2140     }
   2141 
   2142     cJSON_Delete(false_item);
   2143     return NULL;
   2144 }
   2145 
   2146 CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)
   2147 {
   2148     cJSON *bool_item = cJSON_CreateBool(boolean);
   2149     if (add_item_to_object(object, name, bool_item, &global_hooks, false))
   2150     {
   2151         return bool_item;
   2152     }
   2153 
   2154     cJSON_Delete(bool_item);
   2155     return NULL;
   2156 }
   2157 
   2158 CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
   2159 {
   2160     cJSON *number_item = cJSON_CreateNumber(number);
   2161     if (add_item_to_object(object, name, number_item, &global_hooks, false))
   2162     {
   2163         return number_item;
   2164     }
   2165 
   2166     cJSON_Delete(number_item);
   2167     return NULL;
   2168 }
   2169 
   2170 CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
   2171 {
   2172     cJSON *string_item = cJSON_CreateString(string);
   2173     if (add_item_to_object(object, name, string_item, &global_hooks, false))
   2174     {
   2175         return string_item;
   2176     }
   2177 
   2178     cJSON_Delete(string_item);
   2179     return NULL;
   2180 }
   2181 
   2182 CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)
   2183 {
   2184     cJSON *raw_item = cJSON_CreateRaw(raw);
   2185     if (add_item_to_object(object, name, raw_item, &global_hooks, false))
   2186     {
   2187         return raw_item;
   2188     }
   2189 
   2190     cJSON_Delete(raw_item);
   2191     return NULL;
   2192 }
   2193 
   2194 CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)
   2195 {
   2196     cJSON *object_item = cJSON_CreateObject();
   2197     if (add_item_to_object(object, name, object_item, &global_hooks, false))
   2198     {
   2199         return object_item;
   2200     }
   2201 
   2202     cJSON_Delete(object_item);
   2203     return NULL;
   2204 }
   2205 
   2206 CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)
   2207 {
   2208     cJSON *array = cJSON_CreateArray();
   2209     if (add_item_to_object(object, name, array, &global_hooks, false))
   2210     {
   2211         return array;
   2212     }
   2213 
   2214     cJSON_Delete(array);
   2215     return NULL;
   2216 }
   2217 
   2218 CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
   2219 {
   2220     if ((parent == NULL) || (item == NULL) || (item != parent->child && item->prev == NULL))
   2221     {
   2222         return NULL;
   2223     }
   2224 
   2225     if (item != parent->child)
   2226     {
   2227         /* not the first element */
   2228         item->prev->next = item->next;
   2229     }
   2230     if (item->next != NULL)
   2231     {
   2232         /* not the last element */
   2233         item->next->prev = item->prev;
   2234     }
   2235 
   2236     if (item == parent->child)
   2237     {
   2238         /* first element */
   2239         parent->child = item->next;
   2240     }
   2241     else if (item->next == NULL)
   2242     {
   2243         /* last element */
   2244         parent->child->prev = item->prev;
   2245     }
   2246 
   2247     /* make sure the detached item doesn't point anywhere anymore */
   2248     item->prev = NULL;
   2249     item->next = NULL;
   2250 
   2251     return item;
   2252 }
   2253 
   2254 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
   2255 {
   2256     if (which < 0)
   2257     {
   2258         return NULL;
   2259     }
   2260 
   2261     return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
   2262 }
   2263 
   2264 CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
   2265 {
   2266     cJSON_Delete(cJSON_DetachItemFromArray(array, which));
   2267 }
   2268 
   2269 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
   2270 {
   2271     cJSON *to_detach = cJSON_GetObjectItem(object, string);
   2272 
   2273     return cJSON_DetachItemViaPointer(object, to_detach);
   2274 }
   2275 
   2276 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
   2277 {
   2278     cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
   2279 
   2280     return cJSON_DetachItemViaPointer(object, to_detach);
   2281 }
   2282 
   2283 CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
   2284 {
   2285     cJSON_Delete(cJSON_DetachItemFromObject(object, string));
   2286 }
   2287 
   2288 CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
   2289 {
   2290     cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
   2291 }
   2292 
   2293 /* Replace array/object items with new ones. */
   2294 CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
   2295 {
   2296     cJSON *after_inserted = NULL;
   2297 
   2298     if (which < 0 || newitem == NULL)
   2299     {
   2300         return false;
   2301     }
   2302 
   2303     after_inserted = get_array_item(array, (size_t)which);
   2304     if (after_inserted == NULL)
   2305     {
   2306         return add_item_to_array(array, newitem);
   2307     }
   2308 
   2309     if (after_inserted != array->child && after_inserted->prev == NULL) {
   2310         /* return false if after_inserted is a corrupted array item */
   2311         return false;
   2312     }
   2313 
   2314     newitem->next = after_inserted;
   2315     newitem->prev = after_inserted->prev;
   2316     after_inserted->prev = newitem;
   2317     if (after_inserted == array->child)
   2318     {
   2319         array->child = newitem;
   2320     }
   2321     else
   2322     {
   2323         newitem->prev->next = newitem;
   2324     }
   2325     return true;
   2326 }
   2327 
   2328 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
   2329 {
   2330     if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL) || (item == NULL))
   2331     {
   2332         return false;
   2333     }
   2334 
   2335     if (replacement == item)
   2336     {
   2337         return true;
   2338     }
   2339 
   2340     replacement->next = item->next;
   2341     replacement->prev = item->prev;
   2342 
   2343     if (replacement->next != NULL)
   2344     {
   2345         replacement->next->prev = replacement;
   2346     }
   2347     if (parent->child == item)
   2348     {
   2349         if (parent->child->prev == parent->child)
   2350         {
   2351             replacement->prev = replacement;
   2352         }
   2353         parent->child = replacement;
   2354     }
   2355     else
   2356     {   /*
   2357          * To find the last item in array quickly, we use prev in array.
   2358          * We can't modify the last item's next pointer where this item was the parent's child
   2359          */
   2360         if (replacement->prev != NULL)
   2361         {
   2362             replacement->prev->next = replacement;
   2363         }
   2364         if (replacement->next == NULL)
   2365         {
   2366             parent->child->prev = replacement;
   2367         }
   2368     }
   2369 
   2370     item->next = NULL;
   2371     item->prev = NULL;
   2372     cJSON_Delete(item);
   2373 
   2374     return true;
   2375 }
   2376 
   2377 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
   2378 {
   2379     if (which < 0)
   2380     {
   2381         return false;
   2382     }
   2383 
   2384     return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
   2385 }
   2386 
   2387 static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
   2388 {
   2389     if ((replacement == NULL) || (string == NULL))
   2390     {
   2391         return false;
   2392     }
   2393 
   2394     /* replace the name in the replacement */
   2395     if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
   2396     {
   2397         cJSON_free(replacement->string);
   2398     }
   2399     replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
   2400     if (replacement->string == NULL)
   2401     {
   2402         return false;
   2403     }
   2404 
   2405     replacement->type &= ~cJSON_StringIsConst;
   2406 
   2407     return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
   2408 }
   2409 
   2410 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
   2411 {
   2412     return replace_item_in_object(object, string, newitem, false);
   2413 }
   2414 
   2415 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
   2416 {
   2417     return replace_item_in_object(object, string, newitem, true);
   2418 }
   2419 
   2420 /* Create basic types: */
   2421 CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
   2422 {
   2423     cJSON *item = cJSON_New_Item(&global_hooks);
   2424     if(item)
   2425     {
   2426         item->type = cJSON_NULL;
   2427     }
   2428 
   2429     return item;
   2430 }
   2431 
   2432 CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
   2433 {
   2434     cJSON *item = cJSON_New_Item(&global_hooks);
   2435     if(item)
   2436     {
   2437         item->type = cJSON_True;
   2438     }
   2439 
   2440     return item;
   2441 }
   2442 
   2443 CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
   2444 {
   2445     cJSON *item = cJSON_New_Item(&global_hooks);
   2446     if(item)
   2447     {
   2448         item->type = cJSON_False;
   2449     }
   2450 
   2451     return item;
   2452 }
   2453 
   2454 CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
   2455 {
   2456     cJSON *item = cJSON_New_Item(&global_hooks);
   2457     if(item)
   2458     {
   2459         item->type = boolean ? cJSON_True : cJSON_False;
   2460     }
   2461 
   2462     return item;
   2463 }
   2464 
   2465 CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
   2466 {
   2467     cJSON *item = cJSON_New_Item(&global_hooks);
   2468     if(item)
   2469     {
   2470         item->type = cJSON_Number;
   2471         item->valuedouble = num;
   2472 
   2473         /* use saturation in case of overflow */
   2474         if (num >= INT_MAX)
   2475         {
   2476             item->valueint = INT_MAX;
   2477         }
   2478         else if (num <= (double)INT_MIN)
   2479         {
   2480             item->valueint = INT_MIN;
   2481         }
   2482         else
   2483         {
   2484             item->valueint = (int)num;
   2485         }
   2486     }
   2487 
   2488     return item;
   2489 }
   2490 
   2491 CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
   2492 {
   2493     cJSON *item = cJSON_New_Item(&global_hooks);
   2494     if(item)
   2495     {
   2496         item->type = cJSON_String;
   2497         item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
   2498         if(!item->valuestring)
   2499         {
   2500             cJSON_Delete(item);
   2501             return NULL;
   2502         }
   2503     }
   2504 
   2505     return item;
   2506 }
   2507 
   2508 CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)
   2509 {
   2510     cJSON *item = cJSON_New_Item(&global_hooks);
   2511     if (item != NULL)
   2512     {
   2513         item->type = cJSON_String | cJSON_IsReference;
   2514         item->valuestring = (char*)cast_away_const(string);
   2515     }
   2516 
   2517     return item;
   2518 }
   2519 
   2520 CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)
   2521 {
   2522     cJSON *item = cJSON_New_Item(&global_hooks);
   2523     if (item != NULL) {
   2524         item->type = cJSON_Object | cJSON_IsReference;
   2525         item->child = (cJSON*)cast_away_const(child);
   2526     }
   2527 
   2528     return item;
   2529 }
   2530 
   2531 CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {
   2532     cJSON *item = cJSON_New_Item(&global_hooks);
   2533     if (item != NULL) {
   2534         item->type = cJSON_Array | cJSON_IsReference;
   2535         item->child = (cJSON*)cast_away_const(child);
   2536     }
   2537 
   2538     return item;
   2539 }
   2540 
   2541 CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
   2542 {
   2543     cJSON *item = cJSON_New_Item(&global_hooks);
   2544     if(item)
   2545     {
   2546         item->type = cJSON_Raw;
   2547         item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
   2548         if(!item->valuestring)
   2549         {
   2550             cJSON_Delete(item);
   2551             return NULL;
   2552         }
   2553     }
   2554 
   2555     return item;
   2556 }
   2557 
   2558 CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
   2559 {
   2560     cJSON *item = cJSON_New_Item(&global_hooks);
   2561     if(item)
   2562     {
   2563         item->type=cJSON_Array;
   2564     }
   2565 
   2566     return item;
   2567 }
   2568 
   2569 CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
   2570 {
   2571     cJSON *item = cJSON_New_Item(&global_hooks);
   2572     if (item)
   2573     {
   2574         item->type = cJSON_Object;
   2575     }
   2576 
   2577     return item;
   2578 }
   2579 
   2580 /* Create Arrays: */
   2581 CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
   2582 {
   2583     size_t i = 0;
   2584     cJSON *n = NULL;
   2585     cJSON *p = NULL;
   2586     cJSON *a = NULL;
   2587 
   2588     if ((count < 0) || (numbers == NULL))
   2589     {
   2590         return NULL;
   2591     }
   2592 
   2593     a = cJSON_CreateArray();
   2594 
   2595     for(i = 0; a && (i < (size_t)count); i++)
   2596     {
   2597         n = cJSON_CreateNumber(numbers[i]);
   2598         if (!n)
   2599         {
   2600             cJSON_Delete(a);
   2601             return NULL;
   2602         }
   2603         if(!i)
   2604         {
   2605             a->child = n;
   2606         }
   2607         else
   2608         {
   2609             suffix_object(p, n);
   2610         }
   2611         p = n;
   2612     }
   2613 
   2614     if (a && a->child) {
   2615         a->child->prev = n;
   2616     }
   2617 
   2618     return a;
   2619 }
   2620 
   2621 CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
   2622 {
   2623     size_t i = 0;
   2624     cJSON *n = NULL;
   2625     cJSON *p = NULL;
   2626     cJSON *a = NULL;
   2627 
   2628     if ((count < 0) || (numbers == NULL))
   2629     {
   2630         return NULL;
   2631     }
   2632 
   2633     a = cJSON_CreateArray();
   2634 
   2635     for(i = 0; a && (i < (size_t)count); i++)
   2636     {
   2637         n = cJSON_CreateNumber((double)numbers[i]);
   2638         if(!n)
   2639         {
   2640             cJSON_Delete(a);
   2641             return NULL;
   2642         }
   2643         if(!i)
   2644         {
   2645             a->child = n;
   2646         }
   2647         else
   2648         {
   2649             suffix_object(p, n);
   2650         }
   2651         p = n;
   2652     }
   2653 
   2654     if (a && a->child) {
   2655         a->child->prev = n;
   2656     }
   2657 
   2658     return a;
   2659 }
   2660 
   2661 CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
   2662 {
   2663     size_t i = 0;
   2664     cJSON *n = NULL;
   2665     cJSON *p = NULL;
   2666     cJSON *a = NULL;
   2667 
   2668     if ((count < 0) || (numbers == NULL))
   2669     {
   2670         return NULL;
   2671     }
   2672 
   2673     a = cJSON_CreateArray();
   2674 
   2675     for(i = 0; a && (i < (size_t)count); i++)
   2676     {
   2677         n = cJSON_CreateNumber(numbers[i]);
   2678         if(!n)
   2679         {
   2680             cJSON_Delete(a);
   2681             return NULL;
   2682         }
   2683         if(!i)
   2684         {
   2685             a->child = n;
   2686         }
   2687         else
   2688         {
   2689             suffix_object(p, n);
   2690         }
   2691         p = n;
   2692     }
   2693 
   2694     if (a && a->child) {
   2695         a->child->prev = n;
   2696     }
   2697 
   2698     return a;
   2699 }
   2700 
   2701 CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count)
   2702 {
   2703     size_t i = 0;
   2704     cJSON *n = NULL;
   2705     cJSON *p = NULL;
   2706     cJSON *a = NULL;
   2707 
   2708     if ((count < 0) || (strings == NULL))
   2709     {
   2710         return NULL;
   2711     }
   2712 
   2713     a = cJSON_CreateArray();
   2714 
   2715     for (i = 0; a && (i < (size_t)count); i++)
   2716     {
   2717         n = cJSON_CreateString(strings[i]);
   2718         if(!n)
   2719         {
   2720             cJSON_Delete(a);
   2721             return NULL;
   2722         }
   2723         if(!i)
   2724         {
   2725             a->child = n;
   2726         }
   2727         else
   2728         {
   2729             suffix_object(p,n);
   2730         }
   2731         p = n;
   2732     }
   2733 
   2734     if (a && a->child) {
   2735         a->child->prev = n;
   2736     }
   2737 
   2738     return a;
   2739 }
   2740 
   2741 /* Duplication */
   2742 cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse);
   2743 
   2744 CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
   2745 {
   2746     return cJSON_Duplicate_rec(item, 0, recurse );
   2747 }
   2748 
   2749 cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse)
   2750 {
   2751     cJSON *newitem = NULL;
   2752     cJSON *child = NULL;
   2753     cJSON *next = NULL;
   2754     cJSON *newchild = NULL;
   2755 
   2756     /* Bail on bad ptr */
   2757     if (!item)
   2758     {
   2759         goto fail;
   2760     }
   2761     /* Create new item */
   2762     newitem = cJSON_New_Item(&global_hooks);
   2763     if (!newitem)
   2764     {
   2765         goto fail;
   2766     }
   2767     /* Copy over all vars */
   2768     newitem->type = item->type & (~cJSON_IsReference);
   2769     newitem->valueint = item->valueint;
   2770     newitem->valuedouble = item->valuedouble;
   2771     if (item->valuestring)
   2772     {
   2773         newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
   2774         if (!newitem->valuestring)
   2775         {
   2776             goto fail;
   2777         }
   2778     }
   2779     if (item->string)
   2780     {
   2781         newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
   2782         if (!newitem->string)
   2783         {
   2784             goto fail;
   2785         }
   2786     }
   2787     /* If non-recursive, then we're done! */
   2788     if (!recurse)
   2789     {
   2790         return newitem;
   2791     }
   2792     /* Walk the ->next chain for the child. */
   2793     child = item->child;
   2794     while (child != NULL)
   2795     {
   2796         if(depth >= CJSON_CIRCULAR_LIMIT) {
   2797             goto fail;
   2798         }
   2799         newchild = cJSON_Duplicate_rec(child, depth + 1, true); /* Duplicate (with recurse) each item in the ->next chain */
   2800         if (!newchild)
   2801         {
   2802             goto fail;
   2803         }
   2804         if (next != NULL)
   2805         {
   2806             /* If newitem->child already set, then crosswire ->prev and ->next and move on */
   2807             next->next = newchild;
   2808             newchild->prev = next;
   2809             next = newchild;
   2810         }
   2811         else
   2812         {
   2813             /* Set newitem->child and move to it */
   2814             newitem->child = newchild;
   2815             next = newchild;
   2816         }
   2817         child = child->next;
   2818     }
   2819     if (newitem && newitem->child)
   2820     {
   2821         newitem->child->prev = newchild;
   2822     }
   2823 
   2824     return newitem;
   2825 
   2826 fail:
   2827     if (newitem != NULL)
   2828     {
   2829         cJSON_Delete(newitem);
   2830     }
   2831 
   2832     return NULL;
   2833 }
   2834 
   2835 static void skip_oneline_comment(char **input)
   2836 {
   2837     *input += static_strlen("//");
   2838 
   2839     for (; (*input)[0] != '\0'; ++(*input))
   2840     {
   2841         if ((*input)[0] == '\n') {
   2842             *input += static_strlen("\n");
   2843             return;
   2844         }
   2845     }
   2846 }
   2847 
   2848 static void skip_multiline_comment(char **input)
   2849 {
   2850     *input += static_strlen("/*");
   2851 
   2852     for (; (*input)[0] != '\0'; ++(*input))
   2853     {
   2854         if (((*input)[0] == '*') && ((*input)[1] == '/'))
   2855         {
   2856             *input += static_strlen("*/");
   2857             return;
   2858         }
   2859     }
   2860 }
   2861 
   2862 static void minify_string(char **input, char **output) {
   2863     (*output)[0] = (*input)[0];
   2864     *input += static_strlen("\"");
   2865     *output += static_strlen("\"");
   2866 
   2867 
   2868     for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
   2869         (*output)[0] = (*input)[0];
   2870 
   2871         if ((*input)[0] == '\"') {
   2872             (*output)[0] = '\"';
   2873             *input += static_strlen("\"");
   2874             *output += static_strlen("\"");
   2875             return;
   2876         } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
   2877             (*output)[1] = (*input)[1];
   2878             *input += static_strlen("\"");
   2879             *output += static_strlen("\"");
   2880         }
   2881     }
   2882 }
   2883 
   2884 CJSON_PUBLIC(void) cJSON_Minify(char *json)
   2885 {
   2886     char *into = json;
   2887 
   2888     if (json == NULL)
   2889     {
   2890         return;
   2891     }
   2892 
   2893     while (json[0] != '\0')
   2894     {
   2895         switch (json[0])
   2896         {
   2897             case ' ':
   2898             case '\t':
   2899             case '\r':
   2900             case '\n':
   2901                 json++;
   2902                 break;
   2903 
   2904             case '/':
   2905                 if (json[1] == '/')
   2906                 {
   2907                     skip_oneline_comment(&json);
   2908                 }
   2909                 else if (json[1] == '*')
   2910                 {
   2911                     skip_multiline_comment(&json);
   2912                 } else {
   2913                     json++;
   2914                 }
   2915                 break;
   2916 
   2917             case '\"':
   2918                 minify_string(&json, (char**)&into);
   2919                 break;
   2920 
   2921             default:
   2922                 into[0] = json[0];
   2923                 json++;
   2924                 into++;
   2925         }
   2926     }
   2927 
   2928     /* and null-terminate. */
   2929     *into = '\0';
   2930 }
   2931 
   2932 CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
   2933 {
   2934     if (item == NULL)
   2935     {
   2936         return false;
   2937     }
   2938 
   2939     return (item->type & 0xFF) == cJSON_Invalid;
   2940 }
   2941 
   2942 CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
   2943 {
   2944     if (item == NULL)
   2945     {
   2946         return false;
   2947     }
   2948 
   2949     return (item->type & 0xFF) == cJSON_False;
   2950 }
   2951 
   2952 CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
   2953 {
   2954     if (item == NULL)
   2955     {
   2956         return false;
   2957     }
   2958 
   2959     return (item->type & 0xff) == cJSON_True;
   2960 }
   2961 
   2962 
   2963 CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
   2964 {
   2965     if (item == NULL)
   2966     {
   2967         return false;
   2968     }
   2969 
   2970     return (item->type & (cJSON_True | cJSON_False)) != 0;
   2971 }
   2972 CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
   2973 {
   2974     if (item == NULL)
   2975     {
   2976         return false;
   2977     }
   2978 
   2979     return (item->type & 0xFF) == cJSON_NULL;
   2980 }
   2981 
   2982 CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
   2983 {
   2984     if (item == NULL)
   2985     {
   2986         return false;
   2987     }
   2988 
   2989     return (item->type & 0xFF) == cJSON_Number;
   2990 }
   2991 
   2992 CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
   2993 {
   2994     if (item == NULL)
   2995     {
   2996         return false;
   2997     }
   2998 
   2999     return (item->type & 0xFF) == cJSON_String;
   3000 }
   3001 
   3002 CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
   3003 {
   3004     if (item == NULL)
   3005     {
   3006         return false;
   3007     }
   3008 
   3009     return (item->type & 0xFF) == cJSON_Array;
   3010 }
   3011 
   3012 CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
   3013 {
   3014     if (item == NULL)
   3015     {
   3016         return false;
   3017     }
   3018 
   3019     return (item->type & 0xFF) == cJSON_Object;
   3020 }
   3021 
   3022 CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
   3023 {
   3024     if (item == NULL)
   3025     {
   3026         return false;
   3027     }
   3028 
   3029     return (item->type & 0xFF) == cJSON_Raw;
   3030 }
   3031 
   3032 CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
   3033 {
   3034     if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)))
   3035     {
   3036         return false;
   3037     }
   3038 
   3039     /* check if type is valid */
   3040     switch (a->type & 0xFF)
   3041     {
   3042         case cJSON_False:
   3043         case cJSON_True:
   3044         case cJSON_NULL:
   3045         case cJSON_Number:
   3046         case cJSON_String:
   3047         case cJSON_Raw:
   3048         case cJSON_Array:
   3049         case cJSON_Object:
   3050             break;
   3051 
   3052         default:
   3053             return false;
   3054     }
   3055 
   3056     /* identical objects are equal */
   3057     if (a == b)
   3058     {
   3059         return true;
   3060     }
   3061 
   3062     switch (a->type & 0xFF)
   3063     {
   3064         /* in these cases and equal type is enough */
   3065         case cJSON_False:
   3066         case cJSON_True:
   3067         case cJSON_NULL:
   3068             return true;
   3069 
   3070         case cJSON_Number:
   3071             if (compare_double(a->valuedouble, b->valuedouble))
   3072             {
   3073                 return true;
   3074             }
   3075             return false;
   3076 
   3077         case cJSON_String:
   3078         case cJSON_Raw:
   3079             if ((a->valuestring == NULL) || (b->valuestring == NULL))
   3080             {
   3081                 return false;
   3082             }
   3083             if (strcmp(a->valuestring, b->valuestring) == 0)
   3084             {
   3085                 return true;
   3086             }
   3087 
   3088             return false;
   3089 
   3090         case cJSON_Array:
   3091         {
   3092             cJSON *a_element = a->child;
   3093             cJSON *b_element = b->child;
   3094 
   3095             for (; (a_element != NULL) && (b_element != NULL);)
   3096             {
   3097                 if (!cJSON_Compare(a_element, b_element, case_sensitive))
   3098                 {
   3099                     return false;
   3100                 }
   3101 
   3102                 a_element = a_element->next;
   3103                 b_element = b_element->next;
   3104             }
   3105 
   3106             /* one of the arrays is longer than the other */
   3107             if (a_element != b_element) {
   3108                 return false;
   3109             }
   3110 
   3111             return true;
   3112         }
   3113 
   3114         case cJSON_Object:
   3115         {
   3116             cJSON *a_element = NULL;
   3117             cJSON *b_element = NULL;
   3118             cJSON_ArrayForEach(a_element, a)
   3119             {
   3120                 /* TODO This has O(n^2) runtime, which is horrible! */
   3121                 b_element = get_object_item(b, a_element->string, case_sensitive);
   3122                 if (b_element == NULL)
   3123                 {
   3124                     return false;
   3125                 }
   3126 
   3127                 if (!cJSON_Compare(a_element, b_element, case_sensitive))
   3128                 {
   3129                     return false;
   3130                 }
   3131             }
   3132 
   3133             /* doing this twice, once on a and b to prevent true comparison if a subset of b
   3134              * TODO: Do this the proper way, this is just a fix for now */
   3135             cJSON_ArrayForEach(b_element, b)
   3136             {
   3137                 a_element = get_object_item(a, b_element->string, case_sensitive);
   3138                 if (a_element == NULL)
   3139                 {
   3140                     return false;
   3141                 }
   3142 
   3143                 if (!cJSON_Compare(b_element, a_element, case_sensitive))
   3144                 {
   3145                     return false;
   3146                 }
   3147             }
   3148 
   3149             return true;
   3150         }
   3151 
   3152         default:
   3153             return false;
   3154     }
   3155 }
   3156 
   3157 CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
   3158 {
   3159     return global_hooks.allocate(size);
   3160 }
   3161 
   3162 CJSON_PUBLIC(void) cJSON_free(void *object)
   3163 {
   3164     global_hooks.deallocate(object);
   3165     object = NULL;
   3166 }