|  | @@ -36,7 +36,6 @@
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void *(*cJSON_malloc)(size_t sz) = malloc;
 | 
	
		
			
				|  |  | -static void *(*cJSON_realloc)(void *ptr, size_t sz) = realloc;
 | 
	
		
			
				|  |  |  static void (*cJSON_free)(void *ptr) = free;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static char* cJSON_strdup(const char* str)
 | 
	
	
		
			
				|  | @@ -54,13 +53,11 @@ void cJSON_InitHooks(cJSON_Hooks* hooks)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      if (!hooks) { /* Reset hooks */
 | 
	
		
			
				|  |  |          cJSON_malloc = malloc;
 | 
	
		
			
				|  |  | -        cJSON_realloc = realloc;
 | 
	
		
			
				|  |  |          cJSON_free = free;
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
 | 
	
		
			
				|  |  | -	cJSON_realloc= (hooks->realloc_fn)?hooks->realloc_fn:realloc;
 | 
	
		
			
				|  |  |  	cJSON_free	 = (hooks->free_fn)?hooks->free_fn:free;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -300,23 +297,50 @@ static const char *parse_array(cJSON *item,const char *value)
 | 
	
		
			
				|  |  |  // Render an array to text
 | 
	
		
			
				|  |  |  static char *print_array(cJSON *item,int depth)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	char *out,*ptr,*ret;int len=5;
 | 
	
		
			
				|  |  | +	char **entries;
 | 
	
		
			
				|  |  | +	char *out=0,*ptr,*ret;int len=5;
 | 
	
		
			
				|  |  |  	cJSON *child=item->child;
 | 
	
		
			
				|  |  | +	int numentries=0,i=0,fail=0;
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  | -	out=(char*)cJSON_malloc(len);*out='[';
 | 
	
		
			
				|  |  | -	ptr=out+1;*ptr=0;
 | 
	
		
			
				|  |  | -	while (child)
 | 
	
		
			
				|  |  | +	// How many entries in the array?
 | 
	
		
			
				|  |  | +	while (child) numentries++,child=child->next;
 | 
	
		
			
				|  |  | +	// Allocate an array to hold the values for each
 | 
	
		
			
				|  |  | +	entries=(char**)cJSON_malloc(numentries*sizeof(char*));
 | 
	
		
			
				|  |  | +	if (!entries) return 0;
 | 
	
		
			
				|  |  | +	memset(entries,0,numentries*sizeof(char*));
 | 
	
		
			
				|  |  | +	// Retrieve all the results:
 | 
	
		
			
				|  |  | +	child=item->child;
 | 
	
		
			
				|  |  | +	while (child && !fail)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		ret=print_value(child,depth+1);
 | 
	
		
			
				|  |  | -		if (!ret) {cJSON_free(out);return 0;}	// Check for failure!
 | 
	
		
			
				|  |  | -		len+=strlen(ret)+3;
 | 
	
		
			
				|  |  | -		out=(char*)cJSON_realloc(out,len);
 | 
	
		
			
				|  |  | -		ptr=out+strlen(out);
 | 
	
		
			
				|  |  | -		ptr+=sprintf(ptr,"%s",ret);
 | 
	
		
			
				|  |  | -		if (child->next) {*ptr++=',';*ptr++=' ';*ptr=0;}
 | 
	
		
			
				|  |  | +		entries[i++]=ret;
 | 
	
		
			
				|  |  | +		if (ret) len+=strlen(ret)+3; else fail=1;
 | 
	
		
			
				|  |  |  		child=child->next;
 | 
	
		
			
				|  |  | -		cJSON_free(ret);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	// If we didn't fail, try to malloc the output string
 | 
	
		
			
				|  |  | +	if (!fail) out=cJSON_malloc(len);
 | 
	
		
			
				|  |  | +	// If that fails, we fail.
 | 
	
		
			
				|  |  | +	if (!out) fail=1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Handle failure.
 | 
	
		
			
				|  |  | +	if (fail)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
 | 
	
		
			
				|  |  | +		cJSON_free(entries);
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	// Compose the output array.
 | 
	
		
			
				|  |  | +	*out='[';
 | 
	
		
			
				|  |  | +	ptr=out+1;*ptr=0;
 | 
	
		
			
				|  |  | +	for (i=0;i<numentries;i++)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
 | 
	
		
			
				|  |  | +		if (i!=numentries-1) {*ptr++=',';*ptr++=' ';*ptr=0;}
 | 
	
		
			
				|  |  | +		cJSON_free(entries[i]);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	cJSON_free(entries);
 | 
	
		
			
				|  |  |  	*ptr++=']';*ptr++=0;
 | 
	
		
			
				|  |  |  	return out;	
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -359,29 +383,56 @@ static const char *parse_object(cJSON *item,const char *value)
 | 
	
		
			
				|  |  |  // Render an object to text.
 | 
	
		
			
				|  |  |  static char *print_object(cJSON *item,int depth)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	char *out,*ptr,*ret,*str;int len=7,i;
 | 
	
		
			
				|  |  | +	char **entries=0,**names=0;
 | 
	
		
			
				|  |  | +	char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
 | 
	
		
			
				|  |  |  	cJSON *child=item->child;
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	depth++;len+=depth;out=(char*)cJSON_malloc(len);*out='{';
 | 
	
		
			
				|  |  | -	ptr=out+1;*ptr++='\n';*ptr=0;
 | 
	
		
			
				|  |  | +	int numentries=0,fail=0;
 | 
	
		
			
				|  |  | +	// Count the number of entries.
 | 
	
		
			
				|  |  | +	while (child) numentries++,child=child->next;
 | 
	
		
			
				|  |  | +	// Allocate space for the names and the objects
 | 
	
		
			
				|  |  | +	entries=(char**)cJSON_malloc(numentries*sizeof(char*));
 | 
	
		
			
				|  |  | +	if (!entries) return 0;
 | 
	
		
			
				|  |  | +	names=(char**)cJSON_malloc(numentries*sizeof(char*));
 | 
	
		
			
				|  |  | +	if (!names) {cJSON_free(entries);return 0;}
 | 
	
		
			
				|  |  | +	memset(entries,0,sizeof(char*)*numentries);
 | 
	
		
			
				|  |  | +	memset(names,0,sizeof(char*)*numentries);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Collect all the results into our arrays:
 | 
	
		
			
				|  |  | +	child=item->child;depth++;len+=depth;
 | 
	
		
			
				|  |  |  	while (child)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		str=print_string_ptr(child->string);
 | 
	
		
			
				|  |  | -		if (!str) {cJSON_free(out);return 0;}
 | 
	
		
			
				|  |  | -		ret=print_value(child,depth);
 | 
	
		
			
				|  |  | -		if (!ret) {cJSON_free(str);cJSON_free(out);return 0;}	// Check for failure!
 | 
	
		
			
				|  |  | -		len+=strlen(ret)+strlen(str)+4+depth;
 | 
	
		
			
				|  |  | -		out=(char*)cJSON_realloc(out,len);
 | 
	
		
			
				|  |  | -		ptr=out+strlen(out);
 | 
	
		
			
				|  |  | -		for (i=0;i<depth;i++) *ptr++='\t';
 | 
	
		
			
				|  |  | -		ptr+=sprintf(ptr,"%s",str);
 | 
	
		
			
				|  |  | +		names[i]=str=print_string_ptr(child->string);
 | 
	
		
			
				|  |  | +		entries[i++]=ret=print_value(child,depth);
 | 
	
		
			
				|  |  | +		if (str && ret) len+=strlen(ret)+strlen(str)+4+depth; else fail=1;
 | 
	
		
			
				|  |  | +		child=child->next;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	// Try to allocate the output string
 | 
	
		
			
				|  |  | +	if (!fail) out=(char*)cJSON_malloc(len);
 | 
	
		
			
				|  |  | +	if (!out) fail=1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Handle failure
 | 
	
		
			
				|  |  | +	if (fail)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		for (i=0;i<numentries;i++) {if (names[i]) free(names[i]);if (entries[i]) free(entries[i]);}
 | 
	
		
			
				|  |  | +		free(names);free(entries);
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	// Compose the output:
 | 
	
		
			
				|  |  | +	*out='{';ptr=out+1;*ptr++='\n';*ptr=0;
 | 
	
		
			
				|  |  | +	for (i=0;i<numentries;i++)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		for (j=0;j<depth;j++) *ptr++='\t';
 | 
	
		
			
				|  |  | +		strcpy(ptr,names[i]);ptr+=strlen(names[i]);
 | 
	
		
			
				|  |  |  		*ptr++=':';*ptr++='\t';
 | 
	
		
			
				|  |  | -		ptr+=sprintf(ptr,"%s",ret);
 | 
	
		
			
				|  |  | -		if (child->next) *ptr++=',';
 | 
	
		
			
				|  |  | +		strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
 | 
	
		
			
				|  |  | +		if (i!=numentries-1) *ptr++=',';
 | 
	
		
			
				|  |  |  		*ptr++='\n';*ptr=0;
 | 
	
		
			
				|  |  | -		child=child->next;
 | 
	
		
			
				|  |  | -		cJSON_free(str);cJSON_free(ret);
 | 
	
		
			
				|  |  | +		cJSON_free(names[i]);cJSON_free(entries[i]);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	cJSON_free(names);cJSON_free(entries);
 | 
	
		
			
				|  |  |  	for (i=0;i<depth-1;i++) *ptr++='\t';
 | 
	
		
			
				|  |  |  	*ptr++='}';*ptr++=0;
 | 
	
		
			
				|  |  |  	return out;	
 |