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

Side by Side Diff: extensions/common/url_pattern_set.cc

Issue 181043006: Implement correct logic for URLPatternSet set operators. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 10 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
OLDNEW
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 "extensions/common/url_pattern_set.h" 5 #include "extensions/common/url_pattern_set.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 11 matching lines...) Expand all
22 22
23 const char kInvalidURLPatternError[] = "Invalid url pattern '*'"; 23 const char kInvalidURLPatternError[] = "Invalid url pattern '*'";
24 24
25 } // namespace 25 } // namespace
26 26
27 // static 27 // static
28 void URLPatternSet::CreateDifference(const URLPatternSet& set1, 28 void URLPatternSet::CreateDifference(const URLPatternSet& set1,
29 const URLPatternSet& set2, 29 const URLPatternSet& set2,
30 URLPatternSet* out) { 30 URLPatternSet* out) {
31 out->ClearPatterns(); 31 out->ClearPatterns();
32 out->patterns_ = base::STLSetDifference<std::set<URLPattern> >( 32 for (URLPatternSet::const_iterator pattern1 = set1.patterns_.begin();
33 set1.patterns_, set2.patterns_); 33 pattern1 != set1.patterns_.end(); ++pattern1) {
34 bool keepPattern1 = true;
not at google - send to devlin 2014/02/27 21:10:46 is this whole block just if (!set.ContainsPattern
rpaquay 2014/02/28 01:46:47 Done.
35 for (URLPatternSet::const_iterator pattern2 = set2.patterns_.begin();
36 pattern2 != set2.patterns_.end(); ++pattern2) {
37 if (*pattern2 == *pattern1 || pattern2->Contains(*pattern1)) {
not at google - send to devlin 2014/02/27 21:10:46 Could you add the equality shortcut (assuming its
rpaquay 2014/02/28 01:46:47 Done.
38 keepPattern1 = false;
39 break;
40 }
41 }
42 if (keepPattern1)
43 out->InsertPattern(*pattern1);
44 }
34 } 45 }
35 46
36 // static 47 // static
37 void URLPatternSet::CreateIntersection(const URLPatternSet& set1, 48 void URLPatternSet::CreateIntersection(const URLPatternSet& set1,
38 const URLPatternSet& set2, 49 const URLPatternSet& set2,
39 URLPatternSet* out) { 50 URLPatternSet* out) {
40 out->ClearPatterns(); 51 out->ClearPatterns();
41 std::set_intersection(set1.patterns_.begin(), set1.patterns_.end(), 52 for (URLPatternSet::const_iterator pattern1 = set1.patterns_.begin();
42 set2.patterns_.begin(), set2.patterns_.end(), 53 pattern1 != set1.patterns_.end(); ++pattern1) {
43 std::inserter<std::set<URLPattern> >( 54 for (URLPatternSet::const_iterator pattern2 = set2.patterns_.begin();
44 out->patterns_, out->patterns_.begin())); 55 pattern2 != set2.patterns_.end(); ++pattern2) {
56 if (*pattern1 == *pattern2) {
57 out->InsertPattern(*pattern1);
not at google - send to devlin 2014/02/27 21:10:46 likewise above comment; this *pattern1 == *pattern
rpaquay 2014/02/28 01:46:47 Done.
58 } else if (pattern1->Contains(*pattern2)) {
59 out->InsertPattern(*pattern2);
60 } else if (pattern2->Contains(*pattern1)) {
61 out->InsertPattern(*pattern1);
62 }
63 }
64 }
45 } 65 }
46 66
47 // static 67 // static
48 void URLPatternSet::CreateUnion(const URLPatternSet& set1, 68 void URLPatternSet::CreateUnion(const URLPatternSet& set1,
49 const URLPatternSet& set2, 69 const URLPatternSet& set2,
50 URLPatternSet* out) { 70 URLPatternSet* out) {
51 out->ClearPatterns(); 71 out->ClearPatterns();
52 std::set_union(set1.patterns_.begin(), set1.patterns_.end(), 72
53 set2.patterns_.begin(), set2.patterns_.end(), 73 // Add all elements from set1 except the ones that have a "better" element in
54 std::inserter<std::set<URLPattern> >( 74 // set2.
55 out->patterns_, out->patterns_.begin())); 75 for (URLPatternSet::const_iterator pattern1 = set1.patterns_.begin();
76 pattern1 != set1.patterns_.end(); ++pattern1) {
77 bool addPattern1 = true;
78 for (URLPatternSet::const_iterator pattern2 = set2.patterns_.begin();
79 pattern2 != set2.patterns_.end(); ++pattern2) {
80 if (!(*pattern2 == *pattern1) && pattern2->Contains(*pattern1)) {
81 addPattern1 = false;
82 break;
83 }
84 }
85 if (addPattern1)
86 out->InsertPattern(*pattern1);
87 }
88
89 // Add all elements from set2 except the ones that have a "better" element in
90 // set1.
91 for (URLPatternSet::const_iterator pattern2 = set2.patterns_.begin();
92 pattern2 != set2.patterns_.end(); ++pattern2) {
93 bool addPattern2 = true;
94 for (URLPatternSet::const_iterator pattern1 = set1.patterns_.begin();
95 pattern1 != set1.patterns_.end(); ++pattern1) {
96 if (!(*pattern1 == *pattern2) && pattern1->Contains(*pattern2)) {
97 addPattern2 = false;
98 break;
99 }
100 }
101 if (addPattern2)
102 out->InsertPattern(*pattern2);
103 }
not at google - send to devlin 2014/02/27 21:10:46 see above comment(s) that apply to this function t
rpaquay 2014/02/28 01:46:47 Actually, since I updated AddPattern to do the "ri
56 } 104 }
57 105
58 // static 106 // static
59 void URLPatternSet::CreateUnion(const std::vector<URLPatternSet>& sets, 107 void URLPatternSet::CreateUnion(const std::vector<URLPatternSet>& sets,
60 URLPatternSet* out) { 108 URLPatternSet* out) {
61 out->ClearPatterns(); 109 out->ClearPatterns();
62 if (sets.empty()) 110 if (sets.empty())
63 return; 111 return;
64 112
65 // N-way union algorithm is basic O(nlog(n)) merge algorithm. 113 // N-way union algorithm is basic O(nlog(n)) merge algorithm.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 157
110 bool URLPatternSet::is_empty() const { 158 bool URLPatternSet::is_empty() const {
111 return patterns_.empty(); 159 return patterns_.empty();
112 } 160 }
113 161
114 size_t URLPatternSet::size() const { 162 size_t URLPatternSet::size() const {
115 return patterns_.size(); 163 return patterns_.size();
116 } 164 }
117 165
118 bool URLPatternSet::AddPattern(const URLPattern& pattern) { 166 bool URLPatternSet::AddPattern(const URLPattern& pattern) {
119 return patterns_.insert(pattern).second; 167 // Note: Adding a more specific pattern should be a no-op.
168 for (URLPatternSet::const_iterator it = patterns_.begin();
169 it != patterns_.end(); ++it) {
170 if (it->Contains(pattern))
171 return false;
172 }
not at google - send to devlin 2014/02/27 21:10:46 if (ContainsPattern(pattern)) return false; ?
rpaquay 2014/02/28 01:46:47 Done.
173 // Adding a more general pattern should remove the more specific patterns
174 for (URLPatternSet::const_iterator it = patterns_.begin();
175 it != patterns_.end();) {
176 if (pattern.Contains(*it))
177 patterns_.erase(it++);
178 else
179 ++it;
not at google - send to devlin 2014/02/27 21:10:46 nice
rpaquay 2014/02/28 01:46:47 http://stackoverflow.com/questions/2874441/deletin
180 }
181 return InsertPattern(pattern);
120 } 182 }
121 183
122 void URLPatternSet::AddPatterns(const URLPatternSet& set) { 184 void URLPatternSet::AddPatterns(const URLPatternSet& set) {
123 patterns_.insert(set.patterns().begin(), 185 for (URLPatternSet::const_iterator pattern = set.patterns_.begin();
124 set.patterns().end()); 186 pattern != set.patterns_.end(); ++pattern) {
187 AddPattern(*pattern);
188 }
125 } 189 }
126 190
127 void URLPatternSet::ClearPatterns() { 191 void URLPatternSet::ClearPatterns() {
128 patterns_.clear(); 192 patterns_.clear();
129 } 193 }
130 194
131 bool URLPatternSet::Contains(const URLPatternSet& other) const { 195 bool URLPatternSet::Contains(const URLPatternSet& other) const {
132 for (URLPatternSet::const_iterator it = other.begin(); 196 for (URLPatternSet::const_iterator it = other.begin();
133 it != other.end(); ++it) { 197 it != other.end(); ++it) {
134 if (!ContainsPattern(*it)) 198 if (!ContainsPattern(*it))
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 std::vector<std::string> patterns; 286 std::vector<std::string> patterns;
223 for (size_t i = 0; i < value.GetSize(); ++i) { 287 for (size_t i = 0; i < value.GetSize(); ++i) {
224 std::string item; 288 std::string item;
225 if (!value.GetString(i, &item)) 289 if (!value.GetString(i, &item))
226 return false; 290 return false;
227 patterns.push_back(item); 291 patterns.push_back(item);
228 } 292 }
229 return Populate(patterns, valid_schemes, allow_file_access, error); 293 return Populate(patterns, valid_schemes, allow_file_access, error);
230 } 294 }
231 295
296 bool URLPatternSet::InsertPattern(const URLPattern& pattern) {
297 return patterns_.insert(pattern).second;
298 }
299
232 } // namespace extensions 300 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698