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
17class GURL;
18
19namespace base {
20class ListValue;
21class Value;
22}
23
24namespace extensions {
25
26// Represents the set of URLs an extension uses for web content.
27class 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;
96 const std::set<URLPattern>& patterns() const { return patterns_; }
97 const_iterator begin() const { return patterns_.begin(); }
98 const_iterator end() const { return patterns_.end(); }
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
156std::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