diff options
Diffstat (limited to 'chrome/browser/extensions/extension.cc')
-rw-r--r-- | chrome/browser/extensions/extension.cc | 228 |
1 files changed, 52 insertions, 176 deletions
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc index 4dfac73..e8d6513 100644 --- a/chrome/browser/extensions/extension.cc +++ b/chrome/browser/extensions/extension.cc @@ -6,140 +6,32 @@ #include "base/logging.h" #include "base/string_util.h" -#include "net/base/net_util.h" const char Extension::kManifestFilename[] = "manifest"; -const wchar_t* Extension::kDescriptionKey = L"description"; -const wchar_t* Extension::kFilesKey = L"files"; const wchar_t* Extension::kFormatVersionKey = L"format_version"; const wchar_t* Extension::kIdKey = L"id"; -const wchar_t* Extension::kMatchesKey = L"matches"; const wchar_t* Extension::kNameKey = L"name"; -const wchar_t* Extension::kUserScriptsKey = L"user_scripts"; +const wchar_t* Extension::kDescriptionKey = L"description"; +const wchar_t* Extension::kContentScriptsKey = L"content_scripts"; const wchar_t* Extension::kVersionKey = L"version"; -// Extension-related error messages. Some of these are simple patterns, where a -// '*' is replaced at runtime with a specific value. This is used instead of -// printf because we want to unit test them and scanf is hard to make -// cross-platform. -const char* Extension::kInvalidDescriptionError = - "Invalid value for 'description'."; -const char* Extension::kInvalidFileCountError = - "Invalid value for 'user_scripts[*].files. Only one file is currently " - "supported per-user script."; -const char* Extension::kInvalidFileError = - "Invalid value for 'user_scripts[*].files[*]'."; -const char* Extension::kInvalidFilesError = - "Required value 'user_scripts[*].files is missing or invalid."; -const char* Extension::kInvalidFormatVersionError = - "Required value 'format_version' is missing or invalid."; -const char* Extension::kInvalidIdError = - "Required value 'id' is missing or invalid."; const char* Extension::kInvalidManifestError = "Manifest is missing or invalid."; -const char* Extension::kInvalidMatchCountError = - "Invalid value for 'user_scripts[*].matches. There must be at least one " - "match specified."; -const char* Extension::kInvalidMatchError = - "Invalid value for 'user_scripts[*].matches[*]'."; -const char* Extension::kInvalidMatchesError = - "Required value 'user_scripts[*].matches' is missing or invalid."; +const char* Extension::kInvalidFormatVersionError = + "Required key 'format_version' is missing or invalid."; +const char* Extension::kInvalidIdError = + "Required key 'id' is missing or invalid."; const char* Extension::kInvalidNameError = - "Required value 'name' is missing or invalid."; -const char* Extension::kInvalidUserScriptError = - "Invalid value for 'user_scripts[*]'."; -const char* Extension::kInvalidUserScriptsListError = - "Invalid value for 'user_scripts'."; + "Required key 'name' is missing or has invalid type."; +const char* Extension::kInvalidDescriptionError = + "Invalid type for 'description' key."; +const char* Extension::kInvalidContentScriptsListError = + "Invalid type for 'content_scripts' key."; +const char* Extension::kInvalidContentScriptError = + "Invalid type for content_scripts at index "; const char* Extension::kInvalidVersionError = - "Required value 'version' is missing or invalid."; - -// Defined in extension_protocols.h. -extern const char kExtensionURLScheme[]; - -// static -GURL Extension::GetResourceURL(const GURL& extension_url, - const std::string& relative_path) { - DCHECK(extension_url.SchemeIs(kExtensionURLScheme)); - DCHECK(extension_url.path() == "/"); - - GURL ret_val = GURL(extension_url.spec() + relative_path); - DCHECK(StartsWithASCII(ret_val.spec(), extension_url.spec(), false)); - - return ret_val; -} - -// static -FilePath Extension::GetResourcePath(const FilePath& extension_path, - const std::string& relative_path) { - // Build up a file:// URL and convert that back to a FilePath. This avoids - // URL encoding and path separator issues. - - // Convert the extension's root to a file:// URL. - GURL extension_url = net::FilePathToFileURL(extension_path); - if (!extension_url.is_valid()) - return FilePath(); - - // Append the requested path. - GURL::Replacements replacements; - std::string new_path(extension_url.path()); - new_path += "/"; - new_path += relative_path; - replacements.SetPathStr(new_path); - GURL file_url = extension_url.ReplaceComponents(replacements); - if (!file_url.is_valid()) - return FilePath(); - - // Convert the result back to a FilePath. - FilePath ret_val; - if (!net::FileURLToFilePath(file_url, &ret_val)) - return FilePath(); - - // Double-check that the path we ended up with is actually inside the - // extension root. We can do this with a simple prefix match because: - // a) We control the prefix on both sides, and they should match. - // b) GURL normalizes things like "../" and "//" before it gets to us. - if (ret_val.value().find(extension_path.value() + - FilePath::kSeparators[0]) != 0) - return FilePath(); - - return ret_val; -} - -// Creates an error messages from a pattern. -static std::string FormatErrorMessage(const std::string& format, - const std::string s1) { - std::string ret_val = format; - ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s1); - return ret_val; -} - -static std::string FormatErrorMessage(const std::string& format, - const std::string s1, - const std::string s2) { - std::string ret_val = format; - ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s1); - ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s2); - return ret_val; -} - -Extension::Extension(const FilePath& path) { - DCHECK(path.IsAbsolute()); - -#if defined(OS_WIN) - // Normalize any drive letter to upper-case. We do this for consistency with - // net_utils::FilePathToFileURL(), which does the same thing, to make string - // comparisons simpler. - std::wstring path_str = path.value(); - if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' && - path_str[1] == ':') - path_str[0] += ('A' - 'a'); - - path_ = FilePath(path_str); -#else - path_ = path; -#endif -} + "Required key 'version' is missing or invalid."; bool Extension::InitFromValue(const DictionaryValue& source, std::string* error) { @@ -157,9 +49,6 @@ bool Extension::InitFromValue(const DictionaryValue& source, return false; } - // Initialize URL. - extension_url_ = GURL(std::string(kExtensionURLScheme) + "://" + id_ + "/"); - // Initialize version. if (!source.GetString(kVersionKey, &version_)) { *error = kInvalidVersionError; @@ -173,77 +62,64 @@ bool Extension::InitFromValue(const DictionaryValue& source, } // Initialize description (optional). - if (source.HasKey(kDescriptionKey)) { - if (!source.GetString(kDescriptionKey, &description_)) { + Value* value = NULL; + if (source.Get(kDescriptionKey, &value)) { + if (!value->GetAsString(&description_)) { *error = kInvalidDescriptionError; return false; } } - // Initialize user scripts (optional). - if (source.HasKey(kUserScriptsKey)) { - ListValue* list_value; - if (!source.GetList(kUserScriptsKey, &list_value)) { - *error = kInvalidUserScriptsListError; + // Initialize content scripts (optional). + if (source.Get(kContentScriptsKey, &value)) { + ListValue* list_value = NULL; + if (value->GetType() != Value::TYPE_LIST) { + *error = kInvalidContentScriptsListError; return false; + } else { + list_value = static_cast<ListValue*>(value); } for (size_t i = 0; i < list_value->GetSize(); ++i) { - DictionaryValue* user_script; - if (!list_value->GetDictionary(i, &user_script)) { - *error = FormatErrorMessage(kInvalidUserScriptError, IntToString(i)); + std::string content_script; + if (!list_value->Get(i, &value) || !value->GetAsString(&content_script)) { + *error = kInvalidContentScriptError; + *error += IntToString(i); return false; } - ListValue* matches; - ListValue* files; + content_scripts_.push_back(content_script); + } + } - if (!user_script->GetList(kMatchesKey, &matches)) { - *error = FormatErrorMessage(kInvalidMatchesError, IntToString(i)); - return false; - } + return true; +} - if (!user_script->GetList(kFilesKey, &files)) { - *error = FormatErrorMessage(kInvalidFilesError, IntToString(i)); - return false; - } +void Extension::CopyToValue(DictionaryValue* destination) { + // Set format version + destination->SetInteger(kFormatVersionKey, + kExpectedFormatVersion); - if (matches->GetSize() == 0) { - *error = FormatErrorMessage(kInvalidMatchCountError, IntToString(i)); - return false; - } + // Copy id. + destination->SetString(kIdKey, id_); - // NOTE: Only one file is supported right now. - if (files->GetSize() != 1) { - *error = FormatErrorMessage(kInvalidFileCountError, IntToString(i)); - return false; - } + // Copy version. + destination->SetString(kVersionKey, version_); - UserScriptInfo script_info; - for (size_t j = 0; j < matches->GetSize(); ++j) { - std::string match; - if (!matches->GetString(j, &match)) { - *error = FormatErrorMessage(kInvalidMatchError, IntToString(i), - IntToString(j)); - return false; - } + // Copy name. + destination->SetString(kNameKey, name_); - script_info.matches.push_back(match); - } + // Copy description (optional). + if (description_.size() > 0) + destination->SetString(kDescriptionKey, description_); - // TODO(aa): Support multiple files. - std::string file; - if (!files->GetString(0, &file)) { - *error = FormatErrorMessage(kInvalidFileError, IntToString(i), - IntToString(0)); - return false; - } - script_info.path = Extension::GetResourcePath(path(), file); - script_info.url = Extension::GetResourceURL(url(), file); + // Copy content scripts (optional). + if (content_scripts_.size() > 0) { + ListValue* list_value = new ListValue(); + destination->Set(kContentScriptsKey, list_value); - user_scripts_.push_back(script_info); + for (size_t i = 0; i < content_scripts_.size(); ++i) { + list_value->Set(i, Value::CreateStringValue(content_scripts_[i])); } } - - return true; } |