From 97e1e60c6c440f55aa551b7cb0a76605ea2ce09d Mon Sep 17 00:00:00 2001 From: Jordan Lee Date: Sun, 19 Aug 2012 16:12:20 +0000 Subject: [PATCH] (trunk, qt) #4760 'transmission-qt breaks unicode characters in the default target dir' -- fixed with patch from rb07 --- qt/prefs.cc | 21 +++++++++++++++------ qt/prefs.h | 2 +- qt/session.cc | 4 ++-- qt/utils.cc | 22 ++++++++++++++++++++++ qt/utils.h | 2 ++ 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/qt/prefs.cc b/qt/prefs.cc index cf6f8cdf6..cf2cc25fa 100644 --- a/qt/prefs.cc +++ b/qt/prefs.cc @@ -12,7 +12,6 @@ #include #include -#include // strtod #include #include @@ -21,8 +20,10 @@ #include #include #include +#include #include "prefs.h" #include "types.h" +#include "utils.h" /*** **** @@ -125,7 +126,7 @@ Prefs::PrefItem Prefs::myItems[] = ***/ Prefs :: Prefs( const char * configDir ): - myConfigDir( configDir ) + myConfigDir( QString::fromUtf8( configDir ) ) { assert( sizeof(myItems) / sizeof(myItems[0]) == PREFS_COUNT ); for( int i=0; i().name().toUtf8().constData() ); break; case QVariant::String: - tr_bencDictAddStr( &top, key, val.toString().toUtf8().constData() ); + { const char * s = val.toByteArray().constData(); + if ( Utils::isValidUtf8( s ) ) + tr_bencDictAddStr( &top, key, s ); + else + tr_bencDictAddStr( &top, key, val.toString().toUtf8().constData() ); + } break; case QVariant::Bool: tr_bencDictAddBool( &top, key, val.toBool() ); @@ -253,7 +259,7 @@ Prefs :: initDefaults( tr_benc * d ) tr_bencDictAddBool( d, keyStr(INHIBIT_HIBERNATION), false ); tr_bencDictAddInt ( d, keyStr(BLOCKLIST_DATE), 0 ); tr_bencDictAddBool( d, keyStr(BLOCKLIST_UPDATES_ENABLED), true ); - tr_bencDictAddStr ( d, keyStr(OPEN_DIALOG_FOLDER), QDir::home().absolutePath().toLatin1() ); + tr_bencDictAddStr ( d, keyStr(OPEN_DIALOG_FOLDER), QDir::home().absolutePath().toUtf8() ); tr_bencDictAddInt ( d, keyStr(SHOW_TRACKER_SCRAPES), false ); tr_bencDictAddBool( d, keyStr(TOOLBAR), true ); tr_bencDictAddBool( d, keyStr(FILTERBAR), true ); @@ -297,7 +303,10 @@ QString Prefs :: getString( int key ) const { assert( myItems[key].type == QVariant::String ); - return myValues[key].toString( ); + QByteArray b = myValues[key].toByteArray(); + if ( Utils::isValidUtf8( b.constData() ) ) + myValues[key].setValue( QString::fromUtf8( b.constData() ) ); + return myValues[key].toString(); } int diff --git a/qt/prefs.h b/qt/prefs.h index 74d97b038..6bee82b1d 100644 --- a/qt/prefs.h +++ b/qt/prefs.h @@ -141,7 +141,7 @@ class Prefs: public QObject private: QSet myTemporaryPrefs; QString myConfigDir; - QVariant myValues[PREFS_COUNT]; + mutable QVariant myValues[PREFS_COUNT]; void initDefaults( struct tr_benc* ); public: diff --git a/qt/session.cc b/qt/session.cc index bd67f8142..d5bb61f92 100644 --- a/qt/session.cc +++ b/qt/session.cc @@ -101,7 +101,7 @@ Session :: sessionSet( const char * key, const QVariant& value ) case QVariant::Bool: tr_bencDictAddBool ( args, key, value.toBool() ); break; case QVariant::Int: tr_bencDictAddInt ( args, key, value.toInt() ); break; case QVariant::Double: tr_bencDictAddReal ( args, key, value.toDouble() ); break; - case QVariant::String: tr_bencDictAddStr ( args, key, value.toString().toUtf8() ); break; + case QVariant::String: tr_bencDictAddStr ( args, key, value.toString().toUtf8().constData() ); break; default: assert( "unknown type" ); } exec( &top ); @@ -245,7 +245,7 @@ Session :: Session( const char * configDir, Prefs& prefs ): myBlocklistSize( -1 ), myPrefs( prefs ), mySession( 0 ), - myConfigDir( configDir ), + myConfigDir( QString::fromUtf8( configDir ) ), myNAM( 0 ) { myStats.ratio = TR_RATIO_NA; diff --git a/qt/utils.cc b/qt/utils.cc index 0b3a5d968..c92ed4d36 100644 --- a/qt/utils.cc +++ b/qt/utils.cc @@ -117,3 +117,25 @@ Utils :: guessMimeIcon( const QString& filename ) return fallback; } + +bool +Utils :: isValidUtf8 ( const char *s ) +{ + int n; // number of bytes in a UTF-8 sequence + + for ( const char *c = s; *c; c += n ) + { + if ( (*c & 0x80) == 0x00 ) n = 1; // ASCII + else if ((*c & 0xc0) == 0x80) return false; // not valid + else if ((*c & 0xe0) == 0xc0) n = 2; + else if ((*c & 0xf0) == 0xe0) n = 3; + else if ((*c & 0xf8) == 0xf0) n = 4; + else if ((*c & 0xfc) == 0xf8) n = 5; + else if ((*c & 0xfe) == 0xfc) n = 6; + else return false; + for ( int m = 1; m < n; m++ ) + if ( (c[m] & 0xc0) != 0x80 ) + return false; + } + return true; +} diff --git a/qt/utils.h b/qt/utils.h index 05658ebac..9af8100f0 100644 --- a/qt/utils.h +++ b/qt/utils.h @@ -32,6 +32,8 @@ class Utils: public QObject public: static QString remoteFileChooser( QWidget * parent, const QString& title, const QString& myPath, bool dir, bool local ); static const QIcon& guessMimeIcon( const QString& filename ); + // Test if string is UTF-8 or not + static bool isValidUtf8 ( const char *s ); // meh static void toStderr( const QString& qstr );