diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-06-17 23:28:44 +0200 |
---|---|---|
committer | Tomaz Canabrava <tcanabrava@kde.org> | 2018-06-24 20:31:14 +0200 |
commit | db0dd54c376eb25263059075e5103f0849ef2ffe (patch) | |
tree | c09508b373812d440aca2149e40e98612ffe291e | |
parent | 879cb73b8bda364f63cc97c0f9963cfddc581add (diff) | |
download | subsurface-db0dd54c376eb25263059075e5103f0849ef2ffe.tar.gz |
Localization: make cache thread safe and robust against use-after-free
The old trGettext() was not thread-safe and the returned C-strings
could be freed in the case of empty translations strings. Therefore:
1) Introduce a mutex protecting access to the cache.
2) Never change existing entries, even if the translation string is empty.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | core/gettextfromc.cpp | 12 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 1 |
2 files changed, 9 insertions, 4 deletions
diff --git a/core/gettextfromc.cpp b/core/gettextfromc.cpp index fdb1e6d37..c3a592f5b 100644 --- a/core/gettextfromc.cpp +++ b/core/gettextfromc.cpp @@ -1,13 +1,17 @@ // SPDX-License-Identifier: GPL-2.0 #include "gettextfromc.h" #include <QHash> +#include <QMutex> static QHash<QByteArray, QByteArray> translationCache; +static QMutex lock; extern "C" const char *trGettext(const char *text) { - QByteArray &result = translationCache[QByteArray(text)]; - if (result.isEmpty()) - result = gettextFromC::tr(text).toUtf8(); - return result.constData(); + QByteArray key(text); + QMutexLocker l(&lock); + auto it = translationCache.find(key); + if (it == translationCache.end()) + it = translationCache.insert(key, gettextFromC::tr(text).toUtf8()); + return it->constData(); } diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index 95efcca63..b22b7e265 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -14,6 +14,7 @@ #include <QToolBar> #include <QStatusBar> +#include "core/gettextfromc.h" #include "core/version.h" #include "core/subsurface-string.h" #include "desktop-widgets/divelistview.h" |