From 488b8e8ed01018c155812e5cfb06162a5e216c7a Mon Sep 17 00:00:00 2001
From: Kai Koehne <kai.koehne@qt.io>
Date: Mon, 19 Feb 2018 15:57:36 +0100
Subject: [PATCH] Separate argv for QCoreApplication and Chromium in
 WebEngineProcess

On Linux, Chromium manipulates argv, merging all command line
arguments into argv[0] and deleting the other arguments - see
set_process_title_linux.cc for the glory details. This potentially
confuses QCoreApplication::applicationDirPath(), which assumes
that argv[0] contains the binary path. This in turn caused a
regression in Qt 5.9.4 where resource files could not be located
anymore for QtWebEngineProcess.

Avoid this by making two distinct copies of argv already in main().

Task-number: QTBUG-66346
Change-Id: I24d103bb15e77db69faae3bcfc736df25e4ec5d3
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 src/process/main.cpp | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/process/main.cpp b/src/process/main.cpp
index d2f9d2337..3b4ce9837 100644
--- a/src/process/main.cpp
+++ b/src/process/main.cpp
@@ -41,6 +41,7 @@
 
 #include <QCoreApplication>
 #include <stdio.h>
+#include <memory>
 
 #if defined(Q_OS_LINUX)
 
@@ -97,9 +98,30 @@ int main(int argc, const char **argv)
     initDpiAwareness();
 #endif
 
-    // QCoreApplication needs a non-const pointer, while the
-    // ContentMain in Chromium needs the pointer to be const.
-    QCoreApplication qtApplication(argc, const_cast<char**>(argv));
+    // Chromium on Linux manipulates argv to set a process title
+    // (see set_process_title_linux.cc).
+    // This can interfere with QCoreApplication::applicationFilePath,
+    // which assumes that argv[0] only contains the executable path.
+    //
+    // Avoid this by making a deep copy of argv and pass this
+    // to QCoreApplication. Use a unique_ptr with custom deleter to
+    // clean up on exit.
+
+    auto dt = [](char* av[]) {
+        for (char **a = av; *a; a++)
+          delete[] *a;
+        delete[] av;
+    };
+
+    std::unique_ptr<char*[], decltype(dt)> argv_(new char*[argc+1], dt);
+    for (int i = 0; i < argc; ++i) {
+        size_t len = strlen(argv[i]) + 1;
+        argv_[i] = new char[len];
+        strcpy(argv_[i], argv[i]);
+    }
+    argv_[argc] = 0;
+
+    QCoreApplication qtApplication(argc, argv_.get());
 
     return QtWebEngine::processMain(argc, argv);
 }
-- 
GitLab