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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: extensions/common/url_pattern_set.cc
diff --git a/extensions/common/url_pattern_set.cc b/extensions/common/url_pattern_set.cc
index 118f9ee31ead02fa1891469830b54ab90698beb1..58835a98756142d9bdfd87237e8bdbabc494c1e0 100644
--- a/extensions/common/url_pattern_set.cc
+++ b/extensions/common/url_pattern_set.cc
@@ -29,8 +29,19 @@ void URLPatternSet::CreateDifference(const URLPatternSet& set1,
const URLPatternSet& set2,
URLPatternSet* out) {
out->ClearPatterns();
- out->patterns_ = base::STLSetDifference<std::set<URLPattern> >(
- set1.patterns_, set2.patterns_);
+ for (URLPatternSet::const_iterator pattern1 = set1.patterns_.begin();
+ pattern1 != set1.patterns_.end(); ++pattern1) {
+ 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.
+ for (URLPatternSet::const_iterator pattern2 = set2.patterns_.begin();
+ pattern2 != set2.patterns_.end(); ++pattern2) {
+ 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.
+ keepPattern1 = false;
+ break;
+ }
+ }
+ if (keepPattern1)
+ out->InsertPattern(*pattern1);
+ }
}
// static
@@ -38,10 +49,19 @@ void URLPatternSet::CreateIntersection(const URLPatternSet& set1,
const URLPatternSet& set2,
URLPatternSet* out) {
out->ClearPatterns();
- std::set_intersection(set1.patterns_.begin(), set1.patterns_.end(),
- set2.patterns_.begin(), set2.patterns_.end(),
- std::inserter<std::set<URLPattern> >(
- out->patterns_, out->patterns_.begin()));
+ for (URLPatternSet::const_iterator pattern1 = set1.patterns_.begin();
+ pattern1 != set1.patterns_.end(); ++pattern1) {
+ for (URLPatternSet::const_iterator pattern2 = set2.patterns_.begin();
+ pattern2 != set2.patterns_.end(); ++pattern2) {
+ if (*pattern1 == *pattern2) {
+ 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.
+ } else if (pattern1->Contains(*pattern2)) {
+ out->InsertPattern(*pattern2);
+ } else if (pattern2->Contains(*pattern1)) {
+ out->InsertPattern(*pattern1);
+ }
+ }
+ }
}
// static
@@ -49,10 +69,38 @@ void URLPatternSet::CreateUnion(const URLPatternSet& set1,
const URLPatternSet& set2,
URLPatternSet* out) {
out->ClearPatterns();
- std::set_union(set1.patterns_.begin(), set1.patterns_.end(),
- set2.patterns_.begin(), set2.patterns_.end(),
- std::inserter<std::set<URLPattern> >(
- out->patterns_, out->patterns_.begin()));
+
+ // Add all elements from set1 except the ones that have a "better" element in
+ // set2.
+ for (URLPatternSet::const_iterator pattern1 = set1.patterns_.begin();
+ pattern1 != set1.patterns_.end(); ++pattern1) {
+ bool addPattern1 = true;
+ for (URLPatternSet::const_iterator pattern2 = set2.patterns_.begin();
+ pattern2 != set2.patterns_.end(); ++pattern2) {
+ if (!(*pattern2 == *pattern1) && pattern2->Contains(*pattern1)) {
+ addPattern1 = false;
+ break;
+ }
+ }
+ if (addPattern1)
+ out->InsertPattern(*pattern1);
+ }
+
+ // Add all elements from set2 except the ones that have a "better" element in
+ // set1.
+ for (URLPatternSet::const_iterator pattern2 = set2.patterns_.begin();
+ pattern2 != set2.patterns_.end(); ++pattern2) {
+ bool addPattern2 = true;
+ for (URLPatternSet::const_iterator pattern1 = set1.patterns_.begin();
+ pattern1 != set1.patterns_.end(); ++pattern1) {
+ if (!(*pattern1 == *pattern2) && pattern1->Contains(*pattern2)) {
+ addPattern2 = false;
+ break;
+ }
+ }
+ if (addPattern2)
+ out->InsertPattern(*pattern2);
+ }
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
}
// static
@@ -116,12 +164,28 @@ size_t URLPatternSet::size() const {
}
bool URLPatternSet::AddPattern(const URLPattern& pattern) {
- return patterns_.insert(pattern).second;
+ // Note: Adding a more specific pattern should be a no-op.
+ for (URLPatternSet::const_iterator it = patterns_.begin();
+ it != patterns_.end(); ++it) {
+ if (it->Contains(pattern))
+ return false;
+ }
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.
+ // Adding a more general pattern should remove the more specific patterns
+ for (URLPatternSet::const_iterator it = patterns_.begin();
+ it != patterns_.end();) {
+ if (pattern.Contains(*it))
+ patterns_.erase(it++);
+ else
+ ++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
+ }
+ return InsertPattern(pattern);
}
void URLPatternSet::AddPatterns(const URLPatternSet& set) {
- patterns_.insert(set.patterns().begin(),
- set.patterns().end());
+ for (URLPatternSet::const_iterator pattern = set.patterns_.begin();
+ pattern != set.patterns_.end(); ++pattern) {
+ AddPattern(*pattern);
+ }
}
void URLPatternSet::ClearPatterns() {
@@ -229,4 +293,8 @@ bool URLPatternSet::Populate(const base::ListValue& value,
return Populate(patterns, valid_schemes, allow_file_access, error);
}
+bool URLPatternSet::InsertPattern(const URLPattern& pattern) {
+ return patterns_.insert(pattern).second;
+}
+
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698