| 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 "chrome/browser/extensions/api/declarative_webrequest/webrequest_action
.h" | 5 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action
.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/utf_string_conversions.h" | |
| 14 #include "base/values.h" | 13 #include "base/values.h" |
| 15 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h" | 14 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h" |
| 16 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta
nts.h" | 15 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta
nts.h" |
| 17 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" | 16 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
| 18 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" | 17 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" |
| 19 #include "chrome/browser/extensions/extension_info_map.h" | 18 #include "chrome/browser/extensions/extension_info_map.h" |
| 20 #include "chrome/common/extensions/extension.h" | 19 #include "chrome/common/extensions/extension.h" |
| 21 #include "net/url_request/url_request.h" | 20 #include "net/url_request/url_request.h" |
| 21 #include "third_party/re2/re2/re2.h" |
| 22 | 22 |
| 23 namespace extensions { | 23 namespace extensions { |
| 24 | 24 |
| 25 namespace helpers = extension_web_request_api_helpers; | 25 namespace helpers = extension_web_request_api_helpers; |
| 26 namespace keys = declarative_webrequest_constants; | 26 namespace keys = declarative_webrequest_constants; |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 // Error messages. | 29 // Error messages. |
| 30 const char kInvalidInstanceTypeError[] = | 30 const char kInvalidInstanceTypeError[] = |
| 31 "An action has an invalid instanceType: %s"; | 31 "An action has an invalid instanceType: %s"; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 | 101 |
| 102 scoped_ptr<WebRequestAction> CreateRedirectRequestByRegExAction( | 102 scoped_ptr<WebRequestAction> CreateRedirectRequestByRegExAction( |
| 103 const base::DictionaryValue* dict, | 103 const base::DictionaryValue* dict, |
| 104 std::string* error, | 104 std::string* error, |
| 105 bool* bad_message) { | 105 bool* bad_message) { |
| 106 std::string from; | 106 std::string from; |
| 107 std::string to; | 107 std::string to; |
| 108 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kFromKey, &from)); | 108 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kFromKey, &from)); |
| 109 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kToKey, &to)); | 109 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kToKey, &to)); |
| 110 | 110 |
| 111 // TODO(battre): Add this line once we migrate from ICU RegEx to RE2 RegEx.s | 111 to = WebRequestRedirectByRegExAction::PerlToRe2Style(to); |
| 112 // to = WebRequestRedirectByRegExAction::PerlToRe2Style(to); | |
| 113 | 112 |
| 114 UParseError parse_error; | 113 RE2::Options options; |
| 115 UErrorCode status = U_ZERO_ERROR; | 114 options.set_case_sensitive(false); |
| 116 scoped_ptr<icu::RegexPattern> pattern( | 115 scoped_ptr<RE2> from_pattern(new RE2(from, options)); |
| 117 icu::RegexPattern::compile(icu::UnicodeString(from.data(), from.size()), | 116 |
| 118 0, parse_error, status)); | 117 if (!from_pattern->ok()) { |
| 119 if (U_FAILURE(status) || !pattern.get()) { | |
| 120 *error = "Invalid pattern '" + from + "' -> '" + to + "'"; | 118 *error = "Invalid pattern '" + from + "' -> '" + to + "'"; |
| 121 return scoped_ptr<WebRequestAction>(NULL); | 119 return scoped_ptr<WebRequestAction>(NULL); |
| 122 } | 120 } |
| 123 return scoped_ptr<WebRequestAction>( | 121 return scoped_ptr<WebRequestAction>( |
| 124 new WebRequestRedirectByRegExAction(pattern.Pass(), to)); | 122 new WebRequestRedirectByRegExAction(from_pattern.Pass(), to)); |
| 125 } | 123 } |
| 126 | 124 |
| 127 scoped_ptr<WebRequestAction> CreateSetRequestHeaderAction( | 125 scoped_ptr<WebRequestAction> CreateSetRequestHeaderAction( |
| 128 const base::DictionaryValue* dict, | 126 const base::DictionaryValue* dict, |
| 129 std::string* error, | 127 std::string* error, |
| 130 bool* bad_message) { | 128 bool* bad_message) { |
| 131 std::string name; | 129 std::string name; |
| 132 std::string value; | 130 std::string value; |
| 133 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); | 131 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); |
| 134 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); | 132 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 new helpers::EventResponseDelta(extension_id, extension_install_time)); | 570 new helpers::EventResponseDelta(extension_id, extension_install_time)); |
| 573 result->new_url = GURL(kEmptyDocumentUrl); | 571 result->new_url = GURL(kEmptyDocumentUrl); |
| 574 return result; | 572 return result; |
| 575 } | 573 } |
| 576 | 574 |
| 577 // | 575 // |
| 578 // WebRequestRedirectByRegExAction | 576 // WebRequestRedirectByRegExAction |
| 579 // | 577 // |
| 580 | 578 |
| 581 WebRequestRedirectByRegExAction::WebRequestRedirectByRegExAction( | 579 WebRequestRedirectByRegExAction::WebRequestRedirectByRegExAction( |
| 582 scoped_ptr<icu::RegexPattern> from_pattern, | 580 scoped_ptr<RE2> from_pattern, |
| 583 const std::string& to_pattern) | 581 const std::string& to_pattern) |
| 584 : from_pattern_(from_pattern.Pass()), | 582 : from_pattern_(from_pattern.Pass()), |
| 585 to_pattern_(to_pattern.data(), to_pattern.size()) {} | 583 to_pattern_(to_pattern.data(), to_pattern.size()) {} |
| 586 | 584 |
| 587 WebRequestRedirectByRegExAction::~WebRequestRedirectByRegExAction() {} | 585 WebRequestRedirectByRegExAction::~WebRequestRedirectByRegExAction() {} |
| 588 | 586 |
| 589 // About the syntax of the two languages: | 587 // About the syntax of the two languages: |
| 590 // | 588 // |
| 591 // ICU (Perl) states: | 589 // ICU (Perl) states: |
| 592 // $n The text of capture group n will be substituted for $n. n must be >= 0 | 590 // $n The text of capture group n will be substituted for $n. n must be >= 0 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 return WebRequestAction::ACTION_REDIRECT_BY_REGEX_DOCUMENT; | 645 return WebRequestAction::ACTION_REDIRECT_BY_REGEX_DOCUMENT; |
| 648 } | 646 } |
| 649 | 647 |
| 650 LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta( | 648 LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta( |
| 651 const WebRequestRule::RequestData& request_data, | 649 const WebRequestRule::RequestData& request_data, |
| 652 const std::string& extension_id, | 650 const std::string& extension_id, |
| 653 const base::Time& extension_install_time) const { | 651 const base::Time& extension_install_time) const { |
| 654 CHECK(request_data.stage & GetStages()); | 652 CHECK(request_data.stage & GetStages()); |
| 655 CHECK(from_pattern_.get()); | 653 CHECK(from_pattern_.get()); |
| 656 | 654 |
| 657 UErrorCode status = U_ZERO_ERROR; | |
| 658 const std::string& old_url = request_data.request->url().spec(); | 655 const std::string& old_url = request_data.request->url().spec(); |
| 659 icu::UnicodeString old_url_unicode(old_url.data(), old_url.size()); | 656 std::string new_url = old_url; |
| 660 | 657 if (!RE2::Replace(&new_url, *from_pattern_, to_pattern_) || |
| 661 scoped_ptr<icu::RegexMatcher> matcher( | 658 new_url == old_url) { |
| 662 from_pattern_->matcher(old_url_unicode, status)); | |
| 663 if (U_FAILURE(status) || !matcher.get()) | |
| 664 return LinkedPtrEventResponseDelta(NULL); | 659 return LinkedPtrEventResponseDelta(NULL); |
| 665 | 660 } |
| 666 icu::UnicodeString new_url = matcher->replaceAll(to_pattern_, status); | |
| 667 if (U_FAILURE(status)) | |
| 668 return LinkedPtrEventResponseDelta(NULL); | |
| 669 | |
| 670 std::string new_url_utf8; | |
| 671 UTF16ToUTF8(new_url.getBuffer(), new_url.length(), &new_url_utf8); | |
| 672 | |
| 673 if (new_url_utf8 == request_data.request->url().spec()) | |
| 674 return LinkedPtrEventResponseDelta(NULL); | |
| 675 | 661 |
| 676 LinkedPtrEventResponseDelta result( | 662 LinkedPtrEventResponseDelta result( |
| 677 new extension_web_request_api_helpers::EventResponseDelta( | 663 new extension_web_request_api_helpers::EventResponseDelta( |
| 678 extension_id, extension_install_time)); | 664 extension_id, extension_install_time)); |
| 679 result->new_url = GURL(new_url_utf8); | 665 result->new_url = GURL(new_url); |
| 680 return result; | 666 return result; |
| 681 } | 667 } |
| 682 | 668 |
| 683 // | 669 // |
| 684 // WebRequestSetRequestHeaderAction | 670 // WebRequestSetRequestHeaderAction |
| 685 // | 671 // |
| 686 | 672 |
| 687 WebRequestSetRequestHeaderAction::WebRequestSetRequestHeaderAction( | 673 WebRequestSetRequestHeaderAction::WebRequestSetRequestHeaderAction( |
| 688 const std::string& name, | 674 const std::string& name, |
| 689 const std::string& value) | 675 const std::string& value) |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 CHECK(request_data.stage & GetStages()); | 923 CHECK(request_data.stage & GetStages()); |
| 938 LinkedPtrEventResponseDelta result( | 924 LinkedPtrEventResponseDelta result( |
| 939 new extension_web_request_api_helpers::EventResponseDelta( | 925 new extension_web_request_api_helpers::EventResponseDelta( |
| 940 extension_id, extension_install_time)); | 926 extension_id, extension_install_time)); |
| 941 result->response_cookie_modifications.push_back( | 927 result->response_cookie_modifications.push_back( |
| 942 response_cookie_modification_); | 928 response_cookie_modification_); |
| 943 return result; | 929 return result; |
| 944 } | 930 } |
| 945 | 931 |
| 946 } // namespace extensions | 932 } // namespace extensions |
| OLD | NEW |