diff --git a/libtransmission/bencode-test.c b/libtransmission/bencode-test.c index 3839de669..31ef4bec6 100644 --- a/libtransmission/bencode-test.c +++ b/libtransmission/bencode-test.c @@ -15,8 +15,7 @@ static int test = 0; if( VERBOSE ) \ fprintf( stderr, "PASS test #%d (%s, %d)\n", test, __FILE__, __LINE__ ); \ } else { \ - if( VERBOSE ) \ - fprintf( stderr, "FAIL test #%d (%s, %d)\n", test, __FILE__, __LINE__ ); \ + fprintf( stderr, "FAIL test #%d (%s, %d)\n", test, __FILE__, __LINE__ ); \ return test; \ } \ } diff --git a/libtransmission/bencode.c b/libtransmission/bencode.c index e8d2d3e89..dc153bd53 100644 --- a/libtransmission/bencode.c +++ b/libtransmission/bencode.c @@ -19,6 +19,8 @@ #include /* evbuffer */ +#include "ConvertUTF.h" + #include "transmission.h" #include "bencode.h" #include "json.h" @@ -1152,9 +1154,9 @@ static void jsonStringFunc( const tr_benc * val, void * vdata ) { struct jsonWalk * data = vdata; - const char *it, *end; + const unsigned char *it, *end; evbuffer_add_printf( data->out, "\"" ); - for( it=val->val.s.s, end=it+val->val.s.i; it!=end; ++it ) + for( it=(const unsigned char*)val->val.s.s, end=it+val->val.s.i; it!=end; ++it ) { switch( *it ) { case '/' : evbuffer_add_printf( data->out, "\\/" ); break; @@ -1165,7 +1167,19 @@ jsonStringFunc( const tr_benc * val, void * vdata ) case '\t': evbuffer_add_printf( data->out, "\\t" ); break; case '"' : evbuffer_add_printf( data->out, "\\\"" ); break; case '\\': evbuffer_add_printf( data->out, "\\\\" ); break; - default: evbuffer_add_printf( data->out, "%c", *it ); + default: + if( isascii( *it ) ) { + /*fprintf( stderr, "[%c]\n", *it );*/ + evbuffer_add_printf( data->out, "%c", *it ); + } else { + const UTF8 * tmp = it; + UTF32 buf = 0; + UTF32 * u32 = &buf; + ConvertUTF8toUTF32( &tmp, end, &u32, &buf+1, 0 ); + evbuffer_add_printf( data->out, "\\u%04x", buf ); + it = tmp - 1; + /*fprintf( stderr, "[\\u%04x]\n", buf );*/ + } } } evbuffer_add_printf( data->out, "\"" ); diff --git a/libtransmission/json-test.c b/libtransmission/json-test.c index a5127cd79..980d8c15e 100644 --- a/libtransmission/json-test.c +++ b/libtransmission/json-test.c @@ -19,22 +19,64 @@ static int test = 0; } \ } +#include "ConvertUTF.h" + static int test_utf8( void ) { const char * in = "{ \"key\": \"Letöltések\" }"; tr_benc top; const char * str; - const int err = tr_jsonParse( in, strlen(in), &top, NULL ); + char * json; + int json_len; + int err; + err = tr_jsonParse( in, strlen(in), &top, NULL ); check( !err ); check( tr_bencIsDict( &top ) ); check( tr_bencDictFindStr( &top, "key", &str ) ); check( !strcmp( str, "Letöltések" ) ); - if( !err ) tr_bencFree( &top ); + in = "{ \"key\": \"\\u005C\" }"; + err = tr_jsonParse( in, strlen( in ), &top, NULL ); + check( !err ); + check( tr_bencIsDict( &top ) ); + check( tr_bencDictFindStr( &top, "key", &str ) ); + check( !strcmp( str, "\\" ) ); + if( !err ) + tr_bencFree( &top ); + + /** + * 1. Feed it JSON-escaped nonascii to the JSON decoder. + * 2. Confirm that the result is UTF-8. + * 3. Feed the same UTF-8 back into the JSON encoder. + * 4. Confirm that the result is JSON-escaped. + * 5. Dogfood that result back into the parser. + * 6. Confirm that the result is UTF-8. + */ + in = "{ \"key\": \"Let\\u00f6lt\\u00e9sek\" }"; + err = tr_jsonParse( in, strlen(in), &top, NULL ); + check( !err ); + check( tr_bencIsDict( &top ) ); + check( tr_bencDictFindStr( &top, "key", &str ) ); + check( !strcmp( str, "Letöltések" ) ); + json = tr_bencSaveAsJSON( &top, &json_len ); + if( !err ) + tr_bencFree( &top ); + check( json ); + check( strstr( json, "\\u00f6" ) != NULL ); + check( strstr( json, "\\u00e9" ) != NULL ); + err = tr_jsonParse( json, json_len, &top, NULL ); + check( !err ); + check( tr_bencIsDict( &top ) ); + check( tr_bencDictFindStr( &top, "key", &str ) ); + check( !strcmp( str, "Letöltések" ) ); + if( !err ) + tr_bencFree( &top ); + tr_free( json ); + return 0; } @@ -89,9 +131,6 @@ main( void ) { int i; - if(( i = test_utf8( ))) - return i; - if(( i = test_utf8( ))) return i;