From fcc23e84efb0aa42e00f79d5fa1798b5604d7a28 Mon Sep 17 00:00:00 2001
From: "estade@chromium.org"
 <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Thu, 1 Oct 2009 03:19:10 +0000
Subject: GTK: improve app mode .desktop file creation.

1) pass --user-data-dir when appropriate
2) don't overwrite old .desktop files that share the same name.

BUG=23353

Review URL: http://codereview.chromium.org/255016

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27700 0039d316-1c4b-4281-b951-d872f2087c98
---
 chrome/browser/shell_integration_linux.cc    | 42 ++++++++++++++++++----------
 chrome/browser/shell_integration_unittest.cc | 14 +++++-----
 2 files changed, 34 insertions(+), 22 deletions(-)

(limited to 'chrome/browser')

diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc
index 30eab5b..11f976e 100644
--- a/chrome/browser/shell_integration_linux.cc
+++ b/chrome/browser/shell_integration_linux.cc
@@ -29,6 +29,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_plugin_util.h"
 #include "chrome/common/chrome_switches.h"
 #include "googleurl/src/gurl.h"
 
@@ -121,6 +122,8 @@ class CreateDesktopShortcutTask : public Task {
 
     FilePath shortcut_filename =
         ShellIntegration::GetDesktopShortcutFilename(shortcut_info_.url);
+    if (shortcut_filename.empty())
+      return;
 
     std::string icon_name = CreateIcon(shortcut_filename);
 
@@ -293,13 +296,28 @@ bool ShellIntegration::IsFirefoxDefaultBrowser() {
 
 FilePath ShellIntegration::GetDesktopShortcutFilename(const GURL& url) {
   // Use a prefix, because xdg-desktop-menu requires it.
-  std::wstring filename = std::wstring(chrome::kBrowserProcessExecutableName) +
-      L"-" + UTF8ToWide(url.spec()) + L".desktop";
-  file_util::ReplaceIllegalCharacters(&filename, '_');
+  std::wstring filename_wide =
+      std::wstring(chrome::kBrowserProcessExecutableName) + L"-" +
+      UTF8ToWide(url.spec());
+  file_util::ReplaceIllegalCharacters(&filename_wide, '_');
+
+  FilePath desktop_path;
+  if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
+    return FilePath();
+
+  FilePath filepath = desktop_path.Append(
+      FilePath::FromWStringHack(filename_wide));
+  FilePath alternative_filepath(filepath.value() + ".desktop");
+  for (size_t i = 1; i < 100; ++i) {
+    if (file_util::PathExists(FilePath(alternative_filepath))) {
+      alternative_filepath = FilePath(filepath.value() + "_" + IntToString(i) +
+                                      ".desktop");
+    } else {
+      return FilePath(alternative_filepath).BaseName();
+    }
+  }
 
-  // Return BaseName to be absolutely sure we're not vulnerable to a directory
-  // traversal attack.
-  return FilePath::FromWStringHack(filename).BaseName();
+  return FilePath();
 }
 
 std::string ShellIntegration::GetDesktopFileContents(
@@ -319,15 +337,9 @@ std::string ShellIntegration::GetDesktopFileContents(
         if (exec_tokenizer.token() != "%U")
           final_path += exec_tokenizer.token() + " ";
       }
-      std::wstring app_switch_wide(switches::kApp);
-      std::string app_switch(StringPrintf("\"--%s=%s\"",
-                                          WideToUTF8(app_switch_wide).c_str(),
-                                          url.spec().c_str()));
-      // Sanitize the command line string.
-      ReplaceSubstringsAfterOffset(&app_switch, 0, "%", "%%");
-      ReplaceSubstringsAfterOffset(&app_switch, 0, ";", "");
-      ReplaceSubstringsAfterOffset(&app_switch, 0, "$", "");
-      output_buffer += std::string("Exec=") + final_path + app_switch + "\n";
+      std::string switches;
+      CPB_GetCommandLineArgumentsCommon(url.spec().c_str(), &switches);
+      output_buffer += std::string("Exec=") + final_path + switches + "\n";
     } else if (tokenizer.token().substr(0, 5) == "Name=") {
       std::string final_title = UTF16ToUTF8(title);
       // Make sure no endline characters can slip in and possibly introduce
diff --git a/chrome/browser/shell_integration_unittest.cc b/chrome/browser/shell_integration_unittest.cc
index 4f8ddef..6352d5a 100644
--- a/chrome/browser/shell_integration_unittest.cc
+++ b/chrome/browser/shell_integration_unittest.cc
@@ -69,7 +69,7 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
       "Version=1.0\n"
       "Encoding=UTF-8\n"
       "Name=GMail\n"
-      "Exec=/opt/google/chrome/google-chrome \"--app=http://gmail.com/\"\n"
+      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
       "Terminal=false\n"
       "Icon=chrome-http__gmail.com\n"
       "Type=Application\n"
@@ -88,7 +88,7 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
 
       "#!/usr/bin/env xdg-open\n"
       "Name=GMail\n"
-      "Exec=/opt/google/chrome/google-chrome \"--app=http://gmail.com/\"\n"
+      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
     },
 
     // Make sure i18n-ed comments are removed.
@@ -102,7 +102,7 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
 
       "#!/usr/bin/env xdg-open\n"
       "Name=GMail\n"
-      "Exec=/opt/google/chrome/google-chrome \"--app=http://gmail.com/\"\n"
+      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
     },
 
     // Make sure that empty icons are replaced by the chrome icon.
@@ -117,7 +117,7 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
 
       "#!/usr/bin/env xdg-open\n"
       "Name=GMail\n"
-      "Exec=/opt/google/chrome/google-chrome \"--app=http://gmail.com/\"\n"
+      "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
       "Icon=/opt/google/chrome/product_logo_48.png\n"
     },
 
@@ -132,7 +132,7 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
       "#!/usr/bin/env xdg-open\n"
       "Name=http://evil.com/evil%20--join-the-b0tnet\n"
       "Exec=/opt/google/chrome/google-chrome "
-      "\"--app=http://evil.com/evil%%20--join-the-b0tnet\"\n"
+      "--app=\"http://evil.com/evil%%20--join-the-b0tnet\"\n"
     },
     { "http://evil.com/evil; rm -rf /; \"; rm -rf $HOME >ownz0red",
       "Innocent Title",
@@ -144,7 +144,7 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
       "#!/usr/bin/env xdg-open\n"
       "Name=Innocent Title\n"
       "Exec=/opt/google/chrome/google-chrome "
-      "\"--app=http://evil.com/evil%%20rm%%20-rf%%20/%%20%%22%%20rm%%20"
+      "--app=\"http://evil.com/evil%%20rm%%20-rf%%20/%%20%%22%%20rm%%20"
       "-rf%%20HOME%%20%%3Eownz0red\"\n"
     },
     { "http://evil.com/evil | cat `echo ownz0red` >/dev/null\\",
@@ -157,7 +157,7 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
       "#!/usr/bin/env xdg-open\n"
       "Name=Innocent Title\n"
       "Exec=/opt/google/chrome/google-chrome "
-      "\"--app=http://evil.com/evil%%20%%7C%%20cat%%20%%60echo%%20ownz0red"
+      "--app=\"http://evil.com/evil%%20%%7C%%20cat%%20%%60echo%%20ownz0red"
       "%%60%%20%%3E/dev/null/\"\n"
     },
   };
-- 
cgit v1.1