]> granicus.if.org Git - transmission/commitdiff
(trunk libT) #1845: if settings.json is empty, T crashes with "Assertion: tr_bencIsDi...
authorCharles Kerr <charles@transmissionbt.com>
Wed, 18 Feb 2009 16:47:27 +0000 (16:47 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Wed, 18 Feb 2009 16:47:27 +0000 (16:47 +0000)
libtransmission/bencode.c
libtransmission/json-test.c
libtransmission/json.c

index 2a262c45f555bee49be2600805366bde222c78f5..7d1de7a9e3ace623c3a39d4871b9572dc151763b 100644 (file)
 #include "ptrarray.h"
 #include "utils.h" /* tr_new(), tr_free() */
 
+#ifndef ENODATA
+ #define ENODATA EIO
+#endif
+
 /**
 ***
 **/
@@ -1465,16 +1469,17 @@ tr_bencSaveJSONFile( const char *    filename,
 ***/
 
 int
-tr_bencLoadFile( const char * filename,
-                 tr_benc *    b )
+tr_bencLoadFile( const char * filename, tr_benc * b )
 {
     int       err;
     size_t    contentLen;
     uint8_t * content;
 
     content = tr_loadFile( filename, &contentLen );
-    if( !content )
+    if( !content && errno )
         err = errno;
+    else if( !content )
+        err = ENODATA;
     else
         err = tr_bencLoad( content, contentLen, b, NULL );
 
@@ -1483,20 +1488,20 @@ tr_bencLoadFile( const char * filename,
 }
 
 int
-tr_bencLoadJSONFile( const char * filename,
-                     tr_benc *    b )
+tr_bencLoadJSONFile( const char * filename, tr_benc * b )
 {
     int        err;
     size_t     contentLen;
     uint8_t  * content;
 
     content = tr_loadFile( filename, &contentLen );
-    if( !content )
+    if( !content && errno )
         err = errno;
+    else if( !content )
+        err = ENODATA;
     else
         err = tr_jsonParse( content, contentLen, b, NULL );
 
     tr_free( content );
     return err;
 }
-
index 1c6474e5ee7a47b5cff64ce32df3e6374612a494..3e241825e916828f5b2b1982f915cb31ce3d6e26 100644 (file)
@@ -139,6 +139,19 @@ test1( void )
     return 0;
 }
 
+static int
+test2( void )
+{
+    tr_benc top;
+    const char * in = " ";
+    const int err = tr_jsonParse( in, strlen( in ), &top, NULL );
+
+    check( err );
+    check( !tr_bencIsDict( &top ) );
+
+    return 0;
+}
+
 int
 main( void )
 {
@@ -150,6 +163,9 @@ main( void )
     if( ( i = test1( ) ) )
         return i;
 
+    if( ( i = test2( ) ) )
+        return i;
+
     return 0;
 }
 
index 8a7c8e156071470a3e9555ff3722685694e2ada5..7e115b52f64a2c546b0ebcede76338cca1edfe53 100644 (file)
 
 struct json_benc_data
 {
-    tr_benc *      top;
+    tr_bool        hasContent;
+    tr_benc      * top;
     tr_ptrArray    stack;
-    char *         key;
+    char         * key;
 };
 
 static tr_benc*
@@ -69,6 +70,7 @@ callback( void *             vdata,
     switch( type )
     {
         case JSON_T_ARRAY_BEGIN:
+            data->hasContent = TRUE;
             node = getNode( data );
             tr_bencInitList( node, 0 );
             tr_ptrArrayAppend( &data->stack, node );
@@ -79,6 +81,7 @@ callback( void *             vdata,
             break;
 
         case JSON_T_OBJECT_BEGIN:
+            data->hasContent = TRUE;
             node = getNode( data );
             tr_bencInitDict( node, 0 );
             tr_ptrArrayAppend( &data->stack, node );
@@ -94,32 +97,39 @@ callback( void *             vdata,
             tr_snprintf( buf, sizeof( buf ), "%f",
                          (double)value->vu.float_value );
             tr_bencInitStr( getNode( data ), buf, -1 );
+            data->hasContent = TRUE;
             break;
         }
 
         case JSON_T_NULL:
+            data->hasContent = TRUE;
             tr_bencInitStr( getNode( data ), "", 0 );
             break;
 
         case JSON_T_INTEGER:
+            data->hasContent = TRUE;
             tr_bencInitInt( getNode( data ), value->vu.integer_value );
             break;
 
         case JSON_T_TRUE:
+            data->hasContent = TRUE;
             tr_bencInitInt( getNode( data ), 1 );
             break;
 
         case JSON_T_FALSE:
+            data->hasContent = TRUE;
             tr_bencInitInt( getNode( data ), 0 );
             break;
 
         case JSON_T_STRING:
+            data->hasContent = TRUE;
             tr_bencInitStr( getNode( data ),
                             value->vu.str.value,
                             value->vu.str.length );
             break;
 
         case JSON_T_KEY:
+            data->hasContent = TRUE;
             assert( !data->key );
             data->key = tr_strdup( value->vu.str.value );
             break;
@@ -129,14 +139,14 @@ callback( void *             vdata,
 }
 
 int
-tr_jsonParse( const void *     vbuf,
+tr_jsonParse( const void     * vbuf,
               size_t           len,
-              tr_benc *        setme_benc,
+              tr_benc        * setme_benc,
               const uint8_t ** setme_end )
 {
     int                         err = 0;
-    const unsigned char *       buf = vbuf;
-    const void *                bufend = buf + len;
+    const unsigned char       * buf = vbuf;
+    const void                * bufend = buf + len;
     struct JSON_config_struct   config;
     struct JSON_parser_struct * checker;
     struct json_benc_data       data;
@@ -146,6 +156,7 @@ tr_jsonParse( const void *     vbuf,
     config.callback_ctx = &data;
     config.depth = -1;
 
+    data.hasContent = FALSE;
     data.key = NULL;
     data.top = setme_benc;
     data.stack = TR_PTR_ARRAY_INIT;
@@ -157,6 +168,9 @@ tr_jsonParse( const void *     vbuf,
     if( buf != bufend )
         err = EILSEQ;
 
+    if( !data.hasContent )
+        err = EINVAL;
+
     if( setme_end )
         *setme_end = (const uint8_t*) buf;