From 0c453e7e0eddc84d13aeaf50f9886cc799587e20 Mon Sep 17 00:00:00 2001
From: Dale Glass <dale@daleglass.net>
Date: Sun, 28 Nov 2021 22:24:59 +0100
Subject: [PATCH 1/4] Explicitly encode QStrings to utf8

---
 interface/src/Util.cpp                        | 14 +++++-----
 interface/src/commerce/Wallet.cpp             |  2 +-
 libraries/networking/src/AccountManager.cpp   | 26 +++++++++----------
 .../networking/src/DomainAccountManager.cpp   | 20 +++++++-------
 .../networking/src/UserActivityLogger.cpp     |  2 +-
 5 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp
index 0670252406..8808dc34ad 100644
--- a/interface/src/Util.cpp
+++ b/interface/src/Util.cpp
@@ -182,7 +182,7 @@ void runTimingTests() {
     const int EXTRA_JUNK_SIZE = 200;
     extraJunk.append((unsigned char)255);
     for (int i = 0; i < EXTRA_JUNK_SIZE; i++) {
-        extraJunk.append(QString("junk"));
+        extraJunk.append(QString("junk").toUtf8());
     }
 
     {
@@ -257,17 +257,17 @@ void runUnitTests() {
 
     quint64 LAST_TEST = 10;
     quint64 SKIP_BY = 1;
-    
+
     for (quint64 value = 0; value <= LAST_TEST; value += SKIP_BY) {
         qDebug() << "value:" << value;
 
         ByteCountCoded<quint64> codedValue = value;
-    
+
         QByteArray codedValueBuffer = codedValue;
-        
+
         codedValueBuffer.append((unsigned char)255);
-        codedValueBuffer.append(QString("junk"));
-        
+        codedValueBuffer.append(QString("junk").toUtf8());
+
         qDebug() << "codedValueBuffer:";
         outputBufferBits((const unsigned char*)codedValueBuffer.constData(), codedValueBuffer.size());
 
@@ -276,7 +276,7 @@ void runUnitTests() {
         quint64 valueDecoded = valueDecoder;
         qDebug() << "valueDecoded:" << valueDecoded;
         qDebug() << "bytesConsumed:" << bytesConsumed;
-        
+
 
         if (value == valueDecoded) {
             qDebug() << "SUCCESS!";
diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp
index 95533b0fb9..7dfb908844 100644
--- a/interface/src/commerce/Wallet.cpp
+++ b/interface/src/commerce/Wallet.cpp
@@ -525,7 +525,7 @@ bool Wallet::readSecurityImage(const QString& inputFilePath, unsigned char** out
         } else {
             foundFooter = (line == IMAGE_FOOTER);
             if (!foundFooter) {
-                base64EncryptedBuffer.append(line);
+                base64EncryptedBuffer.append(line.toUtf8());
             }
         }
     }
diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp
index 9e4cb01e45..730453aac6 100644
--- a/libraries/networking/src/AccountManager.cpp
+++ b/libraries/networking/src/AccountManager.cpp
@@ -235,7 +235,7 @@ QNetworkRequest AccountManager::createRequest(QString path, AccountManagerAuth::
     } else {
         requestURL.setPath(getMetaverseServerURLPath(true) + path.left(queryStringLocation));
     }
-    
+
     // qCDebug(networking) << "Creating request path" << requestURL;
     // qCDebug(networking) << "requestURL.isValid()" << requestURL.isValid();
     // qCDebug(networking) << "requestURL.errorString()" << requestURL.errorString();
@@ -569,7 +569,7 @@ void AccountManager::requestAccessToken(const QString& login, const QString& pas
     postData.append("grant_type=password&");
     postData.append("username=" + QUrl::toPercentEncoding(login) + "&");
     postData.append("password=" + QUrl::toPercentEncoding(password) + "&");
-    postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+    postData.append(QString("scope=%1").arg(ACCOUNT_MANAGER_REQUESTED_SCOPE).toUtf8());
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -590,10 +590,10 @@ void AccountManager::requestAccessTokenWithAuthCode(const QString& authCode, con
 
     QByteArray postData;
     postData.append("grant_type=authorization_code&");
-    postData.append("client_id=" + clientId + "&");
-    postData.append("client_secret=" + clientSecret + "&");
-    postData.append("code=" + authCode + "&");
-    postData.append("redirect_uri=" + QUrl::toPercentEncoding(redirectUri));
+    postData.append(QString("client_id=%1&").arg(clientId).toUtf8());
+    postData.append(QString("client_secret=%1&").arg(clientSecret).toUtf8());
+    postData.append(QString("code=%1&").arg(authCode).toUtf8());
+    postData.append(QByteArray("redirect_uri=") + QUrl::toPercentEncoding(redirectUri));
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -613,8 +613,8 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) {
 
     QByteArray postData;
     postData.append("grant_type=password&");
-    postData.append("steam_auth_ticket=" + QUrl::toPercentEncoding(authSessionTicket) + "&");
-    postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+    postData.append(QByteArray("steam_auth_ticket=") + QUrl::toPercentEncoding(authSessionTicket) + "&");
+    postData.append(QString("scope=%1").arg(ACCOUNT_MANAGER_REQUESTED_SCOPE).toUtf8());
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -635,9 +635,9 @@ void AccountManager::requestAccessTokenWithOculus(const QString& nonce, const QS
 
     QByteArray postData;
     postData.append("grant_type=password&");
-    postData.append("oculus_nonce=" + nonce + "&");
-    postData.append("oculus_id=" + oculusID + "&");
-    postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+    postData.append(QString("oculus_nonce=%1&").arg(nonce).toUtf8());
+    postData.append(QString("oculus_id=%1&").arg(oculusID).toUtf8());
+    postData.append(QString("scope=%1").arg(ACCOUNT_MANAGER_REQUESTED_SCOPE).toUtf8());
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -666,8 +666,8 @@ void AccountManager::refreshAccessToken() {
 
         QByteArray postData;
         postData.append("grant_type=refresh_token&");
-        postData.append("refresh_token=" + QUrl::toPercentEncoding(_accountInfo.getAccessToken().refreshToken) + "&");
-        postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+        postData.append(QByteArray("refresh_token=") + QUrl::toPercentEncoding(_accountInfo.getAccessToken().refreshToken) + "&");
+        postData.append(QString("scope=%1").arg(ACCOUNT_MANAGER_REQUESTED_SCOPE).toUtf8());
 
         request.setUrl(grantURL);
         request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
diff --git a/libraries/networking/src/DomainAccountManager.cpp b/libraries/networking/src/DomainAccountManager.cpp
index 23c52143f6..de3434c037 100644
--- a/libraries/networking/src/DomainAccountManager.cpp
+++ b/libraries/networking/src/DomainAccountManager.cpp
@@ -57,7 +57,7 @@ void DomainAccountManager::setAuthURL(const QUrl& authURL) {
     }
 
     _currentAuth.authURL = authURL;
-    qCDebug(networking) << "DomainAccountManager URL for authenticated requests has been changed to" 
+    qCDebug(networking) << "DomainAccountManager URL for authenticated requests has been changed to"
         << qPrintable(_currentAuth.authURL.toString());
 
     _currentAuth.accessToken = "";
@@ -70,7 +70,7 @@ bool DomainAccountManager::hasLogIn() {
     return !_currentAuth.authURL.isEmpty();
 }
 
-bool DomainAccountManager::isLoggedIn() { 
+bool DomainAccountManager::isLoggedIn() {
     return !_currentAuth.authURL.isEmpty() && hasValidAccessToken();
 }
 
@@ -90,9 +90,9 @@ void DomainAccountManager::requestAccessToken(const QString& username, const QSt
     // - Ignores "state" parameter.
     QByteArray formData;
     formData.append("grant_type=password&");
-    formData.append("username=" + QUrl::toPercentEncoding(username) + "&");
-    formData.append("password=" + QUrl::toPercentEncoding(password) + "&");
-    formData.append("client_id=" + _currentAuth.clientID);
+    formData.append(QByteArray("username=") + QUrl::toPercentEncoding(username) + "&");
+    formData.append(QByteArray("password=") + QUrl::toPercentEncoding(password) + "&");
+    formData.append(QString("client_id=%1").arg(_currentAuth.clientID).toUtf8());
 
     request.setUrl(_currentAuth.authURL);
 
@@ -168,7 +168,7 @@ bool DomainAccountManager::hasValidAccessToken() {
     }
 
     // ####### TODO
-        
+
     // if (!_isWaitingForTokenRefresh && needsToRefreshToken()) {
     //     refreshAccessToken();
     // }
@@ -184,18 +184,18 @@ void DomainAccountManager::setTokensFromJSON(const QJsonObject& jsonObject, cons
 bool DomainAccountManager::checkAndSignalForAccessToken() {
     bool hasToken = hasValidAccessToken();
 
-    // ####### TODO: Handle hasToken == true. 
-    // It causes the login dialog not to display (OK) but somewhere the domain server needs to be sent it (and if domain server 
+    // ####### TODO: Handle hasToken == true.
+    // It causes the login dialog not to display (OK) but somewhere the domain server needs to be sent it (and if domain server
     // gets error when trying to use it then user should be prompted to login).
     hasToken = false;
-    
+
     if (!hasToken) {
         // Emit a signal so somebody can call back to us and request an access token given a user name and password.
 
         // Dialog can be hidden immediately after showing if we've just teleported to the domain, unless the signal is delayed.
         auto domain = _currentAuth.authURL.host();
         QTimer::singleShot(500, this, [this, domain] {
-            emit this->authRequired(domain); 
+            emit this->authRequired(domain);
         });
     }
 
diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp
index 94d6371ba4..4454648564 100644
--- a/libraries/networking/src/UserActivityLogger.cpp
+++ b/libraries/networking/src/UserActivityLogger.cpp
@@ -52,7 +52,7 @@ void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCall
     // Adding the action name
     QHttpPart actionPart;
     actionPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"action_name\"");
-    actionPart.setBody(QByteArray().append(action));
+    actionPart.setBody(QByteArray().append(action.toUtf8()));
     multipart->append(actionPart);
 
     // Log the local-time that this event was logged

From 6738624bffc73713673ac3248acd3243634320d9 Mon Sep 17 00:00:00 2001
From: Dale Glass <dale@daleglass.net>
Date: Mon, 29 Nov 2021 18:23:06 +0100
Subject: [PATCH 2/4] Two more conversions to Utf8

---
 libraries/octree/src/OctreeDataUtils.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libraries/octree/src/OctreeDataUtils.cpp b/libraries/octree/src/OctreeDataUtils.cpp
index b861904255..81e49d4cff 100644
--- a/libraries/octree/src/OctreeDataUtils.cpp
+++ b/libraries/octree/src/OctreeDataUtils.cpp
@@ -63,11 +63,11 @@ bool OctreeUtils::RawOctreeData::readOctreeDataInfoFromFile(QString path) {
 QByteArray OctreeUtils::RawOctreeData::toByteArray() {
     QByteArray jsonString;
 
-    jsonString += QString("{\n  \"DataVersion\": %1,\n").arg(dataVersion);
+    jsonString += QString("{\n  \"DataVersion\": %1,\n").arg(dataVersion).toUtf8();
 
     writeSubclassData(jsonString);
 
-    jsonString += QString(",\n  \"Id\": \"%1\",\n  \"Version\": %2\n}").arg(id.toString()).arg(version);
+    jsonString += QString(",\n  \"Id\": \"%1\",\n  \"Version\": %2\n}").arg(id.toString()).arg(version).toUtf8();
 
     return jsonString;
 }

From 598032b734b54c9b5ec67504263e3d278baf2992 Mon Sep 17 00:00:00 2001
From: Dale Glass <dale@daleglass.net>
Date: Sun, 2 Jan 2022 20:00:45 +0100
Subject: [PATCH 3/4] Review fixes

---
 libraries/networking/src/AccountManager.cpp | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp
index 730453aac6..c67d049eae 100644
--- a/libraries/networking/src/AccountManager.cpp
+++ b/libraries/networking/src/AccountManager.cpp
@@ -569,7 +569,7 @@ void AccountManager::requestAccessToken(const QString& login, const QString& pas
     postData.append("grant_type=password&");
     postData.append("username=" + QUrl::toPercentEncoding(login) + "&");
     postData.append("password=" + QUrl::toPercentEncoding(password) + "&");
-    postData.append(QString("scope=%1").arg(ACCOUNT_MANAGER_REQUESTED_SCOPE).toUtf8());
+    postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -590,9 +590,9 @@ void AccountManager::requestAccessTokenWithAuthCode(const QString& authCode, con
 
     QByteArray postData;
     postData.append("grant_type=authorization_code&");
-    postData.append(QString("client_id=%1&").arg(clientId).toUtf8());
-    postData.append(QString("client_secret=%1&").arg(clientSecret).toUtf8());
-    postData.append(QString("code=%1&").arg(authCode).toUtf8());
+    postData.append("client_id=" + clientId.toUtf8() + "&");
+    postData.append("client_secret=" + clientSecret.toUtf8() + "&");
+    postData.append("code=" + authCode.toUtf8() + "&");
     postData.append(QByteArray("redirect_uri=") + QUrl::toPercentEncoding(redirectUri));
 
     request.setUrl(grantURL);
@@ -614,7 +614,7 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) {
     QByteArray postData;
     postData.append("grant_type=password&");
     postData.append(QByteArray("steam_auth_ticket=") + QUrl::toPercentEncoding(authSessionTicket) + "&");
-    postData.append(QString("scope=%1").arg(ACCOUNT_MANAGER_REQUESTED_SCOPE).toUtf8());
+    postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -635,9 +635,9 @@ void AccountManager::requestAccessTokenWithOculus(const QString& nonce, const QS
 
     QByteArray postData;
     postData.append("grant_type=password&");
-    postData.append(QString("oculus_nonce=%1&").arg(nonce).toUtf8());
-    postData.append(QString("oculus_id=%1&").arg(oculusID).toUtf8());
-    postData.append(QString("scope=%1").arg(ACCOUNT_MANAGER_REQUESTED_SCOPE).toUtf8());
+    postData.append("oculus_nonce=" + nonce.toUtf8() + "&");
+    postData.append("oculus_id=" + oculusID.toUtf8() + "&");
+    postData.append("scope=" +  ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -667,7 +667,7 @@ void AccountManager::refreshAccessToken() {
         QByteArray postData;
         postData.append("grant_type=refresh_token&");
         postData.append(QByteArray("refresh_token=") + QUrl::toPercentEncoding(_accountInfo.getAccessToken().refreshToken) + "&");
-        postData.append(QString("scope=%1").arg(ACCOUNT_MANAGER_REQUESTED_SCOPE).toUtf8());
+        postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
 
         request.setUrl(grantURL);
         request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

From 309e2b0eaaa634ab922c6358b0e0e34d02eaac51 Mon Sep 17 00:00:00 2001
From: Dale Glass <dale@daleglass.net>
Date: Sun, 16 Jan 2022 23:05:14 +0100
Subject: [PATCH 4/4] Review fixes

---
 libraries/networking/src/AccountManager.cpp       | 8 ++++----
 libraries/networking/src/DomainAccountManager.cpp | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp
index c67d049eae..5805f5ed1a 100644
--- a/libraries/networking/src/AccountManager.cpp
+++ b/libraries/networking/src/AccountManager.cpp
@@ -593,7 +593,7 @@ void AccountManager::requestAccessTokenWithAuthCode(const QString& authCode, con
     postData.append("client_id=" + clientId.toUtf8() + "&");
     postData.append("client_secret=" + clientSecret.toUtf8() + "&");
     postData.append("code=" + authCode.toUtf8() + "&");
-    postData.append(QByteArray("redirect_uri=") + QUrl::toPercentEncoding(redirectUri));
+    postData.append("redirect_uri=" + QUrl::toPercentEncoding(redirectUri));
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -613,7 +613,7 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) {
 
     QByteArray postData;
     postData.append("grant_type=password&");
-    postData.append(QByteArray("steam_auth_ticket=") + QUrl::toPercentEncoding(authSessionTicket) + "&");
+    postData.append("steam_auth_ticket=" + QUrl::toPercentEncoding(authSessionTicket) + "&");
     postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
 
     request.setUrl(grantURL);
@@ -637,7 +637,7 @@ void AccountManager::requestAccessTokenWithOculus(const QString& nonce, const QS
     postData.append("grant_type=password&");
     postData.append("oculus_nonce=" + nonce.toUtf8() + "&");
     postData.append("oculus_id=" + oculusID.toUtf8() + "&");
-    postData.append("scope=" +  ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
+    postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
 
     request.setUrl(grantURL);
     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -666,7 +666,7 @@ void AccountManager::refreshAccessToken() {
 
         QByteArray postData;
         postData.append("grant_type=refresh_token&");
-        postData.append(QByteArray("refresh_token=") + QUrl::toPercentEncoding(_accountInfo.getAccessToken().refreshToken) + "&");
+        postData.append("refresh_token=" + QUrl::toPercentEncoding(_accountInfo.getAccessToken().refreshToken) + "&");
         postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
 
         request.setUrl(grantURL);
diff --git a/libraries/networking/src/DomainAccountManager.cpp b/libraries/networking/src/DomainAccountManager.cpp
index de3434c037..9ec5badc91 100644
--- a/libraries/networking/src/DomainAccountManager.cpp
+++ b/libraries/networking/src/DomainAccountManager.cpp
@@ -90,9 +90,9 @@ void DomainAccountManager::requestAccessToken(const QString& username, const QSt
     // - Ignores "state" parameter.
     QByteArray formData;
     formData.append("grant_type=password&");
-    formData.append(QByteArray("username=") + QUrl::toPercentEncoding(username) + "&");
-    formData.append(QByteArray("password=") + QUrl::toPercentEncoding(password) + "&");
-    formData.append(QString("client_id=%1").arg(_currentAuth.clientID).toUtf8());
+    formData.append("username=" + QUrl::toPercentEncoding(username) + "&");
+    formData.append("password=" + QUrl::toPercentEncoding(password) + "&");
+    formData.append("client_id=" + _currentAuth.clientID.toUtf8());
 
     request.setUrl(_currentAuth.authURL);