diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-01 22:58:24 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-01 22:58:24 +0000 |
commit | 813ed750d0b713d01e755ff2cd91279e68b135f8 (patch) | |
tree | 50911f35344a6398e3daa1870decd478bd47a9a5 /chrome/browser/importer | |
parent | dfa7be2725cd81ffd8f11a6b902159cde7db4957 (diff) | |
download | chromium_src-813ed750d0b713d01e755ff2cd91279e68b135f8.zip chromium_src-813ed750d0b713d01e755ff2cd91279e68b135f8.tar.gz chromium_src-813ed750d0b713d01e755ff2cd91279e68b135f8.tar.bz2 |
Fix a couple of firefox search engine import bugs.
1) on ubuntu, firefox3 search engines are stored in a slightly different place. See bug 53899 for more info.
2) fix parse error in ReadPrefJsValue. Firefox pref values may contain parentheses, e.g. "Wikipedia (en)"
BUG=53899
TEST=create a new firefox profile and set it as the default profile, and set firefox3 as the default browser. Launch chrome with --user-data-dir=/tmp/foo. The default set of firefox search engines should be silently imported. (Also, after I write a patch to do so, the first run ballot box should show the default ffox search engine along side the 3 defaults, if it is not one of the three defaults).
Review URL: http://codereview.chromium.org/3221007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58258 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/importer')
-rw-r--r-- | chrome/browser/importer/firefox3_importer.cc | 32 | ||||
-rw-r--r-- | chrome/browser/importer/firefox3_importer.h | 7 | ||||
-rw-r--r-- | chrome/browser/importer/firefox_importer_utils.cc | 63 | ||||
-rw-r--r-- | chrome/browser/importer/firefox_importer_utils.h | 6 | ||||
-rw-r--r-- | chrome/browser/importer/firefox_importer_utils_unittest.cc | 42 |
5 files changed, 117 insertions, 33 deletions
diff --git a/chrome/browser/importer/firefox3_importer.cc b/chrome/browser/importer/firefox3_importer.cc index 76613b6..8bbba685 100644 --- a/chrome/browser/importer/firefox3_importer.cc +++ b/chrome/browser/importer/firefox3_importer.cc @@ -12,6 +12,7 @@ #include "base/stl_util-inl.h" #include "base/string_util.h" #include "base/values.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/history/history_types.h" #include "chrome/browser/importer/firefox2_importer.h" #include "chrome/browser/importer/firefox_importer_utils.h" @@ -34,14 +35,23 @@ using importer::ProfileInfo; using importer::SEARCH_ENGINES; using webkit_glue::PasswordForm; +Firefox3Importer::Firefox3Importer() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + + locale_ = g_browser_process->GetApplicationLocale(); +} + +Firefox3Importer::~Firefox3Importer() { +} + void Firefox3Importer::StartImport(importer::ProfileInfo profile_info, uint16 items, ImporterBridge* bridge) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); bridge_ = bridge; source_path_ = profile_info.source_path; app_path_ = profile_info.app_path; - // The order here is important! bridge_->NotifyStarted(); if ((items & importer::HOME_PAGE) && !cancelled()) @@ -350,9 +360,9 @@ void Firefox3Importer::GetSearchEnginesXMLFiles( FilePath app_path = app_path_.AppendASCII("searchplugins"); FilePath profile_path = source_path_.AppendASCII("searchplugins"); - // Firefox doesn't store a search engine in its sqlite database unless - // the user has changed the default definition of engine. So we get search - // engines from sqlite db as well as from file system. + // Firefox doesn't store a search engine in its sqlite database unless the + // user has added a engine. So we get search engines from sqlite db as well + // as from the file system. if (s.step() == SQLITE_ROW) { const std::wstring kAppPrefix = L"[app]/"; const std::wstring kProfilePrefix = L"[profile]/"; @@ -381,6 +391,20 @@ void Firefox3Importer::GetSearchEnginesXMLFiles( } while (s.step() == SQLITE_ROW && !cancelled()); } +#if defined(OS_LINUX) + // Ubuntu-flavored Firefox3 supports locale-specific search engines via + // locale-named subdirectories. They fall back to en-US. + // See http://crbug.com/53899 + // TODO(jshin): we need to make sure our locale code matches that of + // Firefox. + FilePath locale_app_path = app_path.AppendASCII(locale_); + FilePath default_locale_app_path = app_path.AppendASCII("en-US"); + if (file_util::DirectoryExists(locale_app_path)) + app_path = locale_app_path; + else if (file_util::DirectoryExists(default_locale_app_path)) + app_path = default_locale_app_path; +#endif + // Get search engine definition from file system. file_util::FileEnumerator engines(app_path, false, file_util::FileEnumerator::FILES); diff --git a/chrome/browser/importer/firefox3_importer.h b/chrome/browser/importer/firefox3_importer.h index 23b6406..32a6a43 100644 --- a/chrome/browser/importer/firefox3_importer.h +++ b/chrome/browser/importer/firefox3_importer.h @@ -24,7 +24,7 @@ struct sqlite3; // http://wiki.mozilla.org/Places class Firefox3Importer : public Importer { public: - Firefox3Importer() { } + Firefox3Importer(); // Importer methods. virtual void StartImport(importer::ProfileInfo profile_info, @@ -34,7 +34,7 @@ class Firefox3Importer : public Importer { private: typedef std::map<int64, std::set<GURL> > FaviconMap; - virtual ~Firefox3Importer() { } + virtual ~Firefox3Importer(); void ImportBookmarks(); void ImportPasswords(); @@ -82,6 +82,9 @@ class Firefox3Importer : public Importer { FilePath source_path_; FilePath app_path_; + // Stored because we can only access it from the UI thread. + std::string locale_; + DISALLOW_COPY_AND_ASSIGN(Firefox3Importer); }; diff --git a/chrome/browser/importer/firefox_importer_utils.cc b/chrome/browser/importer/firefox_importer_utils.cc index 8f8aee1..0ec9109 100644 --- a/chrome/browser/importer/firefox_importer_utils.cc +++ b/chrome/browser/importer/firefox_importer_utils.cc @@ -282,30 +282,7 @@ std::string ReadPrefsJsValue(const FilePath& profile_path, if (!ReadPrefFile(profile_path.AppendASCII("prefs.js"), &content)) return ""; - // This file has the syntax: user_pref("key", value); - std::string search_for = std::string("user_pref(\"") + pref_key + - std::string("\", "); - size_t prop_index = content.find(search_for); - if (prop_index == std::string::npos) - return ""; - - size_t start = prop_index + search_for.length(); - size_t stop = std::string::npos; - if (start != std::string::npos) - stop = content.find(")", start + 1); - - if (start == std::string::npos || stop == std::string::npos) { - NOTREACHED() << "Firefox property " << pref_key << " could not be parsed."; - return ""; - } - - // String values have double quotes we don't need to return to the caller. - if (content[start] == '\"' && content[stop - 1] == '\"') { - ++start; - --stop; - } - - return content.substr(start, stop - start); + return GetPrefsJsValue(content, pref_key); } int GetFirefoxDefaultSearchEngineIndex( @@ -317,8 +294,8 @@ int GetFirefoxDefaultSearchEngineIndex( if (search_engines.empty()) return -1; - std::wstring default_se_name = UTF8ToWide( - ReadPrefsJsValue(profile_path, "browser.search.selectedEngine")); + std::string default_se_name = + ReadPrefsJsValue(profile_path, "browser.search.selectedEngine"); if (default_se_name.empty()) { // browser.search.selectedEngine does not exist if the user has not changed @@ -331,7 +308,7 @@ int GetFirefoxDefaultSearchEngineIndex( int default_se_index = -1; for (std::vector<TemplateURL*>::const_iterator iter = search_engines.begin(); iter != search_engines.end(); ++iter) { - if (default_se_name == (*iter)->short_name()) { + if (default_se_name == WideToUTF8((*iter)->short_name())) { default_se_index = static_cast<int>(iter - search_engines.begin()); break; } @@ -449,3 +426,35 @@ bool ParsePrefFile(const FilePath& pref_file, DictionaryValue* prefs) { } return true; } + +std::string GetPrefsJsValue(const std::string& content, + const std::string& pref_key) { + // This file has the syntax: user_pref("key", value); + std::string search_for = std::string("user_pref(\"") + pref_key + + std::string("\", "); + size_t prop_index = content.find(search_for); + if (prop_index == std::string::npos) + return ""; + + size_t start = prop_index + search_for.length(); + size_t stop = std::string::npos; + if (start != std::string::npos) { + // Stop at the last ')' on this line. + stop = content.find("\n", start + 1); + stop = content.rfind(")", stop); + } + + if (start == std::string::npos || stop == std::string::npos || + stop < start) { + LOG(WARNING) << "Firefox property " << pref_key << " could not be parsed."; + return ""; + } + + // String values have double quotes we don't need to return to the caller. + if (content[start] == '\"' && content[stop - 1] == '\"') { + ++start; + --stop; + } + + return content.substr(start, stop - start); +} diff --git a/chrome/browser/importer/firefox_importer_utils.h b/chrome/browser/importer/firefox_importer_utils.h index e2e2381..b5c4d6d 100644 --- a/chrome/browser/importer/firefox_importer_utils.h +++ b/chrome/browser/importer/firefox_importer_utils.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UTILS_H_ #pragma once +#include <string> #include <vector> #include "base/basictypes.h" @@ -95,4 +96,9 @@ bool IsDefaultHomepage(const GURL& homepage, const FilePath& app_path); // key/pair is not valid UTF-8, it is ignored and will not appear in |prefs|. bool ParsePrefFile(const FilePath& pref_file, DictionaryValue* prefs); +// Parses the value of a particular firefox preference from a string that is +// the contents of the prefs file. +std::string GetPrefsJsValue(const std::string& prefs, + const std::string& pref_key); + #endif // CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UTILS_H_ diff --git a/chrome/browser/importer/firefox_importer_utils_unittest.cc b/chrome/browser/importer/firefox_importer_utils_unittest.cc new file mode 100644 index 0000000..7e5fadc --- /dev/null +++ b/chrome/browser/importer/firefox_importer_utils_unittest.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "testing/gtest/include/gtest/gtest.h" + +#include "chrome/browser/importer/firefox_importer_utils.h" + +struct GetPrefsJsValueCase { + std::string prefs_content; + std::string pref_name; + std::string pref_value; +} GetPrefsJsValueCases[] = { + // Basic case. Single pref, unquoted value. + { "user_pref(\"foo.bar\", 1);", "foo.bar", "1" }, + // Value is quoted. Quotes should be stripped. + { "user_pref(\"foo.bar\", \"1\");", "foo.bar", "1" }, + // Value has parens. + { "user_pref(\"foo.bar\", \"Value (detail)\");", + "foo.bar", "Value (detail)" }, + // Multi-line case. + { "user_pref(\"foo.bar\", 1);\n" + "user_pref(\"foo.baz\", 2);\n" + "user_pref(\"foo.bag\", 3);", + "foo.baz", "2" }, + // Malformed content. + { "user_pref(\"foo.bar\", 1);\n" + "user_pref(\"foo.baz\", 2;\n" + "user_pref(\"foo.bag\", 3);", + "foo.baz", "" }, + // Malformed content. + { "uesr_pref(\"foo.bar\", 1);", "foo.bar", "" }, +}; + +TEST(FirefoxImporterUtilsTest, GetPrefsJsValue) { + for (size_t i = 0; i < arraysize(GetPrefsJsValueCases); ++i) { + EXPECT_EQ( + GetPrefsJsValueCases[i].pref_value, + GetPrefsJsValue(GetPrefsJsValueCases[i].prefs_content, + GetPrefsJsValueCases[i].pref_name)); + } +} |