Ignore:
Timestamp:
Jul 7, 2010, 4:48:23 PM (11 years ago)
Author:
charles
Message:

(2.0x trunk) #3397 "checksum errors when downloading files whose names are encoded in iso-8859-1" -- fixed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/utils.c

    r10956 r10963  
    1717#if defined(SYS_DARWIN)
    1818 #define HAVE_GETPAGESIZE
     19 #define HAVE_ICONV_OPEN
    1920 #define HAVE_VALLOC
    2021 #undef HAVE_POSIX_MEMALIGN /* not supported on OS X 10.5 and lower */
     
    3132#include <time.h> /* nanosleep() */
    3233
     34#ifdef HAVE_ICONV_OPEN
     35 #include <iconv.h>
     36#endif
    3337#include <libgen.h> /* basename() */
    3438#include <sys/time.h>
     
    11621166***/
    11631167
    1164 char*
    1165 tr_utf8clean( const char * str, int max_len, tr_bool * err )
     1168static char*
     1169strip_non_utf8( const char * in, size_t inlen )
    11661170{
    11671171    char * ret;
    11681172    const char * end;
     1173    const char zero = '\0';
     1174    struct evbuffer * buf = evbuffer_new( );
     1175 
     1176    while( !tr_utf8_validate( in, inlen, &end ) )
     1177    {
     1178        const int good_len = end - in;
     1179
     1180        evbuffer_add( buf, in, good_len );
     1181        inlen -= ( good_len + 1 );
     1182        in += ( good_len + 1 );
     1183        evbuffer_add( buf, "?", 1 );
     1184    }
     1185 
     1186    evbuffer_add( buf, in, inlen );
     1187    evbuffer_add( buf, &zero, 1 );
     1188    ret = tr_memdup( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ) );
     1189    evbuffer_free( buf );
     1190    return ret;
     1191}
     1192
     1193static char*
     1194to_utf8( const char * in, size_t inlen )
     1195{
     1196    char * ret = NULL;
     1197
     1198#ifdef HAVE_ICONV_OPEN
     1199    int i;
     1200    const char * encodings[] = { "CURRENT", "ISO-8859-15" };
     1201    const int encoding_count = sizeof(encodings) / sizeof(encodings[1]);
     1202    const size_t buflen = inlen*4 + 10;
     1203    char * out = tr_new( char, buflen );
     1204
     1205    for( i=0; !ret && i<encoding_count; ++i )
     1206    {
     1207        char * inbuf = (char*) in;
     1208        char * outbuf = out;
     1209        size_t inbytesleft = inlen;
     1210        size_t outbytesleft = buflen;
     1211        const char * test_encoding = encodings[i];
     1212
     1213        iconv_t cd = iconv_open( "UTF-8", test_encoding );
     1214        if( cd != (iconv_t)-1 ) {
     1215            if( iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft ) != (size_t)-1 )
     1216                ret = tr_strndup( out, buflen-outbytesleft );
     1217            iconv_close( cd );
     1218        }
     1219    }
     1220#endif
     1221
     1222    if( ret == NULL )
     1223        ret = strip_non_utf8( in, inlen );
     1224
     1225    return ret;
     1226}
     1227
     1228char*
     1229tr_utf8clean( const char * str, int max_len )
     1230{
     1231    char * ret;
     1232    const char * end;
    11691233
    11701234    if( max_len < 0 )
    11711235        max_len = (int) strlen( str );
    11721236
    1173     if( err != NULL )
    1174         *err = FALSE;
    1175 
    11761237    if( tr_utf8_validate( str, max_len, &end  ) )
    1177     {
    11781238        ret = tr_strndup( str, max_len );
    1179     }
    11801239    else
    1181     {
    1182         const char zero = '\0';
    1183         struct evbuffer * buf = evbuffer_new( );
    1184 
    1185         while( !tr_utf8_validate ( str, max_len, &end ) )
    1186         {
    1187             const int good_len = end - str;
    1188 
    1189             evbuffer_add( buf, str, good_len );
    1190             max_len -= ( good_len + 1 );
    1191             str += ( good_len + 1 );
    1192             evbuffer_add( buf, "?", 1 );
    1193 
    1194             if( err != NULL )
    1195                 *err = TRUE;
    1196         }
    1197 
    1198         evbuffer_add( buf, str, max_len );
    1199         evbuffer_add( buf, &zero, 1 );
    1200         ret = tr_memdup( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ) );
    1201         evbuffer_free( buf );
    1202     }
     1240        ret = to_utf8( str, max_len );
    12031241
    12041242    assert( tr_utf8_validate( ret, -1, NULL ) );
Note: See TracChangeset for help on using the changeset viewer.