Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(845)

Side by Side Diff: chrome/browser/extensions/extension.cc

Issue 18681: Revert "Parse more user script info out of the manifest and expose" (Closed)
Patch Set: Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/extensions/extension.h ('k') | chrome/browser/extensions/extension_protocols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension.h" 5 #include "chrome/browser/extensions/extension.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "net/base/net_util.h"
10 9
11 const char Extension::kManifestFilename[] = "manifest"; 10 const char Extension::kManifestFilename[] = "manifest";
12 11
13 const wchar_t* Extension::kDescriptionKey = L"description";
14 const wchar_t* Extension::kFilesKey = L"files";
15 const wchar_t* Extension::kFormatVersionKey = L"format_version"; 12 const wchar_t* Extension::kFormatVersionKey = L"format_version";
16 const wchar_t* Extension::kIdKey = L"id"; 13 const wchar_t* Extension::kIdKey = L"id";
17 const wchar_t* Extension::kMatchesKey = L"matches";
18 const wchar_t* Extension::kNameKey = L"name"; 14 const wchar_t* Extension::kNameKey = L"name";
19 const wchar_t* Extension::kUserScriptsKey = L"user_scripts"; 15 const wchar_t* Extension::kDescriptionKey = L"description";
16 const wchar_t* Extension::kContentScriptsKey = L"content_scripts";
20 const wchar_t* Extension::kVersionKey = L"version"; 17 const wchar_t* Extension::kVersionKey = L"version";
21 18
22 // Extension-related error messages. Some of these are simple patterns, where a
23 // '*' is replaced at runtime with a specific value. This is used instead of
24 // printf because we want to unit test them and scanf is hard to make
25 // cross-platform.
26 const char* Extension::kInvalidDescriptionError =
27 "Invalid value for 'description'.";
28 const char* Extension::kInvalidFileCountError =
29 "Invalid value for 'user_scripts[*].files. Only one file is currently "
30 "supported per-user script.";
31 const char* Extension::kInvalidFileError =
32 "Invalid value for 'user_scripts[*].files[*]'.";
33 const char* Extension::kInvalidFilesError =
34 "Required value 'user_scripts[*].files is missing or invalid.";
35 const char* Extension::kInvalidFormatVersionError =
36 "Required value 'format_version' is missing or invalid.";
37 const char* Extension::kInvalidIdError =
38 "Required value 'id' is missing or invalid.";
39 const char* Extension::kInvalidManifestError = 19 const char* Extension::kInvalidManifestError =
40 "Manifest is missing or invalid."; 20 "Manifest is missing or invalid.";
41 const char* Extension::kInvalidMatchCountError = 21 const char* Extension::kInvalidFormatVersionError =
42 "Invalid value for 'user_scripts[*].matches. There must be at least one " 22 "Required key 'format_version' is missing or invalid.";
43 "match specified."; 23 const char* Extension::kInvalidIdError =
44 const char* Extension::kInvalidMatchError = 24 "Required key 'id' is missing or invalid.";
45 "Invalid value for 'user_scripts[*].matches[*]'.";
46 const char* Extension::kInvalidMatchesError =
47 "Required value 'user_scripts[*].matches' is missing or invalid.";
48 const char* Extension::kInvalidNameError = 25 const char* Extension::kInvalidNameError =
49 "Required value 'name' is missing or invalid."; 26 "Required key 'name' is missing or has invalid type.";
50 const char* Extension::kInvalidUserScriptError = 27 const char* Extension::kInvalidDescriptionError =
51 "Invalid value for 'user_scripts[*]'."; 28 "Invalid type for 'description' key.";
52 const char* Extension::kInvalidUserScriptsListError = 29 const char* Extension::kInvalidContentScriptsListError =
53 "Invalid value for 'user_scripts'."; 30 "Invalid type for 'content_scripts' key.";
31 const char* Extension::kInvalidContentScriptError =
32 "Invalid type for content_scripts at index ";
54 const char* Extension::kInvalidVersionError = 33 const char* Extension::kInvalidVersionError =
55 "Required value 'version' is missing or invalid."; 34 "Required key 'version' is missing or invalid.";
56
57 // Defined in extension_protocols.h.
58 extern const char kExtensionURLScheme[];
59
60 // static
61 GURL Extension::GetResourceURL(const GURL& extension_url,
62 const std::string& relative_path) {
63 DCHECK(extension_url.SchemeIs(kExtensionURLScheme));
64 DCHECK(extension_url.path() == "/");
65
66 GURL ret_val = GURL(extension_url.spec() + relative_path);
67 DCHECK(StartsWithASCII(ret_val.spec(), extension_url.spec(), false));
68
69 return ret_val;
70 }
71
72 // static
73 FilePath Extension::GetResourcePath(const FilePath& extension_path,
74 const std::string& relative_path) {
75 // Build up a file:// URL and convert that back to a FilePath. This avoids
76 // URL encoding and path separator issues.
77
78 // Convert the extension's root to a file:// URL.
79 GURL extension_url = net::FilePathToFileURL(extension_path);
80 if (!extension_url.is_valid())
81 return FilePath();
82
83 // Append the requested path.
84 GURL::Replacements replacements;
85 std::string new_path(extension_url.path());
86 new_path += "/";
87 new_path += relative_path;
88 replacements.SetPathStr(new_path);
89 GURL file_url = extension_url.ReplaceComponents(replacements);
90 if (!file_url.is_valid())
91 return FilePath();
92
93 // Convert the result back to a FilePath.
94 FilePath ret_val;
95 if (!net::FileURLToFilePath(file_url, &ret_val))
96 return FilePath();
97
98 // Double-check that the path we ended up with is actually inside the
99 // extension root. We can do this with a simple prefix match because:
100 // a) We control the prefix on both sides, and they should match.
101 // b) GURL normalizes things like "../" and "//" before it gets to us.
102 if (ret_val.value().find(extension_path.value() +
103 FilePath::kSeparators[0]) != 0)
104 return FilePath();
105
106 return ret_val;
107 }
108
109 // Creates an error messages from a pattern.
110 static std::string FormatErrorMessage(const std::string& format,
111 const std::string s1) {
112 std::string ret_val = format;
113 ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s1);
114 return ret_val;
115 }
116
117 static std::string FormatErrorMessage(const std::string& format,
118 const std::string s1,
119 const std::string s2) {
120 std::string ret_val = format;
121 ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s1);
122 ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s2);
123 return ret_val;
124 }
125
126 Extension::Extension(const FilePath& path) {
127 DCHECK(path.IsAbsolute());
128
129 #if defined(OS_WIN)
130 // Normalize any drive letter to upper-case. We do this for consistency with
131 // net_utils::FilePathToFileURL(), which does the same thing, to make string
132 // comparisons simpler.
133 std::wstring path_str = path.value();
134 if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' &&
135 path_str[1] == ':')
136 path_str[0] += ('A' - 'a');
137
138 path_ = FilePath(path_str);
139 #else
140 path_ = path;
141 #endif
142 }
143 35
144 bool Extension::InitFromValue(const DictionaryValue& source, 36 bool Extension::InitFromValue(const DictionaryValue& source,
145 std::string* error) { 37 std::string* error) {
146 // Check format version. 38 // Check format version.
147 int format_version = 0; 39 int format_version = 0;
148 if (!source.GetInteger(kFormatVersionKey, &format_version) || 40 if (!source.GetInteger(kFormatVersionKey, &format_version) ||
149 format_version != kExpectedFormatVersion) { 41 format_version != kExpectedFormatVersion) {
150 *error = kInvalidFormatVersionError; 42 *error = kInvalidFormatVersionError;
151 return false; 43 return false;
152 } 44 }
153 45
154 // Initialize id. 46 // Initialize id.
155 if (!source.GetString(kIdKey, &id_)) { 47 if (!source.GetString(kIdKey, &id_)) {
156 *error = kInvalidIdError; 48 *error = kInvalidIdError;
157 return false; 49 return false;
158 } 50 }
159 51
160 // Initialize URL.
161 extension_url_ = GURL(std::string(kExtensionURLScheme) + "://" + id_ + "/");
162
163 // Initialize version. 52 // Initialize version.
164 if (!source.GetString(kVersionKey, &version_)) { 53 if (!source.GetString(kVersionKey, &version_)) {
165 *error = kInvalidVersionError; 54 *error = kInvalidVersionError;
166 return false; 55 return false;
167 } 56 }
168 57
169 // Initialize name. 58 // Initialize name.
170 if (!source.GetString(kNameKey, &name_)) { 59 if (!source.GetString(kNameKey, &name_)) {
171 *error = kInvalidNameError; 60 *error = kInvalidNameError;
172 return false; 61 return false;
173 } 62 }
174 63
175 // Initialize description (optional). 64 // Initialize description (optional).
176 if (source.HasKey(kDescriptionKey)) { 65 Value* value = NULL;
177 if (!source.GetString(kDescriptionKey, &description_)) { 66 if (source.Get(kDescriptionKey, &value)) {
67 if (!value->GetAsString(&description_)) {
178 *error = kInvalidDescriptionError; 68 *error = kInvalidDescriptionError;
179 return false; 69 return false;
180 } 70 }
181 } 71 }
182 72
183 // Initialize user scripts (optional). 73 // Initialize content scripts (optional).
184 if (source.HasKey(kUserScriptsKey)) { 74 if (source.Get(kContentScriptsKey, &value)) {
185 ListValue* list_value; 75 ListValue* list_value = NULL;
186 if (!source.GetList(kUserScriptsKey, &list_value)) { 76 if (value->GetType() != Value::TYPE_LIST) {
187 *error = kInvalidUserScriptsListError; 77 *error = kInvalidContentScriptsListError;
188 return false; 78 return false;
79 } else {
80 list_value = static_cast<ListValue*>(value);
189 } 81 }
190 82
191 for (size_t i = 0; i < list_value->GetSize(); ++i) { 83 for (size_t i = 0; i < list_value->GetSize(); ++i) {
192 DictionaryValue* user_script; 84 std::string content_script;
193 if (!list_value->GetDictionary(i, &user_script)) { 85 if (!list_value->Get(i, &value) || !value->GetAsString(&content_script)) {
194 *error = FormatErrorMessage(kInvalidUserScriptError, IntToString(i)); 86 *error = kInvalidContentScriptError;
87 *error += IntToString(i);
195 return false; 88 return false;
196 } 89 }
197 90
198 ListValue* matches; 91 content_scripts_.push_back(content_script);
199 ListValue* files;
200
201 if (!user_script->GetList(kMatchesKey, &matches)) {
202 *error = FormatErrorMessage(kInvalidMatchesError, IntToString(i));
203 return false;
204 }
205
206 if (!user_script->GetList(kFilesKey, &files)) {
207 *error = FormatErrorMessage(kInvalidFilesError, IntToString(i));
208 return false;
209 }
210
211 if (matches->GetSize() == 0) {
212 *error = FormatErrorMessage(kInvalidMatchCountError, IntToString(i));
213 return false;
214 }
215
216 // NOTE: Only one file is supported right now.
217 if (files->GetSize() != 1) {
218 *error = FormatErrorMessage(kInvalidFileCountError, IntToString(i));
219 return false;
220 }
221
222 UserScriptInfo script_info;
223 for (size_t j = 0; j < matches->GetSize(); ++j) {
224 std::string match;
225 if (!matches->GetString(j, &match)) {
226 *error = FormatErrorMessage(kInvalidMatchError, IntToString(i),
227 IntToString(j));
228 return false;
229 }
230
231 script_info.matches.push_back(match);
232 }
233
234 // TODO(aa): Support multiple files.
235 std::string file;
236 if (!files->GetString(0, &file)) {
237 *error = FormatErrorMessage(kInvalidFileError, IntToString(i),
238 IntToString(0));
239 return false;
240 }
241 script_info.path = Extension::GetResourcePath(path(), file);
242 script_info.url = Extension::GetResourceURL(url(), file);
243
244 user_scripts_.push_back(script_info);
245 } 92 }
246 } 93 }
247 94
248 return true; 95 return true;
249 } 96 }
97
98 void Extension::CopyToValue(DictionaryValue* destination) {
99 // Set format version
100 destination->SetInteger(kFormatVersionKey,
101 kExpectedFormatVersion);
102
103 // Copy id.
104 destination->SetString(kIdKey, id_);
105
106 // Copy version.
107 destination->SetString(kVersionKey, version_);
108
109 // Copy name.
110 destination->SetString(kNameKey, name_);
111
112 // Copy description (optional).
113 if (description_.size() > 0)
114 destination->SetString(kDescriptionKey, description_);
115
116 // Copy content scripts (optional).
117 if (content_scripts_.size() > 0) {
118 ListValue* list_value = new ListValue();
119 destination->Set(kContentScriptsKey, list_value);
120
121 for (size_t i = 0; i < content_scripts_.size(); ++i) {
122 list_value->Set(i, Value::CreateStringValue(content_scripts_[i]));
123 }
124 }
125 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension.h ('k') | chrome/browser/extensions/extension_protocols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698