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: 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. 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