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" |
13 #include "base/values.h" | 14 #include "base/values.h" |
14 #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" | 15 #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" |
15 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta
nts.h" | 16 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta
nts.h" |
16 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" | 17 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
17 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" | 18 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" |
18 #include "chrome/browser/extensions/extension_info_map.h" | 19 #include "chrome/browser/extensions/extension_info_map.h" |
19 #include "chrome/common/extensions/extension.h" | 20 #include "chrome/common/extensions/extension.h" |
20 #include "net/url_request/url_request.h" | 21 #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 to = WebRequestRedirectByRegExAction::PerlToRe2Style(to); | 111 // TODO(battre): Add this line once we migrate from ICU RegEx to RE2 RegEx.s |
| 112 // to = WebRequestRedirectByRegExAction::PerlToRe2Style(to); |
112 | 113 |
113 RE2::Options options; | 114 UParseError parse_error; |
114 options.set_case_sensitive(false); | 115 UErrorCode status = U_ZERO_ERROR; |
115 scoped_ptr<RE2> from_pattern(new RE2(from, options)); | 116 scoped_ptr<icu::RegexPattern> pattern( |
116 | 117 icu::RegexPattern::compile(icu::UnicodeString(from.data(), from.size()), |
117 if (!from_pattern->ok()) { | 118 0, parse_error, status)); |
| 119 if (U_FAILURE(status) || !pattern.get()) { |
118 *error = "Invalid pattern '" + from + "' -> '" + to + "'"; | 120 *error = "Invalid pattern '" + from + "' -> '" + to + "'"; |
119 return scoped_ptr<WebRequestAction>(NULL); | 121 return scoped_ptr<WebRequestAction>(NULL); |
120 } | 122 } |
121 return scoped_ptr<WebRequestAction>( | 123 return scoped_ptr<WebRequestAction>( |
122 new WebRequestRedirectByRegExAction(from_pattern.Pass(), to)); | 124 new WebRequestRedirectByRegExAction(pattern.Pass(), to)); |
123 } | 125 } |
124 | 126 |
125 scoped_ptr<WebRequestAction> CreateSetRequestHeaderAction( | 127 scoped_ptr<WebRequestAction> CreateSetRequestHeaderAction( |
126 const base::DictionaryValue* dict, | 128 const base::DictionaryValue* dict, |
127 std::string* error, | 129 std::string* error, |
128 bool* bad_message) { | 130 bool* bad_message) { |
129 std::string name; | 131 std::string name; |
130 std::string value; | 132 std::string value; |
131 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); | 133 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); |
132 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); | 134 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 new helpers::EventResponseDelta(extension_id, extension_install_time)); | 583 new helpers::EventResponseDelta(extension_id, extension_install_time)); |
582 result->new_url = GURL(kEmptyDocumentUrl); | 584 result->new_url = GURL(kEmptyDocumentUrl); |
583 return result; | 585 return result; |
584 } | 586 } |
585 | 587 |
586 // | 588 // |
587 // WebRequestRedirectByRegExAction | 589 // WebRequestRedirectByRegExAction |
588 // | 590 // |
589 | 591 |
590 WebRequestRedirectByRegExAction::WebRequestRedirectByRegExAction( | 592 WebRequestRedirectByRegExAction::WebRequestRedirectByRegExAction( |
591 scoped_ptr<RE2> from_pattern, | 593 scoped_ptr<icu::RegexPattern> from_pattern, |
592 const std::string& to_pattern) | 594 const std::string& to_pattern) |
593 : from_pattern_(from_pattern.Pass()), | 595 : from_pattern_(from_pattern.Pass()), |
594 to_pattern_(to_pattern.data(), to_pattern.size()) {} | 596 to_pattern_(to_pattern.data(), to_pattern.size()) {} |
595 | 597 |
596 WebRequestRedirectByRegExAction::~WebRequestRedirectByRegExAction() {} | 598 WebRequestRedirectByRegExAction::~WebRequestRedirectByRegExAction() {} |
597 | 599 |
598 // About the syntax of the two languages: | 600 // About the syntax of the two languages: |
599 // | 601 // |
600 // ICU (Perl) states: | 602 // ICU (Perl) states: |
601 // $n The text of capture group n will be substituted for $n. n must be >= 0 | 603 // $n The text of capture group n will be substituted for $n. n must be >= 0 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 | 660 |
659 LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta( | 661 LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta( |
660 net::URLRequest* request, | 662 net::URLRequest* request, |
661 RequestStages request_stage, | 663 RequestStages request_stage, |
662 const WebRequestRule::OptionalRequestData& optional_request_data, | 664 const WebRequestRule::OptionalRequestData& optional_request_data, |
663 const std::string& extension_id, | 665 const std::string& extension_id, |
664 const base::Time& extension_install_time) const { | 666 const base::Time& extension_install_time) const { |
665 CHECK(request_stage & GetStages()); | 667 CHECK(request_stage & GetStages()); |
666 CHECK(from_pattern_.get()); | 668 CHECK(from_pattern_.get()); |
667 | 669 |
| 670 UErrorCode status = U_ZERO_ERROR; |
668 const std::string& old_url = request->url().spec(); | 671 const std::string& old_url = request->url().spec(); |
669 std::string new_url = old_url; | 672 icu::UnicodeString old_url_unicode(old_url.data(), old_url.size()); |
670 if (!RE2::Replace(&new_url, *from_pattern_, to_pattern_) || | 673 |
671 new_url == old_url) { | 674 scoped_ptr<icu::RegexMatcher> matcher( |
| 675 from_pattern_->matcher(old_url_unicode, status)); |
| 676 if (U_FAILURE(status) || !matcher.get()) |
672 return LinkedPtrEventResponseDelta(NULL); | 677 return LinkedPtrEventResponseDelta(NULL); |
673 } | 678 |
| 679 icu::UnicodeString new_url = matcher->replaceAll(to_pattern_, status); |
| 680 if (U_FAILURE(status)) |
| 681 return LinkedPtrEventResponseDelta(NULL); |
| 682 |
| 683 std::string new_url_utf8; |
| 684 UTF16ToUTF8(new_url.getBuffer(), new_url.length(), &new_url_utf8); |
| 685 |
| 686 if (new_url_utf8 == request->url().spec()) |
| 687 return LinkedPtrEventResponseDelta(NULL); |
674 | 688 |
675 LinkedPtrEventResponseDelta result( | 689 LinkedPtrEventResponseDelta result( |
676 new extension_web_request_api_helpers::EventResponseDelta( | 690 new extension_web_request_api_helpers::EventResponseDelta( |
677 extension_id, extension_install_time)); | 691 extension_id, extension_install_time)); |
678 result->new_url = GURL(new_url); | 692 result->new_url = GURL(new_url_utf8); |
679 return result; | 693 return result; |
680 } | 694 } |
681 | 695 |
682 // | 696 // |
683 // WebRequestSetRequestHeaderAction | 697 // WebRequestSetRequestHeaderAction |
684 // | 698 // |
685 | 699 |
686 WebRequestSetRequestHeaderAction::WebRequestSetRequestHeaderAction( | 700 WebRequestSetRequestHeaderAction::WebRequestSetRequestHeaderAction( |
687 const std::string& name, | 701 const std::string& name, |
688 const std::string& value) | 702 const std::string& value) |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 CHECK(request_stage & GetStages()); | 964 CHECK(request_stage & GetStages()); |
951 LinkedPtrEventResponseDelta result( | 965 LinkedPtrEventResponseDelta result( |
952 new extension_web_request_api_helpers::EventResponseDelta( | 966 new extension_web_request_api_helpers::EventResponseDelta( |
953 extension_id, extension_install_time)); | 967 extension_id, extension_install_time)); |
954 result->response_cookie_modifications.push_back( | 968 result->response_cookie_modifications.push_back( |
955 response_cookie_modification_); | 969 response_cookie_modification_); |
956 return result; | 970 return result; |
957 } | 971 } |
958 | 972 |
959 } // namespace extensions | 973 } // namespace extensions |
OLD | NEW |