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