Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: chrome/browser/extensions/extension_webrequest_api.cc

Issue 6880219: Fix crash with webRequest.event.addListener when provided an invalid URL (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: oops Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "chrome/browser/extensions/extension_webrequest_api.h" 5 #include "chrome/browser/extensions/extension_webrequest_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 141
142 // Internal representation of the webRequest.RequestFilter type, used to 142 // Internal representation of the webRequest.RequestFilter type, used to
143 // filter what network events an extension cares about. 143 // filter what network events an extension cares about.
144 struct ExtensionWebRequestEventRouter::RequestFilter { 144 struct ExtensionWebRequestEventRouter::RequestFilter {
145 ExtensionExtent urls; 145 ExtensionExtent urls;
146 std::vector<ResourceType::Type> types; 146 std::vector<ResourceType::Type> types;
147 int tab_id; 147 int tab_id;
148 int window_id; 148 int window_id;
149 149
150 RequestFilter() : tab_id(-1), window_id(-1) {} 150 RequestFilter() : tab_id(-1), window_id(-1) {}
151 bool InitFromValue(const DictionaryValue& value); 151 // Returns false if there was an error initializing. If it is a user error,
152 // an error message is provided, otherwise the error is internal (and
153 // unexpected).
154 bool InitFromValue(const DictionaryValue& value, std::string* error);
152 }; 155 };
153 156
154 // Internal representation of the extraInfoSpec parameter on webRequest events, 157 // Internal representation of the extraInfoSpec parameter on webRequest events,
155 // used to specify extra information to be included with network events. 158 // used to specify extra information to be included with network events.
156 struct ExtensionWebRequestEventRouter::ExtraInfoSpec { 159 struct ExtensionWebRequestEventRouter::ExtraInfoSpec {
157 enum Flags { 160 enum Flags {
158 REQUEST_LINE = 1<<0, 161 REQUEST_LINE = 1<<0,
159 REQUEST_HEADERS = 1<<1, 162 REQUEST_HEADERS = 1<<1,
160 STATUS_LINE = 1<<2, 163 STATUS_LINE = 1<<2,
161 RESPONSE_HEADERS = 1<<3, 164 RESPONSE_HEADERS = 1<<3,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 // If non-empty, this contains the new URL that the request will redirect to. 203 // If non-empty, this contains the new URL that the request will redirect to.
201 GURL* new_url; 204 GURL* new_url;
202 205
203 // Time the request was issued. Used for logging purposes. 206 // Time the request was issued. Used for logging purposes.
204 base::Time request_time; 207 base::Time request_time;
205 208
206 BlockedRequest() : num_handlers_blocking(0), callback(NULL), new_url(NULL) {} 209 BlockedRequest() : num_handlers_blocking(0), callback(NULL), new_url(NULL) {}
207 }; 210 };
208 211
209 bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( 212 bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue(
210 const DictionaryValue& value) { 213 const DictionaryValue& value, std::string* error) {
211 for (DictionaryValue::key_iterator key = value.begin_keys(); 214 for (DictionaryValue::key_iterator key = value.begin_keys();
212 key != value.end_keys(); ++key) { 215 key != value.end_keys(); ++key) {
213 if (*key == "urls") { 216 if (*key == "urls") {
214 ListValue* urls_value = NULL; 217 ListValue* urls_value = NULL;
215 if (!value.GetList("urls", &urls_value)) 218 if (!value.GetList("urls", &urls_value))
216 return false; 219 return false;
217 for (size_t i = 0; i < urls_value->GetSize(); ++i) { 220 for (size_t i = 0; i < urls_value->GetSize(); ++i) {
218 std::string url; 221 std::string url;
219 URLPattern pattern(URLPattern::SCHEME_ALL); 222 URLPattern pattern(URLPattern::SCHEME_ALL);
220 if (!urls_value->GetString(i, &url) || 223 if (!urls_value->GetString(i, &url) ||
221 pattern.Parse(url, URLPattern::PARSE_STRICT) != 224 pattern.Parse(url, URLPattern::PARSE_STRICT) !=
222 URLPattern::PARSE_SUCCESS) 225 URLPattern::PARSE_SUCCESS) {
226 *error = ExtensionErrorUtils::FormatErrorMessage(
227 keys::kInvalidRequestFilterUrl, url);
223 return false; 228 return false;
229 }
224 urls.AddPattern(pattern); 230 urls.AddPattern(pattern);
225 } 231 }
226 } else if (*key == "types") { 232 } else if (*key == "types") {
227 ListValue* types_value = NULL; 233 ListValue* types_value = NULL;
228 if (!value.GetList("types", &types_value)) 234 if (!value.GetList("types", &types_value))
229 return false; 235 return false;
230 for (size_t i = 0; i < types_value->GetSize(); ++i) { 236 for (size_t i = 0; i < types_value->GetSize(); ++i) {
231 std::string type_str; 237 std::string type_str;
232 ResourceType::Type type; 238 ResourceType::Type type;
233 if (!types_value->GetString(i, &type_str) || 239 if (!types_value->GetString(i, &type_str) ||
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 size_t slash_sep = sub_event_name.find('/'); 665 size_t slash_sep = sub_event_name.find('/');
660 std::string event_name = sub_event_name.substr(0, slash_sep); 666 std::string event_name = sub_event_name.substr(0, slash_sep);
661 667
662 if (!IsWebRequestEvent(event_name)) 668 if (!IsWebRequestEvent(event_name))
663 return; 669 return;
664 670
665 EventListener listener; 671 EventListener listener;
666 listener.extension_id = extension_id; 672 listener.extension_id = extension_id;
667 listener.sub_event_name = sub_event_name; 673 listener.sub_event_name = sub_event_name;
668 674
675 // It's possible for AddEventListener to fail asynchronously. In that case,
676 // the renderer to believe the listener exists, while the browser does not.
battre 2011/04/27 09:45:31 nit: grammar in "the renderer to believe"
Matt Perry 2011/04/27 19:45:59 Done.
677 // Ignore a RemoveEventListener in that case.
678 std::set<EventListener>::iterator found =
679 listeners_[profile_id][event_name].find(listener);
680 if (found == listeners_[profile_id][event_name].end())
681 return;
682
669 CHECK_EQ(listeners_[profile_id][event_name].count(listener), 1u) << 683 CHECK_EQ(listeners_[profile_id][event_name].count(listener), 1u) <<
670 "extension=" << extension_id << " event=" << event_name; 684 "extension=" << extension_id << " event=" << event_name;
671 685
672 // Unblock any request that this event listener may have been blocking. 686 // Unblock any request that this event listener may have been blocking.
673 std::set<EventListener>::iterator found =
674 listeners_[profile_id][event_name].find(listener);
675 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); 687 for (std::set<uint64>::iterator it = found->blocked_requests.begin();
676 it != found->blocked_requests.end(); ++it) { 688 it != found->blocked_requests.end(); ++it) {
677 DecrementBlockCount(*it, false, GURL()); 689 DecrementBlockCount(*it, false, GURL());
678 } 690 }
679 691
680 listeners_[profile_id][event_name].erase(listener); 692 listeners_[profile_id][event_name].erase(listener);
681 } 693 }
682 694
683 std::vector<const ExtensionWebRequestEventRouter::EventListener*> 695 std::vector<const ExtensionWebRequestEventRouter::EventListener*>
684 ExtensionWebRequestEventRouter::GetMatchingListeners( 696 ExtensionWebRequestEventRouter::GetMatchingListeners(
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 return; 784 return;
773 iter->second &= ~event_type; 785 iter->second &= ~event_type;
774 } 786 }
775 787
776 bool WebRequestAddEventListener::RunImpl() { 788 bool WebRequestAddEventListener::RunImpl() {
777 // Argument 0 is the callback, which we don't use here. 789 // Argument 0 is the callback, which we don't use here.
778 790
779 ExtensionWebRequestEventRouter::RequestFilter filter; 791 ExtensionWebRequestEventRouter::RequestFilter filter;
780 if (HasOptionalArgument(1)) { 792 if (HasOptionalArgument(1)) {
781 DictionaryValue* value = NULL; 793 DictionaryValue* value = NULL;
794 error_.clear();
782 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &value)); 795 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &value));
783 EXTENSION_FUNCTION_VALIDATE(filter.InitFromValue(*value)); 796 // Failure + an empty error string means a fatal error.
797 EXTENSION_FUNCTION_VALIDATE(filter.InitFromValue(*value, &error_) ||
798 !error_.empty());
799 if (!error_.empty())
800 return false;
784 } 801 }
785 802
786 int extra_info_spec = 0; 803 int extra_info_spec = 0;
787 if (HasOptionalArgument(2)) { 804 if (HasOptionalArgument(2)) {
788 ListValue* value = NULL; 805 ListValue* value = NULL;
789 EXTENSION_FUNCTION_VALIDATE(args_->GetList(2, &value)); 806 EXTENSION_FUNCTION_VALIDATE(args_->GetList(2, &value));
790 EXTENSION_FUNCTION_VALIDATE( 807 EXTENSION_FUNCTION_VALIDATE(
791 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( 808 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue(
792 *value, &extra_info_spec)); 809 *value, &extra_info_spec));
793 } 810 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 862
846 BrowserThread::PostTask( 863 BrowserThread::PostTask(
847 BrowserThread::IO, FROM_HERE, 864 BrowserThread::IO, FROM_HERE,
848 NewRunnableFunction( 865 NewRunnableFunction(
849 &EventHandledOnIOThread, 866 &EventHandledOnIOThread,
850 profile()->GetRuntimeId(), extension_id(), 867 profile()->GetRuntimeId(), extension_id(),
851 event_name, sub_event_name, request_id, cancel, new_url)); 868 event_name, sub_event_name, request_id, cancel, new_url));
852 869
853 return true; 870 return true;
854 } 871 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698