From kde-commits Wed Sep 30 23:44:02 2009 From: David Faure Date: Wed, 30 Sep 2009 23:44:02 +0000 To: kde-commits Subject: branches/KDE/4.3/kdelibs/kdecore Message-Id: <1254354242.670375.21417.nullmailer () svn ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=125435425123992 SVN commit 1029879 by dfaure: Backport 1029862+1029870+1029871: protect access to the list of catalogs (and other KLocalePrivate members) using a mutex. Fix will be in KDE-4.3.2. CCBUG: 208178 M +23 -10 localization/klocale.cpp M +1 -0 tests/klocalizedstringtest.cpp --- branches/KDE/4.3/kdelibs/kdecore/localization/klocale.cpp #1029878:1029879 @@ -68,8 +68,6 @@ KLocaleStaticData (); - QMutex mutex; - QString maincatalog; // FIXME: Temporary until full language-sensitivity implemented. @@ -77,7 +75,6 @@ }; KLocaleStaticData::KLocaleStaticData () -: mutex(QMutex::Recursive) { // Languages using non-Western Arabic digit sets. // FIXME: Temporary until full language-sensitivity implemented. @@ -176,6 +173,8 @@ /** * @internal evaluate the list of catalogs and check that all instances for all languages are loaded * and that they are sorted according to the catalog names + * + * Callers must lock the mutex first. */ void updateCatalogs( ); @@ -243,6 +242,7 @@ // Handling of translation catalogs QStringList languageList; + QMutex* mutex; QList catalogNames; // list of all catalogs (regardless of language) QList catalogs; // list of all found catalogs, one instance per catalog name and language int numberOfSysCatalogs; // number of catalogs that each app draws from @@ -276,8 +276,11 @@ KLocalePrivate::KLocalePrivate(const QString& catalog, KConfig *config, const QString &language_, const QString &country_) : language(language_), country(country_), - useTranscript(false), codecForEncoding(0), - languages(0), calendar(0), catalogName(catalog) + mutex(new QMutex(QMutex::Recursive)), + useTranscript(false), + codecForEncoding(0), + languages(0), calendar(0), + catalogName(catalog) { initEncoding(); initFileNameEncoding(); @@ -308,6 +311,7 @@ void KLocalePrivate::initMainCatalogs() { KLocaleStaticData *s = staticData; + QMutexLocker lock(mutex); if (!s->maincatalog.isEmpty()) { // If setMainCatalog was called, then we use that (e.g. korgac calls setMainCatalog("korganizer") to use korganizer.po) @@ -537,7 +541,8 @@ bool KLocalePrivate::setLanguage(const QString & _language, KConfig *config) { - languageList.removeAll( _language ); + QMutexLocker lock(mutex); + languageList.removeAll( _language ); languageList.prepend( _language ); // let us consider this language to be the most important one language = _language; // remember main language for shortcut evaluation @@ -558,6 +563,7 @@ bool KLocalePrivate::setLanguage(const QStringList & languages) { + QMutexLocker lock(mutex); // This list might contain // 1) some empty strings that we have to eliminate // 2) duplicate entries like in de:fr:de, where we have to keep the first occurrence of a language in order @@ -679,6 +685,7 @@ void KLocale::insertCatalog( const QString & catalog ) { + QMutexLocker lock(d->mutex); int pos = d->catalogNames.indexOf(KCatalogName(catalog)); if (pos != -1) { ++d->catalogNames[pos].loadCount; @@ -729,6 +736,7 @@ void KLocale::removeCatalog(const QString &catalog) { + QMutexLocker lock(d->mutex); int pos = d->catalogNames.indexOf(KCatalogName(catalog)); if (pos == -1) return; @@ -741,6 +749,7 @@ void KLocale::setActiveCatalog(const QString &catalog) { + QMutexLocker lock(d->mutex); int pos = d->catalogNames.indexOf(KCatalogName(catalog)); if (pos == -1) return; @@ -750,9 +759,10 @@ KLocale::~KLocale() { - delete d->calendar; - delete d->languages; - delete d; + delete d->mutex; + delete d->calendar; + delete d->languages; + delete d; } void KLocalePrivate::translate_priv(const char *msgctxt, @@ -1359,7 +1369,7 @@ //Kibi-byte KiB 2^10 1,024 bytes if (d->byteSizeFmt.size() == 0) { - QMutexLocker lock(&staticData->mutex); + QMutexLocker lock(d->mutex); // Pretranslated format strings for byte sizes. #define CACHEBYTEFMT(x) { \ QString s; \ @@ -2557,6 +2567,7 @@ { d->languages = 0; // Don't copy languages d->calendar = 0; // Don't copy the calendar + d->mutex = 0; // Don't copy the mutex } KLocale & KLocale::operator=(const KLocale & rhs) @@ -2571,6 +2582,8 @@ void KLocale::copyCatalogsTo(KLocale *locale) { + QMutexLocker lock(d->mutex); + QMutexLocker lockOther(locale->d->mutex); locale->d->catalogNames = d->catalogNames; locale->d->updateCatalogs(); } --- branches/KDE/4.3/kdelibs/kdecore/tests/klocalizedstringtest.cpp #1029878:1029879 @@ -238,6 +238,7 @@ futures << QtConcurrent::run(this, &KLocalizedStringTest::correctSubs); futures << QtConcurrent::run(this, &KLocalizedStringTest::translateQt); futures << QtConcurrent::run(this, &KLocalizedStringTest::translateQt); + KGlobal::locale()->removeCatalog("kdelibs4"); Q_FOREACH(QFuture f, futures) f.waitForFinished(); QThreadPool::globalInstance()->setMaxThreadCount(1); // delete those threads