summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2018-11-17 20:56:07 +0100
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>2018-11-17 21:00:38 +0100
commit11a04a2d92517abbd231534fa71bd346274f053f (patch)
tree39854f73ad0890497941fbb74bde0a0d2f43edd7
parent8e77509053468d0b28b158a3aed1e88c86b3dd3a (diff)
Fix character encoding issues for non-UTF-8 locales.
Since we (most sensibly) encode text as UTF-8 before encrypting we should assume that the password files contain UTF-8 when decrypting, instead of the current locale encoding. This is the biggest issue on Windows, since it doesn't even officially support locales with UTF-8 encoding. For compatibility, detect if the data is not valid UTF-8 and fall back to Qt's BOM based approach, which provides support for UTF-16 and falls back to current locale encoding. Fixes issue #412
-rw-r--r--src/executor.cpp30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/executor.cpp b/src/executor.cpp
index cd20f11c..c39b76a8 100644
--- a/src/executor.cpp
+++ b/src/executor.cpp
@@ -119,6 +119,26 @@ void Executor::execute(int id, const QString &workDir, const QString &app,
}
/**
+ * @brief decodes the input into a string assuming UTF-8 encoding.
+ * If this fails (which is likely if it is not actually UTF-8)
+ * it will then fall back to Qt's decoding function, which
+ * will try based on BOM and if that fails fall back to local encoding.
+ *
+ * @param in input data
+ * @return Input bytes decoded to string
+ */
+static QString decodeAssumingUtf8(QByteArray in)
+{
+ QTextCodec *codec = QTextCodec::codecForName("UTF-8");
+ QTextCodec::ConverterState state;
+ QString out = codec->toUnicode(in.constData(), in.size(), &state);
+ if (!state.invalidChars)
+ return out;
+ codec = QTextCodec::codecForUtfText(in);
+ return codec->toUnicode(in);
+}
+
+/**
* @brief Executor::executeBlocking blocking version of the executor,
* takes input and presents it as stdin
* @param app
@@ -147,9 +167,8 @@ int Executor::executeBlocking(QString app, const QStringList &args,
}
internal.waitForFinished(-1);
if (internal.exitStatus() == QProcess::NormalExit) {
- QTextCodec *codec = QTextCodec::codecForLocale();
- QString pout = codec->toUnicode(internal.readAllStandardOutput());
- QString perr = codec->toUnicode(internal.readAllStandardError());
+ QString pout = decodeAssumingUtf8(internal.readAllStandardOutput());
+ QString perr = decodeAssumingUtf8(internal.readAllStandardError());
if (process_out != Q_NULLPTR)
*process_out = pout;
if (process_err != Q_NULLPTR)
@@ -205,11 +224,10 @@ void Executor::finished(int exitCode, QProcess::ExitStatus exitStatus) {
running = false;
if (exitStatus == QProcess::NormalExit) {
QString output, err;
- QTextCodec *codec = QTextCodec::codecForLocale();
if (i.readStdout)
- output = codec->toUnicode(m_process.readAllStandardOutput());
+ output = decodeAssumingUtf8(m_process.readAllStandardOutput());
if (i.readStderr || exitCode != 0) {
- err = codec->toUnicode(m_process.readAllStandardError());
+ err = decodeAssumingUtf8(m_process.readAllStandardError());
if (exitCode != 0) {
#ifdef QT_DEBUG
dbg() << exitCode << err;