Skip to content
Permalink
Browse files

MumbleApplication: introduce getenvQString and use it in applicationV…

…ersionRoot.

When built against the MSVC2015 CRT, we can't mix-and-match non-wide and
wide environment variables anymore.

Prior to this commit, MumbleApplication::applicationVersionRoot() used
Qt's qgetenv().

However, because of our change to MSVC2015, we can't use Qt's function
anymore.

Instead, we introduce getenvQString (a static function, local to
MumbleApplication -- for now). This function uses _wgetenv_s on
Windows to retrieve environment variables (expecting that they're all
UTF-16). On non-Windows systems, it uses getenv (and expects keys and
values to be UTF-8).

Fixes #2806
  • Loading branch information...
mkrautz authored and hacst committed Feb 3, 2017
1 parent 487e032 commit 11f92440c50b170d2dce7f63ddb85d07846673f7
Showing with 50 additions and 2 deletions.
  1. +50 −2 src/mumble/MumbleApplication.cpp
@@ -11,6 +11,54 @@
#include "GlobalShortcut.h"
#include "Global.h"

// getenvQString is a wrapper around _wgetenv_s (on Windows)
// and getenv (on everything else).
//
// On Windows, it expects a Unicode environment -- so variables
// are expected to be UTF16.
// On everthing else, it expects the environment variables to be
// UTF-8 encoded.
static QString getenvQString(QString name) {
#ifdef Q_OS_WIN
QByteArray buf;
size_t requiredSize = 0;

static_assert(sizeof(wchar_t) == sizeof(ushort), "expected 2-byte wchar_t");

const wchar_t *wname = reinterpret_cast<const wchar_t *>(name.utf16());

// Query the required buffer size (in elements).
_wgetenv_s(&requiredSize, 0, 0, wname);
if (requiredSize == 0) {
return QString();
}

// Resize buf to fit the value and put it there.
buf.resize(static_cast<int>(requiredSize * sizeof(wchar_t)));
_wgetenv_s(&requiredSize, reinterpret_cast<wchar_t *>(buf.data()), requiredSize * sizeof(wchar_t), wname);

// Find the length of the buffer without
// counting NUL elements.
const wchar_t *wbuf = reinterpret_cast<const wchar_t *>(buf.constData());
size_t len = 0;
for (len = 0; len < requiredSize; len++) {
if (wbuf[len] == 0) {
break;
}
}

// Convert the value to QString and return it.
return QString::fromWCharArray(wbuf, static_cast<int>(len));
#else
QByteArray nameU8 = name.toUtf8();
char *val = ::getenv(nameU8.constData());
if (val == NULL) {
return QString();
}
return QString::fromUtf8(val);
#endif
}

MumbleApplication *MumbleApplication::instance() {
return static_cast<MumbleApplication *>(QCoreApplication::instance());
}
@@ -25,9 +73,9 @@ MumbleApplication::MumbleApplication(int &pargc, char **pargv)
}

QString MumbleApplication::applicationVersionRootPath() {
QByteArray versionRoot = qgetenv("MUMBLE_VERSION_ROOT");
QString versionRoot = getenvQString(QLatin1String("MUMBLE_VERSION_ROOT"));
if (versionRoot.count() > 0) {
return QString::fromUtf8(versionRoot.constData());
return versionRoot;
}
return this->applicationDirPath();
}

0 comments on commit 11f9244

Please sign in to comment.
You can’t perform that action at this time.