This source file includes following definitions.
- GetProfilePath
- IsDefaultProfile
- GetFirefoxProfilePath
- GetFirefoxProfilePathFromDictionary
- ComposeMacAppPath
- GetFirefoxVersionAndPathFromProfile
- ReadPrefFile
- ReadBrowserConfigProp
- ReadPrefsJsValue
- GetHomepage
- IsDefaultHomepage
- GetPrefsJsValue
- GetFirefoxImporterName
#include "chrome/common/importer/firefox_importer_utils.h"
#include <algorithm>
#include <map>
#include <string>
#include "base/file_util.h"
#include "base/ini_parser.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
namespace {
base::FilePath GetProfilePath(const base::DictionaryValue& root,
const std::string& profile_name) {
base::string16 path16;
std::string is_relative;
if (!root.GetStringASCII(profile_name + ".IsRelative", &is_relative) ||
!root.GetString(profile_name + ".Path", &path16))
return base::FilePath();
#if defined(OS_WIN)
ReplaceSubstringsAfterOffset(
&path16, 0, base::ASCIIToUTF16("/"), base::ASCIIToUTF16("\\"));
#endif
base::FilePath path = base::FilePath::FromUTF16Unsafe(path16);
if (is_relative == "1")
path = GetProfilesINI().DirName().Append(path);
return path;
}
bool IsDefaultProfile(const base::DictionaryValue& root,
const std::string& profile_name) {
std::string is_default;
root.GetStringASCII(profile_name + ".Default", &is_default);
return is_default == "1";
}
}
base::FilePath GetFirefoxProfilePath() {
base::FilePath ini_file = GetProfilesINI();
std::string content;
base::ReadFileToString(ini_file, &content);
base::DictionaryValueINIParser ini_parser;
ini_parser.Parse(content);
return GetFirefoxProfilePathFromDictionary(ini_parser.root());
}
base::FilePath GetFirefoxProfilePathFromDictionary(
const base::DictionaryValue& root) {
std::vector<std::string> profiles;
for (int i = 0; ; ++i) {
std::string current_profile = base::StringPrintf("Profile%d", i);
if (root.HasKey(current_profile)) {
profiles.push_back(current_profile);
} else {
break;
}
}
if (profiles.empty())
return base::FilePath();
for (std::vector<std::string>::const_iterator it = profiles.begin();
it != profiles.end(); ++it)
if (IsDefaultProfile(root, *it))
return GetProfilePath(root, *it);
return GetProfilePath(root, profiles.front());
}
#if defined(OS_MACOSX)
bool ComposeMacAppPath(const std::string& path_from_file,
base::FilePath* output) {
base::FilePath path(path_from_file);
typedef std::vector<base::FilePath::StringType> ComponentVector;
ComponentVector path_components;
path.GetComponents(&path_components);
if (path_components.empty())
return false;
*output = base::FilePath(path_components[0]);
for (size_t i = 1; i < path_components.size(); ++i) {
*output = output->Append(path_components[i]);
if (EndsWith(path_components[i], ".app", true)) {
*output = output->Append("Contents");
*output = output->Append("MacOS");
return true;
}
}
LOG(ERROR) << path_from_file << " doesn't look like a valid Firefox "
<< "installation path: missing /*.app/ directory.";
return false;
}
#endif
bool GetFirefoxVersionAndPathFromProfile(const base::FilePath& profile_path,
int* version,
base::FilePath* app_path) {
bool ret = false;
base::FilePath compatibility_file =
profile_path.AppendASCII("compatibility.ini");
std::string content;
base::ReadFileToString(compatibility_file, &content);
ReplaceSubstringsAfterOffset(&content, 0, "\r\n", "\n");
std::vector<std::string> lines;
base::SplitString(content, '\n', &lines);
for (size_t i = 0; i < lines.size(); ++i) {
const std::string& line = lines[i];
if (line.empty() || line[0] == '#' || line[0] == ';')
continue;
size_t equal = line.find('=');
if (equal != std::string::npos) {
std::string key = line.substr(0, equal);
if (key == "LastVersion") {
base::StringToInt(line.substr(equal + 1), version);
ret = true;
} else if (key == "LastAppDir") {
#if defined(OS_MACOSX)
size_t separator_pos = line.find_first_of('=');
const std::string& path_from_ini = line.substr(separator_pos + 1);
if (!ComposeMacAppPath(path_from_ini, app_path))
return false;
#else
*app_path = base::FilePath::FromUTF8Unsafe(line.substr(equal + 1));
#endif
}
}
}
return ret;
}
bool ReadPrefFile(const base::FilePath& path, std::string* content) {
if (content == NULL)
return false;
base::ReadFileToString(path, content);
if (content->empty()) {
LOG(WARNING) << "Firefox preference file " << path.value() << " is empty.";
return false;
}
return true;
}
std::string ReadBrowserConfigProp(const base::FilePath& app_path,
const std::string& pref_key) {
std::string content;
if (!ReadPrefFile(app_path.AppendASCII("browserconfig.properties"), &content))
return std::string();
size_t prop_index = content.find(pref_key + "=");
if (prop_index == std::string::npos)
return std::string();
size_t start = prop_index + pref_key.length();
size_t stop = std::string::npos;
if (start != std::string::npos)
stop = content.find("\n", start + 1);
if (start == std::string::npos ||
stop == std::string::npos || (start == stop)) {
LOG(WARNING) << "Firefox property " << pref_key << " could not be parsed.";
return std::string();
}
return content.substr(start + 1, stop - start - 1);
}
std::string ReadPrefsJsValue(const base::FilePath& profile_path,
const std::string& pref_key) {
std::string content;
if (!ReadPrefFile(profile_path.AppendASCII("prefs.js"), &content))
return std::string();
return GetPrefsJsValue(content, pref_key);
}
GURL GetHomepage(const base::FilePath& profile_path) {
std::string home_page_list =
ReadPrefsJsValue(profile_path, "browser.startup.homepage");
size_t seperator = home_page_list.find_first_of('|');
if (seperator == std::string::npos)
return GURL(home_page_list);
return GURL(home_page_list.substr(0, seperator));
}
bool IsDefaultHomepage(const GURL& homepage, const base::FilePath& app_path) {
if (!homepage.is_valid())
return false;
std::string default_homepages =
ReadBrowserConfigProp(app_path, "browser.startup.homepage");
size_t seperator = default_homepages.find_first_of('|');
if (seperator == std::string::npos)
return homepage.spec() == GURL(default_homepages).spec();
std::vector<std::string> urls;
base::SplitString(default_homepages, '|', &urls);
for (size_t i = 0; i < urls.size(); ++i) {
if (homepage.spec() == GURL(urls[i]).spec())
return true;
}
return false;
}
std::string GetPrefsJsValue(const std::string& content,
const std::string& pref_key) {
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 std::string();
size_t start = prop_index + search_for.length();
size_t stop = std::string::npos;
if (start != std::string::npos) {
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 std::string();
}
if (content[start] == '\"' && content[stop - 1] == '\"') {
++start;
--stop;
}
return content.substr(start, stop - start);
}
base::string16 GetFirefoxImporterName(const base::FilePath& app_path) {
const base::FilePath app_ini_file = app_path.AppendASCII("application.ini");
std::string branding_name;
if (base::PathExists(app_ini_file)) {
std::string content;
base::ReadFileToString(app_ini_file, &content);
std::vector<std::string> lines;
base::SplitString(content, '\n', &lines);
const std::string name_attr("Name=");
bool in_app_section = false;
for (size_t i = 0; i < lines.size(); ++i) {
base::TrimWhitespace(lines[i], base::TRIM_ALL, &lines[i]);
if (lines[i] == "[App]") {
in_app_section = true;
} else if (in_app_section) {
if (lines[i].find(name_attr) == 0) {
branding_name = lines[i].substr(name_attr.size());
break;
} else if (lines[i].length() > 0 && lines[i][0] == '[') {
break;
}
}
}
}
StringToLowerASCII(&branding_name);
if (branding_name.find("iceweasel") != std::string::npos)
return l10n_util::GetStringUTF16(IDS_IMPORT_FROM_ICEWEASEL);
return l10n_util::GetStringUTF16(IDS_IMPORT_FROM_FIREFOX);
}