| 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 |