From 6ebeef7924dfc503c8d1175dea63cea8d935410a Mon Sep 17 00:00:00 2001 From: Josh Elsasser Date: Sun, 28 Jan 2007 23:26:57 +0000 Subject: [PATCH] Correctly bencode strings containing nul characters. --- libtransmission/bencode.c | 11 ++++------- libtransmission/utils.c | 34 +++++++++++++++++++++++++++++----- libtransmission/utils.h | 3 +++ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/libtransmission/bencode.c b/libtransmission/bencode.c index 58bf94b1b..f3fb472ef 100644 --- a/libtransmission/bencode.c +++ b/libtransmission/bencode.c @@ -164,7 +164,8 @@ static void __bencPrint( benc_val_t * val, int space ) break; case TYPE_STR: - fprintf( stderr, "%s\n", val->val.s.s ); + fwrite( val->val.s.s, 1, val->val.s.i, stderr ); + putc( '\n', stderr ); break; case TYPE_LIST: @@ -265,12 +266,8 @@ int tr_bencSave( benc_val_t * val, char ** buf, int * used, int * max ) break; case TYPE_STR: - if( (int)strlen(val->val.s.s) != val->val.s.i ) - { - return 1; - } - if( tr_sprintf( buf, used, max, "%i:%s", - val->val.s.i, val->val.s.s ) ) + if( tr_sprintf( buf, used, max, "%i:", val->val.s.i ) || + tr_concat( buf, used, max, val->val.s.s, val->val.s.i ) ) { return 1; } diff --git a/libtransmission/utils.c b/libtransmission/utils.c index 8acc353b3..2e99190a5 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -300,22 +300,46 @@ int tr_vsprintf( char ** buf, int * used, int * max, const char * fmt, va_list ap1, va_list ap2 ) { int want; - char * newbuf; want = vsnprintf( NULL, 0, fmt, ap1 ); - while( *used + want + 1 > *max ) + if( tr_concat( buf, used, max, NULL, want ) ) { - *max += SPRINTF_BUFSIZE; - newbuf = realloc( *buf, *max ); + return 1; + } + assert( *used + want + 1 <= *max ); + + *used += vsnprintf( *buf + *used, *max - *used, fmt, ap2 ); + + return 0; +} + +int tr_concat( char ** buf, int * used, int * max, const char * data, int len ) +{ + int newmax; + char * newbuf; + + newmax = *max; + while( *used + len + 1 > newmax ) + { + newmax += SPRINTF_BUFSIZE; + } + if( newmax > *max ) + { + newbuf = realloc( *buf, newmax ); if( NULL == newbuf ) { return 1; } *buf = newbuf; + *max = newmax; } - *used += vsnprintf( *buf + *used, *max - *used, fmt, ap2 ); + if( NULL != data ) + { + memcpy( *buf + *used, data, len ); + *used += len; + } return 0; } diff --git a/libtransmission/utils.h b/libtransmission/utils.h index dd98fc031..2d778e246 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -62,6 +62,9 @@ int tr_sprintf( char ** buf, int * used, int * max, const char * format, ... ) PRINTF( 4, 5 ); /* gee, it sure would be nice if BeOS had va_copy() */ int tr_vsprintf( char **, int *, int *, const char *, va_list, va_list ); +/* this concatenates some binary data onto the end of a buffer */ +int tr_concat( char ** buf, int * used, int * max, + const char * data, int len ); /*********************************************************************** * tr_dupstr