• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Patterns used in content setting rules.
6 
7 #ifndef CHROME_COMMON_CONTENT_SETTINGS_PATTERN_H_
8 #define CHROME_COMMON_CONTENT_SETTINGS_PATTERN_H_
9 
10 #include <ostream>
11 #include <string>
12 
13 #include "base/basictypes.h"
14 #include "base/compiler_specific.h"
15 #include "base/gtest_prod_util.h"
16 
17 class GURL;
18 class Pickle;
19 class PickleIterator;
20 
21 namespace content_settings {
22 class PatternParser;
23 }
24 
25 namespace IPC {
26 class Message;
27 }
28 
29 // A pattern used in content setting rules. See |IsValid| for a description of
30 // possible patterns.
31 class ContentSettingsPattern {
32  public:
33   // Each content settings pattern describes a set of origins. Patterns, and the
34   // sets they describe, have specific relations. |Relation| describes the
35   // relation of two patterns A and B. When pattern A is compared with pattern B
36   // (A compare B) interesting relations are:
37   // - IDENTITY:
38   //   Pattern A and B are identical. The patterns are equal.
39   //
40   // - DISJOINT_ORDER_PRE:
41   //   Pattern A and B have no intersection. A and B never match the origin of
42   //   a URL at the same time. But pattern A has a higher precedence than
43   //   pattern B when patterns are sorted.
44   //
45   // - DISJOINT_ORDER_POST:
46   //   Pattern A and B have no intersection. A and B never match the origin of
47   //   a URL at the same time. But pattern A has a lower precedence than
48   //   pattern B when patterns are sorted.
49   //
50   // - SUCCESSOR:
51   //   Pattern A and B have an intersection. But pattern B has a higher
52   //   precedence than pattern A for URLs that are matched by both pattern.
53   //
54   // - PREDECESSOR:
55   //   Pattern A and B have an intersection. But pattern A has a higher
56   //   precedence than pattern B for URLs that are matched by both pattern.
57   enum Relation {
58     DISJOINT_ORDER_POST = -2,
59     SUCCESSOR = -1,
60     IDENTITY = 0,
61     PREDECESSOR = 1,
62     DISJOINT_ORDER_PRE = 2,
63   };
64 
65   struct PatternParts {
66     PatternParts();
67     ~PatternParts();
68 
69     // Lowercase string of the URL scheme to match. This string is empty if the
70     // |is_scheme_wildcard| flag is set.
71     std::string scheme;
72 
73     // True if the scheme wildcard is set.
74     bool is_scheme_wildcard;
75 
76     // Normalized string that is either of the following:
77     // - IPv4 or IPv6
78     // - hostname
79     // - domain
80     // - empty string if the |is_host_wildcard flag is set.
81     std::string host;
82 
83     // True if the domain wildcard is set.
84     bool has_domain_wildcard;
85 
86     // String with the port to match. This string is empty if the
87     // |is_port_wildcard| flag is set.
88     std::string port;
89 
90     // True if the port wildcard is set.
91     bool is_port_wildcard;
92 
93     // TODO(markusheintz): Needed for legacy reasons. Remove. Path
94     // specification. Only used for content settings pattern with a "file"
95     // scheme part.
96     std::string path;
97 
98     // True if the path wildcard is set.
99     bool is_path_wildcard;
100   };
101 
102   class BuilderInterface {
103    public:
~BuilderInterface()104     virtual ~BuilderInterface() {}
105 
106     virtual BuilderInterface* WithPort(const std::string& port) = 0;
107 
108     virtual BuilderInterface* WithPortWildcard() = 0;
109 
110     virtual BuilderInterface* WithHost(const std::string& host) = 0;
111 
112     virtual BuilderInterface* WithDomainWildcard() = 0;
113 
114     virtual BuilderInterface* WithScheme(const std::string& scheme) = 0;
115 
116     virtual BuilderInterface* WithSchemeWildcard() = 0;
117 
118     virtual BuilderInterface* WithPath(const std::string& path) = 0;
119 
120     virtual BuilderInterface* WithPathWildcard() = 0;
121 
122     virtual BuilderInterface* Invalid() = 0;
123 
124     // Returns a content settings pattern according to the current configuration
125     // of the builder.
126     virtual ContentSettingsPattern Build() = 0;
127   };
128 
129   static BuilderInterface* CreateBuilder(bool use_legacy_validate);
130 
131   // The version of the pattern format implemented.
132   static const int kContentSettingsPatternVersion;
133 
134   // The format of a domain wildcard.
135   static const char* kDomainWildcard;
136 
137   // The length of kDomainWildcard (without the trailing '\0').
138   static const size_t kDomainWildcardLength;
139 
140   // Returns a wildcard content settings pattern that matches all possible valid
141   // origins.
142   static ContentSettingsPattern Wildcard();
143 
144   // Returns a pattern that matches the scheme and host of this URL, as well as
145   // all subdomains and ports.
146   static ContentSettingsPattern FromURL(const GURL& url);
147 
148   // Returns a pattern that matches exactly this URL.
149   static ContentSettingsPattern FromURLNoWildcard(const GURL& url);
150 
151   // Returns a pattern that matches the given pattern specification.
152   // Valid patterns specifications are:
153   //   - [*.]domain.tld (matches domain.tld and all sub-domains)
154   //   - host (matches an exact hostname)
155   //   - scheme://host:port (supported schemes: http,https)
156   //   - scheme://[*.]domain.tld:port (supported schemes: http,https)
157   //   - file://path (The path has to be an absolute path and start with a '/')
158   //   - a.b.c.d (matches an exact IPv4 ip)
159   //   - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip)
160   static ContentSettingsPattern FromString(const std::string& pattern_spec);
161 
162   static ContentSettingsPattern LegacyFromString(
163       const std::string& pattern_spec);
164 
165   // Constructs an empty pattern. Empty patterns are invalid patterns. Invalid
166   // patterns match nothing.
167   ContentSettingsPattern();
168 
169   // Serializes the pattern to an IPC message or deserializes it.
170   void WriteToMessage(IPC::Message* m) const;
171   bool ReadFromMessage(const IPC::Message* m, PickleIterator* iter);
172 
173   // True if this is a valid pattern.
IsValid()174   bool IsValid() const { return is_valid_; }
175 
176   // True if |url| matches this pattern.
177   bool Matches(const GURL& url) const;
178 
179   // True if this pattern matches all hosts (i.e. it has a host wildcard).
180   bool MatchesAllHosts() const;
181 
182   // Returns a std::string representation of this pattern.
183   const std::string ToString() const;
184 
185   // Compares the pattern with a given |other| pattern and returns the
186   // |Relation| of the two patterns.
187   Relation Compare(const ContentSettingsPattern& other) const;
188 
189   // Returns true if the pattern and the |other| pattern are identical.
190   bool operator==(const ContentSettingsPattern& other) const;
191 
192   // Returns true if the pattern and the |other| pattern are not identical.
193   bool operator!=(const ContentSettingsPattern& other) const;
194 
195   // Returns true if the pattern has a lower priority than the |other| pattern.
196   bool operator<(const ContentSettingsPattern& other) const;
197 
198   // Returns true if the pattern has a higher priority than the |other| pattern.
199   bool operator>(const ContentSettingsPattern& other) const;
200 
201  private:
202   friend class content_settings::PatternParser;
203   friend class Builder;
204   FRIEND_TEST_ALL_PREFIXES(ContentSettingsPatternParserTest, SerializePatterns);
205 
206   class Builder : public BuilderInterface {
207     public:
208      explicit Builder(bool use_legacy_validate);
209      virtual ~Builder();
210 
211      // Overrides BuilderInterface
212      virtual BuilderInterface* WithPort(const std::string& port) OVERRIDE;
213 
214      virtual BuilderInterface* WithPortWildcard() OVERRIDE;
215 
216      virtual BuilderInterface* WithHost(const std::string& host) OVERRIDE;
217 
218      virtual BuilderInterface* WithDomainWildcard() OVERRIDE;
219 
220      virtual BuilderInterface* WithScheme(const std::string& scheme) OVERRIDE;
221 
222      virtual BuilderInterface* WithSchemeWildcard() OVERRIDE;
223 
224      virtual BuilderInterface* WithPath(const std::string& path) OVERRIDE;
225 
226      virtual BuilderInterface* WithPathWildcard() OVERRIDE;
227 
228      virtual BuilderInterface* Invalid() OVERRIDE;
229 
230      virtual ContentSettingsPattern Build() OVERRIDE;
231 
232     private:
233      // Canonicalizes the pattern parts so that they are ASCII only, either
234      // in original (if it was already ASCII) or punycode form. Returns true if
235      // the canonicalization was successful.
236      static bool Canonicalize(PatternParts* parts);
237 
238      // Returns true when the pattern |parts| represent a valid pattern.
239      static bool Validate(const PatternParts& parts);
240 
241      static bool LegacyValidate(const PatternParts& parts);
242 
243      bool is_valid_;
244 
245      bool use_legacy_validate_;
246 
247      PatternParts parts_;
248 
249      DISALLOW_COPY_AND_ASSIGN(Builder);
250   };
251 
252   static Relation CompareScheme(
253       const ContentSettingsPattern::PatternParts& parts,
254       const ContentSettingsPattern::PatternParts& other_parts);
255 
256   static Relation CompareHost(
257       const ContentSettingsPattern::PatternParts& parts,
258       const ContentSettingsPattern::PatternParts& other_parts);
259 
260   static Relation ComparePort(
261       const ContentSettingsPattern::PatternParts& parts,
262       const ContentSettingsPattern::PatternParts& other_parts);
263 
264   static bool Validate(const PatternParts& parts);
265 
266   ContentSettingsPattern(const PatternParts& parts, bool valid);
267 
268   PatternParts parts_;
269 
270   bool is_valid_;
271 };
272 
273 // Stream operator so ContentSettingsPattern can be used in assertion
274 // statements.
275 inline std::ostream& operator<<(
276     std::ostream& out, const ContentSettingsPattern& pattern) {
277   return out << pattern.ToString();
278 }
279 
280 #endif  // CHROME_COMMON_CONTENT_SETTINGS_PATTERN_H_
281