OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // This is a port of ManifestParser.cc from WebKit/WebCore/loader/appcache. | 5 // This is a port of ManifestParser.cc from WebKit/WebCore/loader/appcache. |
6 | 6 |
7 /* | 7 /* |
8 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 8 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
9 * | 9 * |
10 * Redistribution and use in source and binary forms, with or without | 10 * Redistribution and use in source and binary forms, with or without |
(...skipping 13 matching lines...) Expand all Loading... |
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 #include "webkit/appcache/manifest_parser.h" | 32 #include "webkit/appcache/manifest_parser.h" |
33 | 33 |
| 34 #include "base/command_line.h" |
34 #include "base/i18n/icu_string_conversions.h" | 35 #include "base/i18n/icu_string_conversions.h" |
35 #include "base/logging.h" | 36 #include "base/logging.h" |
36 #include "base/utf_string_conversions.h" | 37 #include "base/utf_string_conversions.h" |
37 #include "googleurl/src/gurl.h" | 38 #include "googleurl/src/gurl.h" |
38 | 39 |
39 namespace appcache { | 40 namespace appcache { |
40 | 41 |
41 namespace { | 42 namespace { |
42 | 43 |
43 // Helper function used to identify 'isPattern' annotations. | 44 // Helper function used to identify 'isPattern' annotations. |
44 bool HasPatternMatchingAnnotation(const wchar_t* line_p, | 45 bool HasPatternMatchingAnnotation(const wchar_t* line_p, |
45 const wchar_t* line_end) { | 46 const wchar_t* line_end) { |
46 // Skip whitespace separating the resource url from the annotation. | 47 // Skip whitespace separating the resource url from the annotation. |
47 // Note: trailing whitespace has already been trimmed from the line. | 48 // Note: trailing whitespace has already been trimmed from the line. |
48 while (line_p < line_end && (*line_p == '\t' || *line_p == ' ')) | 49 while (line_p < line_end && (*line_p == '\t' || *line_p == ' ')) |
49 ++line_p; | 50 ++line_p; |
50 if (line_p == line_end) | 51 if (line_p == line_end) |
51 return false; | 52 return false; |
52 std::wstring annotation(line_p, line_end - line_p); | 53 std::wstring annotation(line_p, line_end - line_p); |
53 return annotation == L"isPattern"; | 54 return annotation == L"isPattern"; |
54 } | 55 } |
55 | 56 |
56 } | 57 } |
57 | 58 |
58 enum Mode { | 59 enum Mode { |
59 EXPLICIT, | 60 EXPLICIT, |
60 INTERCEPT, | 61 INTERCEPT, |
61 FALLBACK, | 62 FALLBACK, |
62 ONLINE_WHITELIST, | 63 ONLINE_WHITELIST, |
63 UNKNOWN, | 64 UNKNOWN_MODE, |
| 65 }; |
| 66 |
| 67 enum InterceptVerb { |
| 68 RETURN, |
| 69 EXECUTE, |
| 70 UNKNOWN_VERB, |
64 }; | 71 }; |
65 | 72 |
66 Manifest::Manifest() : online_whitelist_all(false) {} | 73 Manifest::Manifest() : online_whitelist_all(false) {} |
67 | 74 |
68 Manifest::~Manifest() {} | 75 Manifest::~Manifest() {} |
69 | 76 |
70 bool ParseManifest(const GURL& manifest_url, const char* data, int length, | 77 bool ParseManifest(const GURL& manifest_url, const char* data, int length, |
71 Manifest& manifest) { | 78 Manifest& manifest) { |
72 // This is an implementation of the parsing algorithm specified in | 79 // This is an implementation of the parsing algorithm specified in |
73 // the HTML5 offline web application docs: | 80 // the HTML5 offline web application docs: |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 | 165 |
159 if (line == L"CACHE:") { | 166 if (line == L"CACHE:") { |
160 mode = EXPLICIT; | 167 mode = EXPLICIT; |
161 } else if (line == L"FALLBACK:") { | 168 } else if (line == L"FALLBACK:") { |
162 mode = FALLBACK; | 169 mode = FALLBACK; |
163 } else if (line == L"NETWORK:") { | 170 } else if (line == L"NETWORK:") { |
164 mode = ONLINE_WHITELIST; | 171 mode = ONLINE_WHITELIST; |
165 } else if (line == L"CHROMIUM-INTERCEPT:") { | 172 } else if (line == L"CHROMIUM-INTERCEPT:") { |
166 mode = INTERCEPT; | 173 mode = INTERCEPT; |
167 } else if (*(line.end() - 1) == ':') { | 174 } else if (*(line.end() - 1) == ':') { |
168 mode = UNKNOWN; | 175 mode = UNKNOWN_MODE; |
169 } else if (mode == UNKNOWN) { | 176 } else if (mode == UNKNOWN_MODE) { |
170 continue; | 177 continue; |
171 } else if (line == L"*" && mode == ONLINE_WHITELIST) { | 178 } else if (line == L"*" && mode == ONLINE_WHITELIST) { |
172 manifest.online_whitelist_all = true; | 179 manifest.online_whitelist_all = true; |
173 continue; | 180 continue; |
174 } else if (mode == EXPLICIT || mode == ONLINE_WHITELIST) { | 181 } else if (mode == EXPLICIT || mode == ONLINE_WHITELIST) { |
175 const wchar_t *line_p = line.c_str(); | 182 const wchar_t *line_p = line.c_str(); |
176 const wchar_t *line_end = line_p + line.length(); | 183 const wchar_t *line_end = line_p + line.length(); |
177 | 184 |
178 // Look for whitespace separating the URL from subsequent ignored tokens. | 185 // Look for whitespace separating the URL from subsequent ignored tokens. |
179 while (line_p < line_end && *line_p != '\t' && *line_p != ' ') | 186 while (line_p < line_end && *line_p != '\t' && *line_p != ' ') |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 // Skip whitespace separating namespace from the type. | 250 // Skip whitespace separating namespace from the type. |
244 while (line_p < line_end && (*line_p == '\t' || *line_p == ' ')) | 251 while (line_p < line_end && (*line_p == '\t' || *line_p == ' ')) |
245 ++line_p; | 252 ++line_p; |
246 | 253 |
247 // Look for whitespace separating the type from the target url. | 254 // Look for whitespace separating the type from the target url. |
248 const wchar_t* type_start = line_p; | 255 const wchar_t* type_start = line_p; |
249 while (line_p < line_end && *line_p != '\t' && *line_p != ' ') | 256 while (line_p < line_end && *line_p != '\t' && *line_p != ' ') |
250 ++line_p; | 257 ++line_p; |
251 | 258 |
252 // Look for a type value we understand, otherwise skip the line. | 259 // Look for a type value we understand, otherwise skip the line. |
| 260 InterceptVerb verb = UNKNOWN_VERB; |
253 std::wstring type(type_start, line_p - type_start); | 261 std::wstring type(type_start, line_p - type_start); |
254 if (type != L"return") | 262 if (type == L"return") { |
| 263 verb = RETURN; |
| 264 } else if (type == L"execute" && |
| 265 CommandLine::ForCurrentProcess()->HasSwitch( |
| 266 kEnableExecutableHandlers)) { |
| 267 verb = EXECUTE; |
| 268 } |
| 269 if (verb == UNKNOWN_VERB) |
255 continue; | 270 continue; |
256 | 271 |
257 // Skip whitespace separating type from the target_url. | 272 // Skip whitespace separating type from the target_url. |
258 while (line_p < line_end && (*line_p == '\t' || *line_p == ' ')) | 273 while (line_p < line_end && (*line_p == '\t' || *line_p == ' ')) |
259 ++line_p; | 274 ++line_p; |
260 | 275 |
261 // Look for whitespace separating the URL from subsequent ignored tokens. | 276 // Look for whitespace separating the URL from subsequent ignored tokens. |
262 const wchar_t* target_url_start = line_p; | 277 const wchar_t* target_url_start = line_p; |
263 while (line_p < line_end && *line_p != '\t' && *line_p != ' ') | 278 while (line_p < line_end && *line_p != '\t' && *line_p != ' ') |
264 ++line_p; | 279 ++line_p; |
265 | 280 |
266 base::string16 target_url16; | 281 base::string16 target_url16; |
267 WideToUTF16(target_url_start, line_p - target_url_start, &target_url16); | 282 WideToUTF16(target_url_start, line_p - target_url_start, &target_url16); |
268 GURL target_url = manifest_url.Resolve(target_url16); | 283 GURL target_url = manifest_url.Resolve(target_url16); |
269 if (!target_url.is_valid()) | 284 if (!target_url.is_valid()) |
270 continue; | 285 continue; |
271 | 286 |
272 if (target_url.has_ref()) { | 287 if (target_url.has_ref()) { |
273 GURL::Replacements replacements; | 288 GURL::Replacements replacements; |
274 replacements.ClearRef(); | 289 replacements.ClearRef(); |
275 target_url = target_url.ReplaceComponents(replacements); | 290 target_url = target_url.ReplaceComponents(replacements); |
276 } | 291 } |
277 if (manifest_url.GetOrigin() != target_url.GetOrigin()) | 292 if (manifest_url.GetOrigin() != target_url.GetOrigin()) |
278 continue; | 293 continue; |
279 | 294 |
280 bool is_pattern = HasPatternMatchingAnnotation(line_p, line_end); | 295 bool is_pattern = HasPatternMatchingAnnotation(line_p, line_end); |
281 manifest.intercept_namespaces.push_back( | 296 manifest.intercept_namespaces.push_back( |
282 Namespace(INTERCEPT_NAMESPACE, namespace_url, | 297 Namespace(INTERCEPT_NAMESPACE, namespace_url, |
283 target_url, is_pattern)); | 298 target_url, is_pattern, verb == EXECUTE)); |
284 } else if (mode == FALLBACK) { | 299 } else if (mode == FALLBACK) { |
285 const wchar_t* line_p = line.c_str(); | 300 const wchar_t* line_p = line.c_str(); |
286 const wchar_t* line_end = line_p + line.length(); | 301 const wchar_t* line_end = line_p + line.length(); |
287 | 302 |
288 // Look for whitespace separating the two URLs | 303 // Look for whitespace separating the two URLs |
289 while (line_p < line_end && *line_p != '\t' && *line_p != ' ') | 304 while (line_p < line_end && *line_p != '\t' && *line_p != ' ') |
290 ++line_p; | 305 ++line_p; |
291 | 306 |
292 if (line_p == line_end) { | 307 if (line_p == line_end) { |
293 // There was no whitespace separating the URLs. | 308 // There was no whitespace separating the URLs. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 fallback_url, is_pattern)); | 361 fallback_url, is_pattern)); |
347 } else { | 362 } else { |
348 NOTREACHED(); | 363 NOTREACHED(); |
349 } | 364 } |
350 } | 365 } |
351 | 366 |
352 return true; | 367 return true; |
353 } | 368 } |
354 | 369 |
355 } // namespace appcache | 370 } // namespace appcache |
OLD | NEW |