| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "components/url_fixer/url_fixer.h" | 5 #include "components/url_formatter/url_fixer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #if defined(OS_POSIX) | 12 #if defined(OS_POSIX) |
| 13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
| 14 #endif | 14 #endif |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 17 #include "components/url_formatter/url_formatter.h" |
| 17 #include "net/base/escape.h" | 18 #include "net/base/escape.h" |
| 18 #include "net/base/filename_util.h" | 19 #include "net/base/filename_util.h" |
| 19 #include "net/base/net_util.h" | |
| 20 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 20 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 21 #include "url/third_party/mozilla/url_parse.h" | 21 #include "url/third_party/mozilla/url_parse.h" |
| 22 #include "url/url_file.h" | 22 #include "url/url_file.h" |
| 23 #include "url/url_util.h" | 23 #include "url/url_util.h" |
| 24 | 24 |
| 25 const char* url_fixer::home_directory_override = NULL; | 25 namespace url_formatter { |
| 26 |
| 27 const char* home_directory_override = nullptr; |
| 26 | 28 |
| 27 namespace { | 29 namespace { |
| 28 | 30 |
| 29 // Hardcode these constants to avoid dependences on //chrome and //content. | 31 // Hardcode these constants to avoid dependences on //chrome and //content. |
| 30 const char kChromeUIScheme[] = "chrome"; | 32 const char kChromeUIScheme[] = "chrome"; |
| 31 const char kChromeUIDefaultHost[] = "version"; | 33 const char kChromeUIDefaultHost[] = "version"; |
| 32 const char kViewSourceScheme[] = "view-source"; | 34 const char kViewSourceScheme[] = "view-source"; |
| 33 | 35 |
| 34 // TODO(estade): Remove these ugly, ugly functions. They are only used in | 36 // TODO(estade): Remove these ugly, ugly functions. They are only used in |
| 35 // SegmentURL. A url::Parsed object keeps track of a bunch of indices into | 37 // SegmentURL. A url::Parsed object keeps track of a bunch of indices into |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 119 } |
| 118 | 120 |
| 119 #if defined(OS_POSIX) | 121 #if defined(OS_POSIX) |
| 120 // Given a path that starts with ~, return a path that starts with an | 122 // Given a path that starts with ~, return a path that starts with an |
| 121 // expanded-out /user/foobar directory. | 123 // expanded-out /user/foobar directory. |
| 122 std::string FixupHomedir(const std::string& text) { | 124 std::string FixupHomedir(const std::string& text) { |
| 123 DCHECK(text.length() > 0 && text[0] == '~'); | 125 DCHECK(text.length() > 0 && text[0] == '~'); |
| 124 | 126 |
| 125 if (text.length() == 1 || text[1] == '/') { | 127 if (text.length() == 1 || text[1] == '/') { |
| 126 base::FilePath file_path; | 128 base::FilePath file_path; |
| 127 if (url_fixer::home_directory_override) | 129 if (home_directory_override) |
| 128 file_path = base::FilePath(url_fixer::home_directory_override); | 130 file_path = base::FilePath(home_directory_override); |
| 129 else | 131 else |
| 130 PathService::Get(base::DIR_HOME, &file_path); | 132 PathService::Get(base::DIR_HOME, &file_path); |
| 131 | 133 |
| 132 // We'll probably break elsewhere if $HOME is undefined, but check here | 134 // We'll probably break elsewhere if $HOME is undefined, but check here |
| 133 // just in case. | 135 // just in case. |
| 134 if (file_path.value().empty()) | 136 if (file_path.value().empty()) |
| 135 return text; | 137 return text; |
| 136 // Append requires to be a relative path, so we have to cut all preceeding | 138 // Append requires to be a relative path, so we have to cut all preceeding |
| 137 // '/' characters. | 139 // '/' characters. |
| 138 size_t i = 1; | 140 size_t i = 1; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 #elif defined(OS_POSIX) | 175 #elif defined(OS_POSIX) |
| 174 base::FilePath input_path(text); | 176 base::FilePath input_path(text); |
| 175 PrepareStringForFileOps(input_path, &filename); | 177 PrepareStringForFileOps(input_path, &filename); |
| 176 if (filename.length() > 0 && filename[0] == '~') | 178 if (filename.length() > 0 && filename[0] == '~') |
| 177 filename = FixupHomedir(filename); | 179 filename = FixupHomedir(filename); |
| 178 #endif | 180 #endif |
| 179 | 181 |
| 180 // Here, we know the input looks like a file. | 182 // Here, we know the input looks like a file. |
| 181 GURL file_url = net::FilePathToFileURL(base::FilePath(filename)); | 183 GURL file_url = net::FilePathToFileURL(base::FilePath(filename)); |
| 182 if (file_url.is_valid()) { | 184 if (file_url.is_valid()) { |
| 183 return base::UTF16ToUTF8(net::FormatUrl(file_url, | 185 return base::UTF16ToUTF8(url_formatter::FormatUrl( |
| 184 std::string(), | 186 file_url, std::string(), url_formatter::kFormatUrlOmitUsernamePassword, |
| 185 net::kFormatUrlOmitUsernamePassword, | 187 net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr)); |
| 186 net::UnescapeRule::NORMAL, | |
| 187 NULL, | |
| 188 NULL, | |
| 189 NULL)); | |
| 190 } | 188 } |
| 191 | 189 |
| 192 // Invalid file URL, just return the input. | 190 // Invalid file URL, just return the input. |
| 193 return text; | 191 return text; |
| 194 } | 192 } |
| 195 | 193 |
| 196 // Checks |domain| to see if a valid TLD is already present. If not, appends | 194 // Checks |domain| to see if a valid TLD is already present. If not, appends |
| 197 // |desired_tld| to the domain, and prepends "www." unless it's already present. | 195 // |desired_tld| to the domain, and prepends "www." unless it's already present. |
| 198 void AddDesiredTLD(const std::string& desired_tld, std::string* domain) { | 196 void AddDesiredTLD(const std::string& desired_tld, std::string* domain) { |
| 199 if (desired_tld.empty() || domain->empty()) | 197 if (desired_tld.empty() || domain->empty()) |
| 200 return; | 198 return; |
| 201 | 199 |
| 202 // Check the TLD. If the return value is positive, we already have a TLD, so | 200 // Check the TLD. If the return value is positive, we already have a TLD, so |
| 203 // abort. If the return value is std::string::npos, there's no valid host, | 201 // abort. If the return value is std::string::npos, there's no valid host, |
| 204 // but we can try to append a TLD anyway, since the host may become valid once | 202 // but we can try to append a TLD anyway, since the host may become valid once |
| 205 // the TLD is attached -- for example, "999999999999" is detected as a broken | 203 // the TLD is attached -- for example, "999999999999" is detected as a broken |
| 206 // IP address and marked invalid, but attaching ".com" makes it legal. When | 204 // IP address and marked invalid, but attaching ".com" makes it legal. When |
| 207 // the return value is 0, there's a valid host with no known TLD, so we can | 205 // the return value is 0, there's a valid host with no known TLD, so we can |
| 208 // definitely append the user's TLD. We disallow unknown registries here so | 206 // definitely append the user's TLD. We disallow unknown registries here so |
| 209 // users can input "mail.yahoo" and hit ctrl-enter to get | 207 // users can input "mail.yahoo" and hit ctrl-enter to get |
| 210 // "www.mail.yahoo.com". | 208 // "www.mail.yahoo.com". |
| 211 const size_t registry_length = | 209 const size_t registry_length = |
| 212 net::registry_controlled_domains::GetRegistryLength( | 210 net::registry_controlled_domains::GetRegistryLength( |
| 213 *domain, | 211 *domain, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, |
| 214 net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, | |
| 215 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); | 212 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); |
| 216 if ((registry_length != 0) && (registry_length != std::string::npos)) | 213 if ((registry_length != 0) && (registry_length != std::string::npos)) |
| 217 return; | 214 return; |
| 218 | 215 |
| 219 // Add the suffix at the end of the domain. | 216 // Add the suffix at the end of the domain. |
| 220 const size_t domain_length(domain->length()); | 217 const size_t domain_length(domain->length()); |
| 221 DCHECK_GT(domain_length, 0U); | 218 DCHECK_GT(domain_length, 0U); |
| 222 DCHECK_NE(desired_tld[0], '.'); | 219 DCHECK_NE(desired_tld[0], '.'); |
| 223 if ((*domain)[domain_length - 1] != '.') | 220 if ((*domain)[domain_length - 1] != '.') |
| 224 domain->push_back('.'); | 221 domain->push_back('.'); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 // Try to extract a valid scheme from the beginning of |text|. | 350 // Try to extract a valid scheme from the beginning of |text|. |
| 354 // If successful, set |scheme_component| to the text range where the scheme | 351 // If successful, set |scheme_component| to the text range where the scheme |
| 355 // was located, and fill |canon_scheme| with its canonicalized form. | 352 // was located, and fill |canon_scheme| with its canonicalized form. |
| 356 // Otherwise, return false and leave the outputs in an indeterminate state. | 353 // Otherwise, return false and leave the outputs in an indeterminate state. |
| 357 bool GetValidScheme(const std::string& text, | 354 bool GetValidScheme(const std::string& text, |
| 358 url::Component* scheme_component, | 355 url::Component* scheme_component, |
| 359 std::string* canon_scheme) { | 356 std::string* canon_scheme) { |
| 360 canon_scheme->clear(); | 357 canon_scheme->clear(); |
| 361 | 358 |
| 362 // Locate everything up to (but not including) the first ':' | 359 // Locate everything up to (but not including) the first ':' |
| 363 if (!url::ExtractScheme( | 360 if (!url::ExtractScheme(text.data(), static_cast<int>(text.length()), |
| 364 text.data(), static_cast<int>(text.length()), scheme_component)) { | 361 scheme_component)) { |
| 365 return false; | 362 return false; |
| 366 } | 363 } |
| 367 | 364 |
| 368 // Make sure the scheme contains only valid characters, and convert | 365 // Make sure the scheme contains only valid characters, and convert |
| 369 // to lowercase. This also catches IPv6 literals like [::1], because | 366 // to lowercase. This also catches IPv6 literals like [::1], because |
| 370 // brackets are not in the whitelist. | 367 // brackets are not in the whitelist. |
| 371 url::StdStringCanonOutput canon_scheme_output(canon_scheme); | 368 url::StdStringCanonOutput canon_scheme_output(canon_scheme); |
| 372 url::Component canon_scheme_component; | 369 url::Component canon_scheme_component; |
| 373 if (!url::CanonicalizeScheme(text.data(), | 370 if (!url::CanonicalizeScheme(text.data(), *scheme_component, |
| 374 *scheme_component, | 371 &canon_scheme_output, &canon_scheme_component)) { |
| 375 &canon_scheme_output, | |
| 376 &canon_scheme_component)) { | |
| 377 return false; | 372 return false; |
| 378 } | 373 } |
| 379 | 374 |
| 380 // Strip the ':', and any trailing buffer space. | 375 // Strip the ':', and any trailing buffer space. |
| 381 DCHECK_EQ(0, canon_scheme_component.begin); | 376 DCHECK_EQ(0, canon_scheme_component.begin); |
| 382 canon_scheme->erase(canon_scheme_component.len); | 377 canon_scheme->erase(canon_scheme_component.len); |
| 383 | 378 |
| 384 // We need to fix up the segmentation for "www.example.com:/". For this | 379 // We need to fix up the segmentation for "www.example.com:/". For this |
| 385 // case, we guess that schemes with a "." are not actually schemes. | 380 // case, we guess that schemes with a "." are not actually schemes. |
| 386 if (canon_scheme->find('.') != std::string::npos) | 381 if (canon_scheme->find('.') != std::string::npos) |
| 387 return false; | 382 return false; |
| 388 | 383 |
| 389 // We need to fix up the segmentation for "www:123/". For this case, we | 384 // We need to fix up the segmentation for "www:123/". For this case, we |
| 390 // will add an HTTP scheme later and make the URL parser happy. | 385 // will add an HTTP scheme later and make the URL parser happy. |
| 391 // TODO(pkasting): Maybe we should try to use GURL's parser for this? | 386 // TODO(pkasting): Maybe we should try to use GURL's parser for this? |
| 392 if (HasPort(text, *scheme_component)) | 387 if (HasPort(text, *scheme_component)) |
| 393 return false; | 388 return false; |
| 394 | 389 |
| 395 // Everything checks out. | 390 // Everything checks out. |
| 396 return true; | 391 return true; |
| 397 } | 392 } |
| 398 | 393 |
| 399 // Performs the work for url_fixer::SegmentURL. |text| may be modified on | 394 // Performs the work for url_formatter::SegmentURL. |text| may be modified on |
| 400 // output on success: a semicolon following a valid scheme is replaced with a | 395 // output on success: a semicolon following a valid scheme is replaced with a |
| 401 // colon. | 396 // colon. |
| 402 std::string SegmentURLInternal(std::string* text, url::Parsed* parts) { | 397 std::string SegmentURLInternal(std::string* text, url::Parsed* parts) { |
| 403 // Initialize the result. | 398 // Initialize the result. |
| 404 *parts = url::Parsed(); | 399 *parts = url::Parsed(); |
| 405 | 400 |
| 406 std::string trimmed; | 401 std::string trimmed; |
| 407 TrimWhitespaceUTF8(*text, base::TRIM_ALL, &trimmed); | 402 TrimWhitespaceUTF8(*text, base::TRIM_ALL, &trimmed); |
| 408 if (trimmed.empty()) | 403 if (trimmed.empty()) |
| 409 return std::string(); // Nothing to segment. | 404 return std::string(); // Nothing to segment. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 429 if (semicolon != 0 && semicolon != std::string::npos) { | 424 if (semicolon != 0 && semicolon != std::string::npos) { |
| 430 (*text)[semicolon] = ':'; | 425 (*text)[semicolon] = ':'; |
| 431 if (GetValidScheme(*text, &parts->scheme, &scheme)) | 426 if (GetValidScheme(*text, &parts->scheme, &scheme)) |
| 432 found_scheme = true; | 427 found_scheme = true; |
| 433 else | 428 else |
| 434 (*text)[semicolon] = ';'; | 429 (*text)[semicolon] = ';'; |
| 435 } | 430 } |
| 436 if (!found_scheme) { | 431 if (!found_scheme) { |
| 437 // Couldn't determine the scheme, so just pick one. | 432 // Couldn't determine the scheme, so just pick one. |
| 438 parts->scheme.reset(); | 433 parts->scheme.reset(); |
| 439 scheme = base::StartsWith(*text, "ftp.", | 434 scheme = |
| 440 base::CompareCase::INSENSITIVE_ASCII) ? | 435 base::StartsWith(*text, "ftp.", base::CompareCase::INSENSITIVE_ASCII) |
| 441 url::kFtpScheme : url::kHttpScheme; | 436 ? url::kFtpScheme |
| 437 : url::kHttpScheme; |
| 442 } | 438 } |
| 443 } | 439 } |
| 444 | 440 |
| 445 // Proceed with about and chrome schemes, but not file or nonstandard schemes. | 441 // Proceed with about and chrome schemes, but not file or nonstandard schemes. |
| 446 if ((scheme != url::kAboutScheme) && (scheme != kChromeUIScheme) && | 442 if ((scheme != url::kAboutScheme) && (scheme != kChromeUIScheme) && |
| 447 ((scheme == url::kFileScheme) || | 443 ((scheme == url::kFileScheme) || |
| 448 !url::IsStandard( | 444 !url::IsStandard( |
| 449 scheme.c_str(), | 445 scheme.c_str(), |
| 450 url::Component(0, static_cast<int>(scheme.length()))))) { | 446 url::Component(0, static_cast<int>(scheme.length()))))) { |
| 451 return scheme; | 447 return scheme; |
| 452 } | 448 } |
| 453 | 449 |
| 454 if (scheme == url::kFileSystemScheme) { | 450 if (scheme == url::kFileSystemScheme) { |
| 455 // Have the GURL parser do the heavy lifting for us. | 451 // Have the GURL parser do the heavy lifting for us. |
| 456 url::ParseFileSystemURL( | 452 url::ParseFileSystemURL(text->data(), static_cast<int>(text->length()), |
| 457 text->data(), static_cast<int>(text->length()), parts); | 453 parts); |
| 458 return scheme; | 454 return scheme; |
| 459 } | 455 } |
| 460 | 456 |
| 461 if (parts->scheme.is_valid()) { | 457 if (parts->scheme.is_valid()) { |
| 462 // Have the GURL parser do the heavy lifting for us. | 458 // Have the GURL parser do the heavy lifting for us. |
| 463 url::ParseStandardURL( | 459 url::ParseStandardURL(text->data(), static_cast<int>(text->length()), |
| 464 text->data(), static_cast<int>(text->length()), parts); | 460 parts); |
| 465 return scheme; | 461 return scheme; |
| 466 } | 462 } |
| 467 | 463 |
| 468 // We need to add a scheme in order for ParseStandardURL to be happy. | 464 // We need to add a scheme in order for ParseStandardURL to be happy. |
| 469 // Find the first non-whitespace character. | 465 // Find the first non-whitespace character. |
| 470 std::string::iterator first_nonwhite = text->begin(); | 466 std::string::iterator first_nonwhite = text->begin(); |
| 471 while ((first_nonwhite != text->end()) && | 467 while ((first_nonwhite != text->end()) && |
| 472 base::IsUnicodeWhitespace(*first_nonwhite)) | 468 base::IsUnicodeWhitespace(*first_nonwhite)) |
| 473 ++first_nonwhite; | 469 ++first_nonwhite; |
| 474 | 470 |
| 475 // Construct the text to parse by inserting the scheme. | 471 // Construct the text to parse by inserting the scheme. |
| 476 std::string inserted_text(scheme); | 472 std::string inserted_text(scheme); |
| 477 inserted_text.append(url::kStandardSchemeSeparator); | 473 inserted_text.append(url::kStandardSchemeSeparator); |
| 478 std::string text_to_parse(text->begin(), first_nonwhite); | 474 std::string text_to_parse(text->begin(), first_nonwhite); |
| 479 text_to_parse.append(inserted_text); | 475 text_to_parse.append(inserted_text); |
| 480 text_to_parse.append(first_nonwhite, text->end()); | 476 text_to_parse.append(first_nonwhite, text->end()); |
| 481 | 477 |
| 482 // Have the GURL parser do the heavy lifting for us. | 478 // Have the GURL parser do the heavy lifting for us. |
| 483 url::ParseStandardURL( | 479 url::ParseStandardURL(text_to_parse.data(), |
| 484 text_to_parse.data(), static_cast<int>(text_to_parse.length()), parts); | 480 static_cast<int>(text_to_parse.length()), parts); |
| 485 | 481 |
| 486 // Offset the results of the parse to match the original text. | 482 // Offset the results of the parse to match the original text. |
| 487 const int offset = -static_cast<int>(inserted_text.length()); | 483 const int offset = -static_cast<int>(inserted_text.length()); |
| 488 url_fixer::OffsetComponent(offset, &parts->scheme); | 484 OffsetComponent(offset, &parts->scheme); |
| 489 url_fixer::OffsetComponent(offset, &parts->username); | 485 OffsetComponent(offset, &parts->username); |
| 490 url_fixer::OffsetComponent(offset, &parts->password); | 486 OffsetComponent(offset, &parts->password); |
| 491 url_fixer::OffsetComponent(offset, &parts->host); | 487 OffsetComponent(offset, &parts->host); |
| 492 url_fixer::OffsetComponent(offset, &parts->port); | 488 OffsetComponent(offset, &parts->port); |
| 493 url_fixer::OffsetComponent(offset, &parts->path); | 489 OffsetComponent(offset, &parts->path); |
| 494 url_fixer::OffsetComponent(offset, &parts->query); | 490 OffsetComponent(offset, &parts->query); |
| 495 url_fixer::OffsetComponent(offset, &parts->ref); | 491 OffsetComponent(offset, &parts->ref); |
| 496 | 492 |
| 497 return scheme; | 493 return scheme; |
| 498 } | 494 } |
| 499 | 495 |
| 500 } // namespace | 496 } // namespace |
| 501 | 497 |
| 502 std::string url_fixer::SegmentURL(const std::string& text, url::Parsed* parts) { | 498 std::string SegmentURL(const std::string& text, url::Parsed* parts) { |
| 503 std::string mutable_text(text); | 499 std::string mutable_text(text); |
| 504 return SegmentURLInternal(&mutable_text, parts); | 500 return SegmentURLInternal(&mutable_text, parts); |
| 505 } | 501 } |
| 506 | 502 |
| 507 base::string16 url_fixer::SegmentURL(const base::string16& text, | 503 base::string16 SegmentURL(const base::string16& text, url::Parsed* parts) { |
| 508 url::Parsed* parts) { | |
| 509 std::string text_utf8 = base::UTF16ToUTF8(text); | 504 std::string text_utf8 = base::UTF16ToUTF8(text); |
| 510 url::Parsed parts_utf8; | 505 url::Parsed parts_utf8; |
| 511 std::string scheme_utf8 = SegmentURL(text_utf8, &parts_utf8); | 506 std::string scheme_utf8 = SegmentURL(text_utf8, &parts_utf8); |
| 512 UTF8PartsToUTF16Parts(text_utf8, parts_utf8, parts); | 507 UTF8PartsToUTF16Parts(text_utf8, parts_utf8, parts); |
| 513 return base::UTF8ToUTF16(scheme_utf8); | 508 return base::UTF8ToUTF16(scheme_utf8); |
| 514 } | 509 } |
| 515 | 510 |
| 516 GURL url_fixer::FixupURL(const std::string& text, | 511 GURL FixupURL(const std::string& text, const std::string& desired_tld) { |
| 517 const std::string& desired_tld) { | |
| 518 std::string trimmed; | 512 std::string trimmed; |
| 519 TrimWhitespaceUTF8(text, base::TRIM_ALL, &trimmed); | 513 TrimWhitespaceUTF8(text, base::TRIM_ALL, &trimmed); |
| 520 if (trimmed.empty()) | 514 if (trimmed.empty()) |
| 521 return GURL(); // Nothing here. | 515 return GURL(); // Nothing here. |
| 522 | 516 |
| 523 // Segment the URL. | 517 // Segment the URL. |
| 524 url::Parsed parts; | 518 url::Parsed parts; |
| 525 std::string scheme(SegmentURLInternal(&trimmed, &parts)); | 519 std::string scheme(SegmentURLInternal(&trimmed, &parts)); |
| 526 | 520 |
| 527 // For view-source: URLs, we strip "view-source:", do fixup, and stick it back | 521 // For view-source: URLs, we strip "view-source:", do fixup, and stick it back |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 } | 583 } |
| 590 | 584 |
| 591 return GURL(trimmed); | 585 return GURL(trimmed); |
| 592 } | 586 } |
| 593 | 587 |
| 594 // The rules are different here than for regular fixup, since we need to handle | 588 // The rules are different here than for regular fixup, since we need to handle |
| 595 // input like "hello.html" and know to look in the current directory. Regular | 589 // input like "hello.html" and know to look in the current directory. Regular |
| 596 // fixup will look for cues that it is actually a file path before trying to | 590 // fixup will look for cues that it is actually a file path before trying to |
| 597 // figure out what file it is. If our logic doesn't work, we will fall back on | 591 // figure out what file it is. If our logic doesn't work, we will fall back on |
| 598 // regular fixup. | 592 // regular fixup. |
| 599 GURL url_fixer::FixupRelativeFile(const base::FilePath& base_dir, | 593 GURL FixupRelativeFile(const base::FilePath& base_dir, |
| 600 const base::FilePath& text) { | 594 const base::FilePath& text) { |
| 601 base::FilePath old_cur_directory; | 595 base::FilePath old_cur_directory; |
| 602 if (!base_dir.empty()) { | 596 if (!base_dir.empty()) { |
| 603 // Save the old current directory before we move to the new one. | 597 // Save the old current directory before we move to the new one. |
| 604 base::GetCurrentDirectory(&old_cur_directory); | 598 base::GetCurrentDirectory(&old_cur_directory); |
| 605 base::SetCurrentDirectory(base_dir); | 599 base::SetCurrentDirectory(base_dir); |
| 606 } | 600 } |
| 607 | 601 |
| 608 // Allow funny input with extra whitespace and the wrong kind of slashes. | 602 // Allow funny input with extra whitespace and the wrong kind of slashes. |
| 609 base::FilePath::StringType trimmed; | 603 base::FilePath::StringType trimmed; |
| 610 PrepareStringForFileOps(text, &trimmed); | 604 PrepareStringForFileOps(text, &trimmed); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 633 is_file = false; | 627 is_file = false; |
| 634 } | 628 } |
| 635 | 629 |
| 636 // Put back the current directory if we saved it. | 630 // Put back the current directory if we saved it. |
| 637 if (!base_dir.empty()) | 631 if (!base_dir.empty()) |
| 638 base::SetCurrentDirectory(old_cur_directory); | 632 base::SetCurrentDirectory(old_cur_directory); |
| 639 | 633 |
| 640 if (is_file) { | 634 if (is_file) { |
| 641 GURL file_url = net::FilePathToFileURL(full_path); | 635 GURL file_url = net::FilePathToFileURL(full_path); |
| 642 if (file_url.is_valid()) | 636 if (file_url.is_valid()) |
| 643 return GURL( | 637 return GURL(base::UTF16ToUTF8(url_formatter::FormatUrl( |
| 644 base::UTF16ToUTF8(net::FormatUrl(file_url, | 638 file_url, std::string(), |
| 645 std::string(), | 639 url_formatter::kFormatUrlOmitUsernamePassword, |
| 646 net::kFormatUrlOmitUsernamePassword, | 640 net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr))); |
| 647 net::UnescapeRule::NORMAL, | |
| 648 NULL, | |
| 649 NULL, | |
| 650 NULL))); | |
| 651 // Invalid files fall through to regular processing. | 641 // Invalid files fall through to regular processing. |
| 652 } | 642 } |
| 653 | 643 |
| 654 // Fall back on regular fixup for this input. | 644 // Fall back on regular fixup for this input. |
| 655 #if defined(OS_WIN) | 645 #if defined(OS_WIN) |
| 656 std::string text_utf8 = base::WideToUTF8(text.value()); | 646 std::string text_utf8 = base::WideToUTF8(text.value()); |
| 657 #elif defined(OS_POSIX) | 647 #elif defined(OS_POSIX) |
| 658 std::string text_utf8 = text.value(); | 648 std::string text_utf8 = text.value(); |
| 659 #endif | 649 #endif |
| 660 return FixupURL(text_utf8, std::string()); | 650 return FixupURL(text_utf8, std::string()); |
| 661 } | 651 } |
| 662 | 652 |
| 663 void url_fixer::OffsetComponent(int offset, url::Component* part) { | 653 void OffsetComponent(int offset, url::Component* part) { |
| 664 DCHECK(part); | 654 DCHECK(part); |
| 665 | 655 |
| 666 if (part->is_valid()) { | 656 if (part->is_valid()) { |
| 667 // Offset the location of this component. | 657 // Offset the location of this component. |
| 668 part->begin += offset; | 658 part->begin += offset; |
| 669 | 659 |
| 670 // This part might not have existed in the original text. | 660 // This part might not have existed in the original text. |
| 671 if (part->begin < 0) | 661 if (part->begin < 0) |
| 672 part->reset(); | 662 part->reset(); |
| 673 } | 663 } |
| 674 } | 664 } |
| 675 | 665 |
| 676 bool url_fixer::IsEquivalentScheme(const std::string& scheme1, | 666 bool IsEquivalentScheme(const std::string& scheme1, |
| 677 const std::string& scheme2) { | 667 const std::string& scheme2) { |
| 678 return scheme1 == scheme2 || | 668 return scheme1 == scheme2 || |
| 679 (scheme1 == url::kAboutScheme && scheme2 == kChromeUIScheme) || | 669 (scheme1 == url::kAboutScheme && scheme2 == kChromeUIScheme) || |
| 680 (scheme1 == kChromeUIScheme && scheme2 == url::kAboutScheme); | 670 (scheme1 == kChromeUIScheme && scheme2 == url::kAboutScheme); |
| 681 } | 671 } |
| 672 |
| 673 } // namespace url_formatter |
| OLD | NEW |