Skip to content

Commit 75c66fc

Browse files
authored
Merge PR #6635: FIX(client): Fix Windows Unicode paths when using raw file streams
2 parents 56d44cc + fe5fe68 commit 75c66fc

File tree

4 files changed

+31
-8
lines changed

4 files changed

+31
-8
lines changed

src/QtUtils.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <QStringList>
88
#include <QUrl>
99

10+
#include <filesystem>
11+
1012
namespace Mumble {
1113
namespace QtUtils {
1214
void deleteQObject(QObject *object) { object->deleteLater(); }
@@ -23,6 +25,17 @@ namespace QtUtils {
2325
return QString();
2426
}
2527

28+
std::filesystem::path qstring_to_path(const QString &input) {
29+
// Path handling uses wide character encoding on Windows.
30+
// When converting from QStrings, we need to take that
31+
// into account, otherwise raw file operations will fail when
32+
// the path contains Unicode characters.
33+
#ifdef Q_OS_WIN
34+
return std::filesystem::path(input.toStdWString());
35+
#else
36+
return std::filesystem::path(input.toUtf8().data());
37+
#endif
38+
}
2639

2740
} // namespace QtUtils
2841
} // namespace Mumble

src/QtUtils.h

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <QString>
1111
#include <QStringList>
1212

13+
#include <filesystem>
14+
1315
#include <memory>
1416

1517
class QObject;
@@ -34,6 +36,11 @@ namespace QtUtils {
3436
*/
3537
QString decode_first_utf8_qssl_string(const QStringList &list);
3638

39+
/**
40+
* Creates a platform agnostic path from a QString
41+
*/
42+
std::filesystem::path qstring_to_path(const QString &input);
43+
3744
} // namespace QtUtils
3845
} // namespace Mumble
3946

src/mumble/PluginInstaller.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "PluginInstaller.h"
77
#include "PluginManager.h"
88
#include "PluginManifest.h"
9+
#include "QtUtils.h"
910
#include "Global.h"
1011

1112
#include <QMessageBox>
@@ -127,7 +128,7 @@ void PluginInstaller::init() {
127128

128129
zipInput.clear();
129130
Poco::Zip::ZipInputStream zipin(zipInput, pluginIt->second);
130-
std::ofstream out(tmpPluginPath.toStdString(), std::ios::out | std::ios::binary);
131+
std::ofstream out(Mumble::QtUtils::qstring_to_path(tmpPluginPath), std::ios::out | std::ios::binary);
131132
Poco::StreamCopier::copyStream(zipin, out);
132133

133134
m_pluginSource = QFileInfo(tmpPluginPath);

src/mumble/Settings.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "EnvUtils.h"
1111
#include "JSONSerialization.h"
1212
#include "Log.h"
13+
#include "QtUtils.h"
1314
#include "SSL.h"
1415
#include "SettingsKeys.h"
1516
#include "SettingsMacros.h"
@@ -155,11 +156,12 @@ void Settings::save(const QString &path) const {
155156
QFile tmpFile(QString::fromLatin1("%1/mumble_settings.json.tmp")
156157
.arg(QStandardPaths::writableLocation(QStandardPaths::TempLocation)));
157158

158-
{
159-
// The separate scope makes sure, the stream is closed again after the write has finished
160-
std::ofstream stream(tmpFile.fileName().toUtf8());
159+
std::ofstream stream(Mumble::QtUtils::qstring_to_path(tmpFile.fileName()));
160+
stream << settingsJSON.dump(4) << std::endl;
161+
stream.close();
161162

162-
stream << settingsJSON.dump(4) << std::endl;
163+
if (stream.fail()) {
164+
qWarning("Failed at writing temporary settings file: %s", qUtf8Printable(tmpFile.fileName()));
163165
}
164166

165167
QFile targetFile(path);
@@ -222,7 +224,7 @@ void Settings::load(const QString &path) {
222224
settingsLocation = path;
223225
}
224226

225-
std::ifstream stream(path.toUtf8());
227+
std::ifstream stream(Mumble::QtUtils::qstring_to_path(path));
226228

227229
nlohmann::json settingsJSON;
228230
try {
@@ -611,13 +613,13 @@ void OverlaySettings::savePresets(const QString &filename) {
611613
settingsJSON.erase(SettingsKeys::OVERLAY_LAUNCHERS_KEY);
612614
settingsJSON.erase(SettingsKeys::OVERLAY_LAUNCHERS_EXCLUDE_KEY);
613615

614-
std::ofstream stream(filename.toUtf8());
616+
std::ofstream stream(Mumble::QtUtils::qstring_to_path(filename));
615617

616618
stream << settingsJSON.dump(4) << std::endl;
617619
}
618620

619621
void OverlaySettings::load(const QString &filename) {
620-
std::ifstream stream(filename.toUtf8());
622+
std::ifstream stream(Mumble::QtUtils::qstring_to_path(filename));
621623

622624
nlohmann::json settingsJSON;
623625
try {

0 commit comments

Comments
 (0)