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 3 // found in the LICENSE file. 4 5 #ifndef EXTENSIONS_COMMON_URL_PATTERN_SET_H_ 6 #define EXTENSIONS_COMMON_URL_PATTERN_SET_H_ 7 8 #include <stddef.h> 9 10 #include <iosfwd> 11 #include <memory> 12 #include <set> 13 14 #include "base/macros.h" 15 #include "extensions/common/url_pattern.h" 16 17 class GURL; 18 19 namespace base { 20 class ListValue; 21 class Value; 22 } 23 24 namespace extensions { 25 26 // Represents the set of URLs an extension uses for web content. 27 class URLPatternSet { 28 public: 29 typedef std::set<URLPattern>::const_iterator const_iterator; 30 typedef std::set<URLPattern>::iterator iterator; 31 32 // Returns |set1| - |set2|. 33 static URLPatternSet CreateDifference(const URLPatternSet& set1, 34 const URLPatternSet& set2); 35 36 enum class IntersectionBehavior { 37 // For the following descriptions, consider the two URLPatternSets: 38 // Set 1: {"https://example.com/*", "https://*.google.com/*", "http://*/*"} 39 // Set 2: {"https://example.com/*", "https://google.com/maps", 40 // "*://chromium.org/*"} 41 42 // Only includes patterns that are exactly in both sets. The intersection of 43 // the two sets above is {"https://example.com/*"}, since that is the only 44 // pattern that appears exactly in each. 45 kStringComparison, 46 47 // Includes patterns that are effectively contained by both sets. The 48 // intersection of the two sets above is 49 // { 50 // "https://example.com/*" (contained exactly by each set) 51 // "https://google.com/maps" (contained exactly by set 2 and a strict 52 // subset of https://*.google.com/* in set 1) 53 // } 54 kPatternsContainedByBoth, 55 56 // Includes patterns that are contained by both sets and creates new 57 // patterns to represent the intersection of any others. The intersection of 58 // the two sets above is 59 // { 60 // "https://example.com/*" (contained exactly by each set) 61 // "https://google.com/maps" (contained exactly by set 2 and a strict 62 // subset of https://*.google.com/* in set 1) 63 // "http://chromium.org/*" (the overlap between "http://*/*" in set 1 and 64 // *://chromium.org/*" in set 2). 65 // } 66 // Note that this is the most computationally expensive - potentially 67 // O(n^2) - since it can require comparing each pattern in one set to every 68 // pattern in the other set. 69 kDetailed, 70 }; 71 72 // Returns the intersection of |set1| and |set2| according to 73 // |intersection_behavior|. 74 static URLPatternSet CreateIntersection( 75 const URLPatternSet& set1, 76 const URLPatternSet& set2, 77 IntersectionBehavior intersection_behavior); 78 79 // Returns the union of |set1| and |set2|. 80 static URLPatternSet CreateUnion(const URLPatternSet& set1, 81 const URLPatternSet& set2); 82 83 // Returns the union of all sets in |sets|. 84 static URLPatternSet CreateUnion(const std::vector<URLPatternSet>& sets); 85 86 URLPatternSet(); 87 URLPatternSet(URLPatternSet&& rhs); 88 explicit URLPatternSet(const std::set<URLPattern>& patterns); 89 ~URLPatternSet(); 90 91 URLPatternSet& operator=(URLPatternSet&& rhs); 92 bool operator==(const URLPatternSet& rhs) const; 93 94 bool is_empty() const; 95 size_t size() const; patterns()96 const std::set<URLPattern>& patterns() const { return patterns_; } begin()97 const_iterator begin() const { return patterns_.begin(); } end()98 const_iterator end() const { return patterns_.end(); } erase(iterator iter)99 iterator erase(iterator iter) { return patterns_.erase(iter); } 100 101 // Returns a copy of this URLPatternSet; not instrumented as a copy 102 // constructor to avoid accidental/unnecessary copies. 103 URLPatternSet Clone() const; 104 105 // Adds a pattern to the set. Returns true if a new pattern was inserted, 106 // false if the pattern was already in the set. 107 bool AddPattern(const URLPattern& pattern); 108 109 // Adds all patterns from |set| into this. 110 void AddPatterns(const URLPatternSet& set); 111 112 void ClearPatterns(); 113 114 // Adds a pattern based on |origin| to the set. 115 bool AddOrigin(int valid_schemes, const GURL& origin); 116 117 // Returns true if every URL that matches |set| is matched by this. In other 118 // words, if every pattern in |set| is encompassed by a pattern in this. 119 bool Contains(const URLPatternSet& set) const; 120 121 // Returns true if any pattern in this set encompasses |pattern|. 122 bool ContainsPattern(const URLPattern& pattern) const; 123 124 // Test if the extent contains a URL. 125 bool MatchesURL(const GURL& url) const; 126 127 // Test if the extent matches all URLs (for example, <all_urls>). 128 bool MatchesAllURLs() const; 129 130 bool MatchesSecurityOrigin(const GURL& origin) const; 131 132 // Returns true if there is a single URL that would be in two extents. 133 bool OverlapsWith(const URLPatternSet& other) const; 134 135 // Converts to and from Value for serialization to preferences. 136 std::unique_ptr<base::ListValue> ToValue() const; 137 bool Populate(const base::ListValue& value, 138 int valid_schemes, 139 bool allow_file_access, 140 std::string* error); 141 142 // Converts to and from a vector of strings. 143 std::unique_ptr<std::vector<std::string>> ToStringVector() const; 144 bool Populate(const std::vector<std::string>& patterns, 145 int valid_schemes, 146 bool allow_file_access, 147 std::string* error); 148 149 private: 150 // The list of URL patterns that comprise the extent. 151 std::set<URLPattern> patterns_; 152 153 DISALLOW_COPY_AND_ASSIGN(URLPatternSet); 154 }; 155 156 std::ostream& operator<<(std::ostream& out, 157 const URLPatternSet& url_pattern_set); 158 159 } // namespace extensions 160 161 #endif // EXTENSIONS_COMMON_URL_PATTERN_SET_H_ 162