1 /*
2   Copyright (c) 2009 Dave Gamble
3   Copyright (c) 2009 The OpenTyrian Development Team
4 
5   Permission is hereby granted, free of charge, to any person obtaining a copy
6   of this software and associated documentation files (the "Software"), to deal
7   in the Software without restriction, including without limitation the rights
8   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9   copies of the Software, and to permit persons to whom the Software is
10   furnished to do so, subject to the following conditions:
11 
12   The above copyright notice and this permission notice shall be included in
13   all copies or substantial portions of the Software.
14 
15   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21   THE SOFTWARE.
22 */
23 
24 // cJSON
25 // JSON parser in C.
26 
27 #include "cJSON.h"
28 #include "mingw_fixes.h"
29 
30 #include <assert.h>
31 #include <ctype.h>
32 #include <float.h>
33 #include <limits.h>
34 #include <math.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 
39 static void *(*cJSON_malloc)( size_t ) = malloc;
40 static void *(*cJSON_realloc)( void *, size_t ) = realloc;
41 static void (*cJSON_free)( void *ptr ) = free;
42 
43 // helper for compilers without strdup
cJSON_strdup(const char * str)44 static char *cJSON_strdup( const char *str )
45 {
46 	size_t size = strlen(str) + 1;
47 	char *copy = (char *)cJSON_malloc(size);
48 
49 	if (copy != NULL)
50 		memcpy(copy, str, size);
51 
52 	return copy;
53 }
54 
55 // helper for compilers without strcasecmp
cJSON_strcasecmp(const char * s1,const char * s2)56 static int cJSON_strcasecmp( const char *s1, const char *s2 )
57 {
58 	for(; tolower(*(const unsigned char *)s1) == tolower(*(const unsigned char *)s2); ++s1, ++s2)
59 		if (*s1 == 0)
60 			return 0;
61 	return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
62 }
63 
64 // construct empty item
cJSON_NewItem(cJSON_Type type)65 static cJSON *cJSON_NewItem( cJSON_Type type )
66 {
67 	cJSON *node = (cJSON *)cJSON_malloc(sizeof(cJSON));
68 
69 	if (node != NULL)
70 	{
71 		node->type = type;
72 		node->child =
73 		node->prev =
74 		node->next = NULL;
75 
76 		node->string = NULL;
77 
78 		node->valuestring = NULL;
79 		node->valueint =
80 		node->valuedouble = 0;
81 	}
82 
83 	return node;
84 }
85 
86 // destroy item chain
cJSON_Delete(cJSON * item)87 void cJSON_Delete( cJSON *item )
88 {
89 	while (item != NULL)
90 	{
91 		if (item->child)
92 			cJSON_Delete(item->child);
93 
94 		cJSON *next = item->next;
95 
96 		if (item->string)
97 			cJSON_free(item->string);
98 		if (item->valuestring)
99 			cJSON_free(item->valuestring);
100 		cJSON_free(item);
101 
102 		item = next;
103 	}
104 }
105 
106 // parser/emitter prototypes
107 
108 static const char *parse_value( cJSON *item, const char *in );
109 static char *print_value(cJSON *item,int depth);
110 
111 static const char *parse_number( cJSON *item, const char *in );
112 static char *print_number( cJSON *item );
113 
114 static const char *parse_string(cJSON *item,const char *str);
115 static char *print_string(cJSON *item);
116 
117 static const char *parse_array_or_object( cJSON *item, const char *in, cJSON_Type type );
118 static char *print_array(cJSON *item,int depth);
119 static char *print_object(cJSON *item,int depth);
120 
parse_array(cJSON * item,const char * in)121 static inline const char *parse_array( cJSON *item, const char *in )
122 {
123 	return parse_array_or_object(item, in, cJSON_Array);
124 }
parse_object(cJSON * item,const char * in)125 static inline const char *parse_object( cJSON *item, const char *in )
126 {
127 	return parse_array_or_object(item, in, cJSON_Object);
128 }
129 
130 // helper to skip whitespace
skip_space(const char * str)131 static inline const char *skip_space( const char *str )
132 {
133 	if (str != NULL)
134 		while (isspace(*str))
135 			++str;
136 	return str;
137 }
138 
139 // parse root of JSON into cJSON item
cJSON_Parse(const char * in)140 cJSON *cJSON_Parse( const char *in )
141 {
142 	cJSON *item = cJSON_NewItem(cJSON_NULL);
143 
144 	if (item != NULL)
145 	{
146 		if (parse_value(item, skip_space(in)) == NULL)  // if malformed or out-of-memory
147 		{
148 			cJSON_Delete(item);
149 			item = NULL;
150 		}
151 	}
152 
153 	return item;
154 }
155 
156 // emit cJSON item as JSON value
cJSON_Print(cJSON * item)157 char *cJSON_Print( cJSON *item )
158 {
159 	return print_value(item, 0);
160 }
161 
162 // parse JSON value into cJSON item
parse_value(cJSON * item,const char * in)163 static const char *parse_value( cJSON *item, const char *in )
164 {
165 	if (in == NULL)
166 		return in;
167 
168 	if (!strncmp(in, "null", 4))
169 	{
170 		item->type = cJSON_NULL;
171 		return in + 4;
172 	}
173 	if (!strncmp(in, "false", 5))
174 	{
175 		item->type = cJSON_False;
176 		return in + 5;
177 	}
178 	if (!strncmp(in, "true", 4))
179 	{
180 		item->type = cJSON_True;
181 		return in + 4;
182 	}
183 	if (*in == '\"')
184 		return parse_string(item, in);
185 	if (*in == '-' || (*in >= '0' && *in <= '9'))
186 		return parse_number(item, in);
187 	if (*in == '[')
188 		return parse_array(item, in);
189 	if (*in == '{')
190 		return parse_object(item, in);
191 
192 	return NULL;  // malformed: expected value
193 }
194 
195 // emit cJSON item as JSON value
print_value(cJSON * item,int depth)196 static char *print_value( cJSON *item, int depth )
197 {
198 	char *out = NULL;
199 
200 	switch (item->type)
201 	{
202 	case cJSON_NULL:
203 		out = cJSON_strdup("null");
204 		break;
205 	case cJSON_False:
206 		out = cJSON_strdup("false");
207 		break;
208 	case cJSON_True:
209 		out = cJSON_strdup("true");
210 		break;
211 	case cJSON_Number:
212 		out = print_number(item);
213 		break;
214 	case cJSON_String:
215 		out = print_string(item);
216 		break;
217 	case cJSON_Array:
218 		out = print_array(item, depth);
219 		break;
220 	case cJSON_Object:
221 		out = print_object(item, depth);
222 		break;
223 	}
224 
225 	return out;
226 }
227 
228 // parse JSON number value into cJSON item
parse_number(cJSON * item,const char * in)229 static const char *parse_number( cJSON *item, const char *in )
230 {
231 	double n = 0;
232 	int sign = 1, decimal_shift = 0;
233 	int exponent_sign = 1, exponent = 0;
234 
235 	if (*in == '-')
236 		sign = -1, ++in;
237 
238 	// integer part
239 	if (*in == '0')
240 		++in;
241 	else if (*in >= '1' && *in <= '9')
242 		do
243 			n = (n * 10.0) + (*(in++) - '0');
244 		while (*in >= '0' && *in <= '9');
245 
246 	// fractional part
247 	if (*in == '.')
248 	{
249 		++in;
250 
251 		while (*in >= '0' && *in <= '9')
252 			n = (n * 10.0) + (*(in++) - '0'), decimal_shift--;
253 	}
254 
255 	// exponent part
256 	if (*in == 'e' || *in == 'E')
257 	{
258 		++in;
259 
260 		if (*in == '+')
261 			++in;
262 		else if (*in == '-')
263 			exponent_sign = -1, ++in;
264 
265 		while (*in >= '0' && *in <= '9')
266 			exponent = (exponent * 10) + (*(in++) - '0');
267 	}
268 
269 	// number = +/- number.fraction * (10 ^ +/- exponent)
270 	n = sign * n * pow(10.0, decimal_shift + exponent_sign * exponent);
271 
272 	item->valuedouble = n;
273 	item->valueint = n;
274 	item->type = cJSON_Number;
275 
276 	return in;
277 }
278 
279 // emit string containing numeric value of cJSON item
print_number(cJSON * item)280 static char *print_number( cJSON *item )
281 {
282 	char *str = (char *)cJSON_malloc(DBL_DIG + 10);
283 	snprintf(str, DBL_DIG + 10, "%.*g", DBL_DIG, item->valuedouble);
284 	return str;
285 }
286 
287 // Parse the input text into an unescaped cstring, and populate item.
288 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
parse_string(cJSON * item,const char * str)289 static const char *parse_string(cJSON *item,const char *str)
290 {
291 	const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
292 	if (*str!='\"') return 0;	// not a string!
293 
294 	while (*ptr!='\"' && *ptr>31 && ++len) if (*ptr++ == '\\') ptr++;	// skip escaped quotes.
295 
296 	out=(char*)cJSON_malloc(len+1);	// This is how long we need for the string, roughly.
297 	if (!out) return 0;
298 
299 	ptr=str+1;ptr2=out;
300 	while (*ptr!='\"' && *ptr>31)
301 	{
302 		if (*ptr!='\\') *ptr2++=*ptr++;
303 		else
304 		{
305 			ptr++;
306 			switch (*ptr)
307 			{
308 				case 'b': *ptr2++='\b';	break;
309 				case 'f': *ptr2++='\f';	break;
310 				case 'n': *ptr2++='\n';	break;
311 				case 'r': *ptr2++='\r';	break;
312 				case 't': *ptr2++='\t';	break;
313 				case 'u':	 // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
314 					sscanf(ptr+1,"%4x",&uc);	// get the unicode char.
315 					len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
316 
317 					switch (len) {
318 						case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
319 						case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
320 						case 1: *--ptr2 =(uc | firstByteMark[len]);
321 					}
322 					ptr2+=len;ptr+=4;
323 					break;
324 				default:  *ptr2++=*ptr; break;
325 			}
326 			ptr++;
327 		}
328 	}
329 	*ptr2=0;
330 	if (*ptr=='\"') ptr++;
331 	item->valuestring=out;
332 	item->type=cJSON_String;
333 	return ptr;
334 }
335 
336 // Render the cstring provided to an escaped version that can be printed.
print_string_ptr(const char * str)337 static char *print_string_ptr(const char *str)
338 {
339 	const char *ptr;char *ptr2,*out;int len=0;
340 
341 	ptr=str;while (*ptr && ++len) {if (*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
342 
343 	out=(char*)cJSON_malloc(len+3);
344 	ptr2=out;ptr=str;
345 	*ptr2++='\"';
346 	while (*ptr)
347 	{
348 		if (*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
349 		else
350 		{
351 			*ptr2++='\\';
352 			switch (*ptr++)
353 			{
354 				case '\\':	*ptr2++='\\';	break;
355 				case '\"':	*ptr2++='\"';	break;
356 				case '\b':	*ptr2++='b';	break;
357 				case '\f':	*ptr2++='f';	break;
358 				case '\n':	*ptr2++='n';	break;
359 				case '\r':	*ptr2++='r';	break;
360 				case '\t':	*ptr2++='t';	break;
361 				default: ptr2--;	break;	// eviscerate with prejudice.
362 			}
363 		}
364 	}
365 	*ptr2++='\"';*ptr2++=0;
366 	return out;
367 }
368 // Invote print_string_ptr (which is useful) on an item.
print_string(cJSON * item)369 static char *print_string(cJSON *item)
370 {
371 	return (item->valuestring != NULL) ? print_string_ptr(item->valuestring) : cJSON_strdup("");
372 }
373 
374 // parse JSON array/object into cJSON item chain
parse_array_or_object(cJSON * const item,const char * in,cJSON_Type type)375 static const char *parse_array_or_object( cJSON *const item, const char *in, cJSON_Type type )
376 {
377 	assert(type == cJSON_Array || type == cJSON_Object);
378 
379 	const char opening = (type == cJSON_Object) ? '{' : '[',
380 	           closing = (type == cJSON_Object) ? '}' : ']';
381 
382 	if (*in != opening)  // not an array/object!
383 		return NULL;
384 	else
385 		in = skip_space(++in);
386 
387 	item->type = type;
388 
389 	if (*in == closing)  // empty array/object
390 		return ++in;
391 
392 	cJSON *prev_child = NULL;
393 	for (; ; )
394 	{
395 		cJSON *child = cJSON_NewItem(cJSON_NULL);
396 		if (child == NULL)  // memory fail
397 			return NULL;
398 
399 		if (prev_child == NULL)
400 		{
401 			// attach first child to parent
402 			item->child = child;
403 		}
404 		else
405 		{
406 			// attach other children to older sibling
407 			prev_child->next = child;
408 			child->prev = prev_child;
409 		}
410 
411 		if (type == cJSON_Object)
412 		{
413 			// object children have identifier string
414 
415 			in = skip_space(parse_string(child, skip_space(in)));
416 			if (in == NULL)  // malformed or memory fail
417 				return NULL;
418 
419 			// parse_string parses into the item's value; we can use it to parse the identifier string, we just have to move the results
420 			child->string = child->valuestring;
421 			child->valuestring = NULL;
422 
423 			if (*in != ':')  // malformed
424 				return NULL;
425 			else
426 				++in;
427 		}
428 
429 		in = skip_space(parse_value(child, skip_space(in)));
430 		if (in == NULL)  // malformed or memory fail
431 			return NULL;
432 
433 		prev_child = child;
434 
435 		if (*in == ',')
436 			++in;
437 		else
438 			break;
439 	}
440 
441 	if (*in == closing)  // end of array/object
442 		return ++in;
443 
444 	return NULL;  // malformed
445 }
446 
447 // Render an array to text
print_array(cJSON * item,int depth)448 static char *print_array(cJSON *item,int depth)
449 {
450 	char *out, *ptr;
451 	size_t len = 3;  // minimum needed to print empty array
452 
453 	ptr = out = (char*)cJSON_malloc(len);
454 
455 	strcpy(ptr, "[");
456 	ptr += 1;
457 
458 	cJSON *child = item->child;
459 
460 	while (child)
461 	{
462 		char *ret = print_value(child, depth + 1);
463 		if (!ret)
464 		{
465 			cJSON_free(out);
466 			return NULL;
467 		}
468 		size_t ret_len = strlen(ret);
469 
470 		len += ret_len + 2;
471 		ptr = out = (char*)cJSON_realloc(out, len);
472 		ptr += strlen(out);
473 
474 		strcpy(ptr, ret);  // strcat(out, ret);
475 		ptr += ret_len;
476 
477 		cJSON_free(ret);
478 
479 		if (child->next)
480 		{
481 			strcpy(ptr, ", ");  // strcat(out, ", ");
482 			ptr += 2;
483 		}
484 
485 		child = child->next;
486 	}
487 
488 	strcpy(ptr, "]");  // strcat(out, "]");
489 
490 	return out;
491 }
492 
493 // Render an object to text.
print_object(cJSON * item,int depth)494 static char *print_object(cJSON *item,int depth)
495 {
496 	char *out, *ptr;
497 	size_t len = 4 + depth;  // minimum needed to print empty object
498 
499 	++depth;
500 
501 	ptr = out = (char*)cJSON_malloc(len);
502 
503 	strcpy(ptr, "{\n");
504 	ptr += 2;
505 
506 	cJSON *child = item->child;
507 
508 	while (child)
509 	{
510 		char *str = print_string_ptr(child->string);
511 		if (!str)
512 		{
513 			cJSON_free(out);
514 			return NULL;
515 		}
516 		size_t str_len = strlen(str);
517 
518 		char *ret = print_value(child, depth);
519 		if (!ret)
520 		{
521 			cJSON_free(str);
522 			cJSON_free(out);
523 			return NULL;
524 		}
525 		size_t ret_len = strlen(ret);
526 
527 		len += depth + str_len + ret_len + 4;
528 		out = (char*)cJSON_realloc(out, len);
529 		ptr = out + strlen(out);
530 
531 		for (int i = 0; i < depth; ++i)
532 			*(ptr++) = '\t';
533 
534 		strcpy(ptr, str);  // strcat(out, str);
535 		ptr += str_len;
536 
537 		cJSON_free(str);
538 
539 		strcpy(ptr, ":\t");  // strcat(out, ":\t");
540 		ptr += 2;
541 
542 		strcpy(ptr, ret);  // strcat(out, ret);
543 		ptr += ret_len;
544 
545 		cJSON_free(ret);
546 
547 		if (child->next)
548 		{
549 			strcpy(ptr, ",\n");  // strcat(out, ",\n");
550 			ptr += 2;
551 		}
552 		else
553 		{
554 			strcpy(ptr, "\n");  // strcat(out, "\n");
555 			ptr += 1;
556 		}
557 
558 		child = child->next;
559 	}
560 
561 	--depth;
562 
563 	for (int i = 0; i < depth; ++i)
564 		*(ptr++) = '\t';
565 
566 	strcpy(ptr, "}");  // strcat(out, "}");
567 
568 	return out;
569 }
570 
571 // Get Array size/item / object item.
cJSON_GetArraySize(cJSON * array)572 int cJSON_GetArraySize( cJSON *array )
573 {
574 	int size = 0;
575 	cJSON *item = array->child;
576 	while (item != NULL)
577 		item = item->next, ++size;
578 	return size;
579 }
cJSON_GetArrayItem(cJSON * array,int index)580 cJSON *cJSON_GetArrayItem( cJSON *array, int index )
581 {
582 	cJSON *item = array->child;
583 	while (item != NULL && index > 0)
584 		item = item->next, --index;
585 	return item;
586 }
cJSON_GetObjectItem(cJSON * object,const char * string)587 cJSON *cJSON_GetObjectItem( cJSON *object, const char *string)
588 {
589 	cJSON *item=object->child;
590 	while (item != NULL && cJSON_strcasecmp(item->string, string) != 0)
591 		item = item->next;
592 	return item;
593 }
594 
cJSON_CreateOrGetObjectItem(cJSON * object,const char * string)595 cJSON *cJSON_CreateOrGetObjectItem( cJSON *object, const char *string )
596 {
597 	cJSON *child = cJSON_GetObjectItem(object, string);
598 	if (child == NULL)
599 		cJSON_AddItemToObject(object, string, child = cJSON_CreateNull());
600 
601 	return child;
602 }
603 
604 // Utility for array list handling.
suffix_object(cJSON * prev,cJSON * item)605 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
606 
607 // Add item to array/object.
cJSON_AddItemToArray(cJSON * array,cJSON * item)608 void   cJSON_AddItemToArray(cJSON *array, cJSON *item)						{cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
cJSON_AddItemToObject(cJSON * object,const char * string,cJSON * item)609 void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)	{if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
610 
611 // remove all items from array/object
cJSON_ClearArray(cJSON * array)612 void cJSON_ClearArray( cJSON *array )
613 {
614 	cJSON_Delete(array->child);
615 	array->child = NULL;
616 }
617 
618 // create basic types
619 
cJSON_CreateNull(void)620 cJSON *cJSON_CreateNull( void )
621 {
622 	return cJSON_NewItem(cJSON_NULL);
623 }
cJSON_CreateBoolean(bool value)624 cJSON *cJSON_CreateBoolean( bool value )
625 {
626 	return cJSON_NewItem(value ? cJSON_True : cJSON_False);
627 }
cJSON_CreateNumber(double value)628 cJSON *cJSON_CreateNumber( double value )
629 {
630 	cJSON *item = cJSON_NewItem(cJSON_Number);
631 	item->valueint = item->valuedouble = value;
632 	return item;
633 }
cJSON_CreateString(const char * value)634 cJSON *cJSON_CreateString( const char *value )
635 {
636 	cJSON *item = cJSON_NewItem(cJSON_String);
637 	item->valuestring = cJSON_strdup(value);
638 	return item;
639 }
cJSON_CreateArray(void)640 cJSON *cJSON_CreateArray( void )
641 {
642 	return cJSON_NewItem(cJSON_Array);
643 }
cJSON_CreateObject(void)644 cJSON *cJSON_CreateObject( void )
645 {
646 	return cJSON_NewItem(cJSON_Object);
647 }
648 
cJSON_ForceType(cJSON * item,cJSON_Type type)649 void cJSON_ForceType( cJSON *item, cJSON_Type type )
650 {
651 	if (item->type != type)
652 	{
653 		cJSON_Delete(item->child);
654 		item->child = NULL;
655 
656 		item->type = type;
657 	}
658 }
659 
cJSON_SetBoolean(cJSON * item,bool value)660 void cJSON_SetBoolean( cJSON *item, bool value )
661 {
662 	cJSON_ForceType(item, value ? cJSON_True : cJSON_False);
663 }
cJSON_SetNumber(cJSON * item,double value)664 void cJSON_SetNumber( cJSON *item, double value )
665 {
666 	cJSON_ForceType(item, cJSON_Number);
667 	item->valueint = item->valuedouble = value;
668 }
cJSON_SetString(cJSON * item,const char * value)669 void cJSON_SetString( cJSON *item, const char *value )
670 {
671 	cJSON_ForceType(item, cJSON_String);
672 	cJSON_free(item->valuestring);
673 	item->valuestring = cJSON_strdup(value);
674 }
675 
676 // Create Arrays:
cJSON_CreateIntArray(int * numbers,int count)677 cJSON *cJSON_CreateIntArray(int *numbers,int count)				{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateFloatArray(float * numbers,int count)678 cJSON *cJSON_CreateFloatArray(float *numbers,int count)			{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateDoubleArray(double * numbers,int count)679 cJSON *cJSON_CreateDoubleArray(double *numbers,int count)		{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateStringArray(const char ** strings,int count)680 cJSON *cJSON_CreateStringArray(const char **strings,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
681