From f9683ec428e37360ba5812124a91e8115afb3300 Mon Sep 17 00:00:00 2001 From: scottmk Date: Wed, 21 Apr 2010 20:48:18 +0000 Subject: [PATCH 1/1] Fix the jsonFormatString function. Specifically: it was misbehaving when a string literal contained a comma, square bracket, or curly brace. Now it pays attention to whether those characters are in within quotes or not, and treats them accordingly. It also applies more consistent indentation by consuming extraneous white space that would otherwise lead to ragged margins. M src/libopensrf/osrf_json_tools.c git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1946 9efc2488-bf62-4759-914b-345cdb29e865 --- src/libopensrf/osrf_json_tools.c | 63 ++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/src/libopensrf/osrf_json_tools.c b/src/libopensrf/osrf_json_tools.c index d8e0a8f..e444db9 100644 --- a/src/libopensrf/osrf_json_tools.c +++ b/src/libopensrf/osrf_json_tools.c @@ -13,8 +13,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#include -#include +#include +#include "opensrf/osrf_json.h" +#include "opensrf/osrf_json_utils.h" static jsonObject* findMultiPath( const jsonObject* o, const char* root, const char* path ); @@ -45,42 +46,74 @@ static void append_indentation( growing_buffer* buf, int depth ) { If the input pointer is NULL, return an empty string. + WARNING: if the input JSON is not well-formed, the output JSON is likely + to be even worse-formed. + The calling code is responsible for freeing the formatted copy. */ char* jsonFormatString( const char* string ) { - if(!string) return strdup(""); + if( !string ) return strdup( "" ); - growing_buffer* buf = buffer_init(64); + growing_buffer* buf = buffer_init( 64 ); int i; int depth = 0; + int in_quote = 0; // boolean; true if in a string literal + int escaped = 0; // boolean: true if previous character was a backslash + int beginning = 1; // boolean: true if we're starting a new line char c; - for(i = 0; string[i]; i++) { - c = string[i]; + for( i = 0; string[i]; i++ ) { + c = string[ i ]; if( c == '{' || c == '[' ) { OSRF_BUFFER_ADD_CHAR( buf, c ); - OSRF_BUFFER_ADD_CHAR( buf, '\n' ); - append_indentation( buf, ++depth ); + if( !in_quote ) { + OSRF_BUFFER_ADD_CHAR( buf, '\n' ); + append_indentation( buf, ++depth ); + beginning = 1; + } } else if( c == '}' || c == ']' ) { - OSRF_BUFFER_ADD_CHAR( buf, '\n' ); - append_indentation( buf, --depth ); + if( !in_quote ) { + OSRF_BUFFER_ADD_CHAR( buf, '\n' ); + append_indentation( buf, --depth ); + beginning = 1; + } OSRF_BUFFER_ADD_CHAR( buf, c ); } else if( c == ',' ) { OSRF_BUFFER_ADD_CHAR( buf, ',' ); - OSRF_BUFFER_ADD_CHAR( buf, '\n' ); - append_indentation( buf, depth ); + if( !in_quote ) { + OSRF_BUFFER_ADD_CHAR( buf, '\n' ); + append_indentation( buf, depth ); + beginning = 1; + } - } else - OSRF_BUFFER_ADD_CHAR(buf, c); + } else { + // Ignore white space at the beginning of a line + if( beginning ) { + if( !isspace( (unsigned char) c )) { + OSRF_BUFFER_ADD_CHAR( buf, c ); + beginning = 0; + } + } else { + OSRF_BUFFER_ADD_CHAR( buf, c ); + } + } + + if( '\\' == c ) + escaped = !escaped; + else { + if( '\"' == c && !escaped ) + in_quote = !in_quote; + escaped = 0; + } } - return buffer_release(buf); + return buffer_release( buf ); } -- 2.43.2