| Index: chrome/browser/extensions/extension.cc
|
| diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc
|
| index 4dfac7326feb3aed0cdc1320f403f3396c23a406..e8d65136f5f91c3a8f396cb2712afd25f5f0f464 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;
|
| }
|
|
|