Browse Source

fix: don't propagate GDK_BACKEND to subprocs (#28898)

Shelley Vohr 3 years ago
parent
commit
7b169c2884

+ 17 - 0
shell/browser/electron_browser_main_parts.cc

@@ -155,6 +155,7 @@ std::u16string MediaStringProvider(media::MessageId id) {
 }
 
 #if defined(OS_LINUX)
+
 void OverrideLinuxAppDataPath() {
   base::FilePath path;
   if (base::PathService::Get(DIR_APP_DATA, &path))
@@ -375,8 +376,24 @@ void ElectronBrowserMainParts::PostDestroyThreads() {
   fake_browser_process_->PostDestroyThreads();
 }
 
+#if defined(OS_LINUX)
+// static
+base::Optional<std::string>& ElectronBrowserMainParts::GetGDKBackend() {
+  static base::Optional<std::string> gdk_backend;
+  return gdk_backend;
+}
+#endif
+
 void ElectronBrowserMainParts::ToolkitInitialized() {
 #if defined(OS_LINUX)
+  // This is set by Chromium here:
+  // https://chromium-review.googlesource.com/c/chromium/src/+/2586184
+  // and can detrimentally affect external app behaviors, so we want to
+  // check if the user has set it so we can use it later.
+  std::string backend;
+  if (base::Environment::Create()->GetVar("GDK_BACKEND", &backend))
+    GetGDKBackend().reset(backend);
+
   auto linux_ui = BuildGtkUi();
   linux_ui->Initialize();
 

+ 5 - 0
shell/browser/electron_browser_main_parts.h

@@ -88,6 +88,11 @@ class ElectronBrowserMainParts : public content::BrowserMainParts {
   Browser* browser() { return browser_.get(); }
   BrowserProcessImpl* browser_process() { return fake_browser_process_.get(); }
 
+#if defined(OS_LINUX)
+  // Used by platform_util to set GDK_BACKEND.
+  static base::Optional<std::string>& GetGDKBackend();
+#endif
+
  protected:
   // content::BrowserMainParts:
   int PreEarlyInitialization() override;

+ 13 - 0
shell/common/platform_util_linux.cc

@@ -19,6 +19,7 @@
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_proxy.h"
+#include "shell/browser/electron_browser_main_parts.h"
 #include "shell/common/platform_util_internal.h"
 #include "ui/gtk/gtk_util.h"
 #include "url/gurl.h"
@@ -122,6 +123,18 @@ bool XDGUtil(const std::vector<std::string>& argv,
   // bring up a new terminal if necessary.  See "man mailcap".
   options.environment["MM_NOTTTY"] = "1";
 
+  // If the user set a GDK_BACKEND value of their own, use that,
+  // otherwise unset it becuase Chromium is setting GDK_BACKEND
+  // during GTK initialization and we want to respect user preference.
+  // Setting values in EnvironmentMap to an empty-string
+  // will make sure that they get unset from the environment via
+  // AlterEnvironment().
+  const base::Optional<std::string>& gdk_backend =
+      electron::ElectronBrowserMainParts::GetGDKBackend();
+  options.environment["GDK_BACKEND"] = gdk_backend.has_value()
+                                           ? gdk_backend.value().c_str()
+                                           : base::NativeEnvironmentString();
+
   base::Process process = base::LaunchProcess(argv, options);
   if (!process.IsValid())
     return false;

+ 7 - 0
spec-main/chromium-spec.ts

@@ -367,6 +367,13 @@ describe('web security', () => {
   });
 });
 
+ifdescribe(process.platform === 'linux')('subprocesses', () => {
+  it('does not propagate GDK_BACKEND', () => {
+    const backend = process.env.GDK_BACKEND;
+    expect(backend).to.eq(null);
+  });
+});
+
 describe('command line switches', () => {
   let appProcess: ChildProcess.ChildProcessWithoutNullStreams | undefined;
   afterEach(() => {