1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_quota_originorpatternstring_h__ 8 #define mozilla_dom_quota_originorpatternstring_h__ 9 10 #include <utility> 11 #include "mozilla/Assertions.h" 12 #include "mozilla/OriginAttributes.h" 13 #include "mozilla/UniquePtr.h" 14 #include "mozilla/Variant.h" 15 #include "nsStringFlags.h" 16 #include "nsStringFwd.h" 17 18 namespace mozilla::dom::quota { 19 20 class OriginScope { 21 class Origin { 22 nsCString mOrigin; 23 nsCString mOriginNoSuffix; 24 UniquePtr<OriginAttributes> mAttributes; 25 26 public: Origin(const nsACString & aOrigin)27 explicit Origin(const nsACString& aOrigin) : mOrigin(aOrigin) { 28 InitMembers(); 29 } 30 Origin(const Origin & aOther)31 Origin(const Origin& aOther) 32 : mOrigin(aOther.mOrigin), 33 mOriginNoSuffix(aOther.mOriginNoSuffix), 34 mAttributes(MakeUnique<OriginAttributes>(*aOther.mAttributes)) {} 35 36 Origin(Origin&& aOther) = default; 37 GetOrigin()38 const nsACString& GetOrigin() const { return mOrigin; } 39 SetOrigin(const nsACString & aOrigin)40 void SetOrigin(const nsACString& aOrigin) { 41 mOrigin = aOrigin; 42 43 InitMembers(); 44 } 45 GetOriginNoSuffix()46 const nsACString& GetOriginNoSuffix() const { return mOriginNoSuffix; } 47 GetAttributes()48 const OriginAttributes& GetAttributes() const { 49 MOZ_ASSERT(mAttributes); 50 51 return *mAttributes; 52 } 53 54 private: InitMembers()55 void InitMembers() { 56 mAttributes = MakeUnique<OriginAttributes>(); 57 58 MOZ_ALWAYS_TRUE( 59 mAttributes->PopulateFromOrigin(mOrigin, mOriginNoSuffix)); 60 } 61 }; 62 63 class Prefix { 64 nsCString mOriginNoSuffix; 65 66 public: Prefix(const nsACString & aOriginNoSuffix)67 explicit Prefix(const nsACString& aOriginNoSuffix) 68 : mOriginNoSuffix(aOriginNoSuffix) {} 69 GetOriginNoSuffix()70 const nsCString& GetOriginNoSuffix() const { return mOriginNoSuffix; } 71 SetOriginNoSuffix(const nsACString & aOriginNoSuffix)72 void SetOriginNoSuffix(const nsACString& aOriginNoSuffix) { 73 mOriginNoSuffix = aOriginNoSuffix; 74 } 75 }; 76 77 class Pattern { 78 UniquePtr<OriginAttributesPattern> mPattern; 79 80 public: Pattern(const OriginAttributesPattern & aPattern)81 explicit Pattern(const OriginAttributesPattern& aPattern) 82 : mPattern(MakeUnique<OriginAttributesPattern>(aPattern)) {} 83 Pattern(const nsAString & aJSONPattern)84 explicit Pattern(const nsAString& aJSONPattern) 85 : mPattern(MakeUnique<OriginAttributesPattern>()) { 86 MOZ_ALWAYS_TRUE(mPattern->Init(aJSONPattern)); 87 } 88 Pattern(const Pattern & aOther)89 Pattern(const Pattern& aOther) 90 : mPattern(MakeUnique<OriginAttributesPattern>(*aOther.mPattern)) {} 91 92 Pattern(Pattern&& aOther) = default; 93 GetPattern()94 const OriginAttributesPattern& GetPattern() const { 95 MOZ_ASSERT(mPattern); 96 97 return *mPattern; 98 } 99 SetPattern(const OriginAttributesPattern & aPattern)100 void SetPattern(const OriginAttributesPattern& aPattern) { 101 mPattern = MakeUnique<OriginAttributesPattern>(aPattern); 102 } 103 GetJSONPattern()104 nsString GetJSONPattern() const { 105 MOZ_ASSERT(mPattern); 106 107 nsString result; 108 MOZ_ALWAYS_TRUE(mPattern->ToJSON(result)); 109 110 return result; 111 } 112 }; 113 114 struct Null {}; 115 116 using DataType = Variant<Origin, Prefix, Pattern, Null>; 117 118 DataType mData; 119 120 public: OriginScope()121 OriginScope() : mData(Null()) {} 122 FromOrigin(const nsACString & aOrigin)123 static OriginScope FromOrigin(const nsACString& aOrigin) { 124 return OriginScope(std::move(Origin(aOrigin))); 125 } 126 FromPrefix(const nsACString & aPrefix)127 static OriginScope FromPrefix(const nsACString& aPrefix) { 128 return OriginScope(std::move(Prefix(aPrefix))); 129 } 130 FromPattern(const OriginAttributesPattern & aPattern)131 static OriginScope FromPattern(const OriginAttributesPattern& aPattern) { 132 return OriginScope(std::move(Pattern(aPattern))); 133 } 134 FromJSONPattern(const nsAString & aJSONPattern)135 static OriginScope FromJSONPattern(const nsAString& aJSONPattern) { 136 return OriginScope(std::move(Pattern(aJSONPattern))); 137 } 138 FromNull()139 static OriginScope FromNull() { return OriginScope(std::move(Null())); } 140 IsOrigin()141 bool IsOrigin() const { return mData.is<Origin>(); } 142 IsPrefix()143 bool IsPrefix() const { return mData.is<Prefix>(); } 144 IsPattern()145 bool IsPattern() const { return mData.is<Pattern>(); } 146 IsNull()147 bool IsNull() const { return mData.is<Null>(); } 148 SetFromOrigin(const nsACString & aOrigin)149 void SetFromOrigin(const nsACString& aOrigin) { 150 mData = AsVariant(Origin(aOrigin)); 151 } 152 SetFromPrefix(const nsACString & aPrefix)153 void SetFromPrefix(const nsACString& aPrefix) { 154 mData = AsVariant(Prefix(aPrefix)); 155 } 156 SetFromPattern(const OriginAttributesPattern & aPattern)157 void SetFromPattern(const OriginAttributesPattern& aPattern) { 158 mData = AsVariant(Pattern(aPattern)); 159 } 160 SetFromJSONPattern(const nsAString & aJSONPattern)161 void SetFromJSONPattern(const nsAString& aJSONPattern) { 162 mData = AsVariant(Pattern(aJSONPattern)); 163 } 164 SetFromNull()165 void SetFromNull() { mData = AsVariant(Null()); } 166 GetOrigin()167 const nsACString& GetOrigin() const { 168 MOZ_ASSERT(IsOrigin()); 169 170 return mData.as<Origin>().GetOrigin(); 171 } 172 SetOrigin(const nsACString & aOrigin)173 void SetOrigin(const nsACString& aOrigin) { 174 MOZ_ASSERT(IsOrigin()); 175 176 mData.as<Origin>().SetOrigin(aOrigin); 177 } 178 GetOriginNoSuffix()179 const nsACString& GetOriginNoSuffix() const { 180 MOZ_ASSERT(IsOrigin() || IsPrefix()); 181 182 if (IsOrigin()) { 183 return mData.as<Origin>().GetOriginNoSuffix(); 184 } 185 return mData.as<Prefix>().GetOriginNoSuffix(); 186 } 187 SetOriginNoSuffix(const nsACString & aOriginNoSuffix)188 void SetOriginNoSuffix(const nsACString& aOriginNoSuffix) { 189 MOZ_ASSERT(IsPrefix()); 190 191 mData.as<Prefix>().SetOriginNoSuffix(aOriginNoSuffix); 192 } 193 GetPattern()194 const OriginAttributesPattern& GetPattern() const { 195 MOZ_ASSERT(IsPattern()); 196 197 return mData.as<Pattern>().GetPattern(); 198 } 199 GetJSONPattern()200 nsString GetJSONPattern() const { 201 MOZ_ASSERT(IsPattern()); 202 203 return mData.as<Pattern>().GetJSONPattern(); 204 } 205 SetPattern(const OriginAttributesPattern & aPattern)206 void SetPattern(const OriginAttributesPattern& aPattern) { 207 MOZ_ASSERT(IsPattern()); 208 209 mData.as<Pattern>().SetPattern(aPattern); 210 } 211 Matches(const OriginScope & aOther)212 bool Matches(const OriginScope& aOther) const { 213 struct Matcher { 214 const OriginScope& mThis; 215 216 explicit Matcher(const OriginScope& aThis) : mThis(aThis) {} 217 218 bool operator()(const Origin& aOther) { 219 return mThis.MatchesOrigin(aOther); 220 } 221 222 bool operator()(const Prefix& aOther) { 223 return mThis.MatchesPrefix(aOther); 224 } 225 226 bool operator()(const Pattern& aOther) { 227 return mThis.MatchesPattern(aOther); 228 } 229 230 bool operator()(const Null& aOther) { return true; } 231 }; 232 233 return aOther.mData.match(Matcher(*this)); 234 } 235 Clone()236 OriginScope Clone() { return OriginScope(mData); } 237 238 private: 239 // Move constructors OriginScope(const Origin && aOrigin)240 explicit OriginScope(const Origin&& aOrigin) : mData(aOrigin) {} 241 OriginScope(const Prefix && aPrefix)242 explicit OriginScope(const Prefix&& aPrefix) : mData(aPrefix) {} 243 OriginScope(const Pattern && aPattern)244 explicit OriginScope(const Pattern&& aPattern) : mData(aPattern) {} 245 OriginScope(const Null && aNull)246 explicit OriginScope(const Null&& aNull) : mData(aNull) {} 247 248 // Copy constructor OriginScope(const DataType & aOther)249 explicit OriginScope(const DataType& aOther) : mData(aOther) {} 250 MatchesOrigin(const Origin & aOther)251 bool MatchesOrigin(const Origin& aOther) const { 252 struct OriginMatcher { 253 const Origin& mOther; 254 255 explicit OriginMatcher(const Origin& aOther) : mOther(aOther) {} 256 257 bool operator()(const Origin& aThis) { 258 return aThis.GetOrigin().Equals(mOther.GetOrigin()); 259 } 260 261 bool operator()(const Prefix& aThis) { 262 return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix()); 263 } 264 265 bool operator()(const Pattern& aThis) { 266 return aThis.GetPattern().Matches(mOther.GetAttributes()); 267 } 268 269 bool operator()(const Null& aThis) { 270 // Null covers everything. 271 return true; 272 } 273 }; 274 275 return mData.match(OriginMatcher(aOther)); 276 } 277 MatchesPrefix(const Prefix & aOther)278 bool MatchesPrefix(const Prefix& aOther) const { 279 struct PrefixMatcher { 280 const Prefix& mOther; 281 282 explicit PrefixMatcher(const Prefix& aOther) : mOther(aOther) {} 283 284 bool operator()(const Origin& aThis) { 285 return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix()); 286 } 287 288 bool operator()(const Prefix& aThis) { 289 return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix()); 290 } 291 292 bool operator()(const Pattern& aThis) { 293 // The match will be always true here because any origin attributes 294 // pattern overlaps any origin prefix (an origin prefix targets all 295 // origin attributes). 296 return true; 297 } 298 299 bool operator()(const Null& aThis) { 300 // Null covers everything. 301 return true; 302 } 303 }; 304 305 return mData.match(PrefixMatcher(aOther)); 306 } 307 MatchesPattern(const Pattern & aOther)308 bool MatchesPattern(const Pattern& aOther) const { 309 struct PatternMatcher { 310 const Pattern& mOther; 311 312 explicit PatternMatcher(const Pattern& aOther) : mOther(aOther) {} 313 314 bool operator()(const Origin& aThis) { 315 return mOther.GetPattern().Matches(aThis.GetAttributes()); 316 } 317 318 bool operator()(const Prefix& aThis) { 319 // The match will be always true here because any origin attributes 320 // pattern overlaps any origin prefix (an origin prefix targets all 321 // origin attributes). 322 return true; 323 } 324 325 bool operator()(const Pattern& aThis) { 326 return aThis.GetPattern().Overlaps(mOther.GetPattern()); 327 } 328 329 bool operator()(const Null& aThis) { 330 // Null covers everything. 331 return true; 332 } 333 }; 334 335 PatternMatcher patternMatcher(aOther); 336 return mData.match(PatternMatcher(aOther)); 337 } 338 339 bool operator==(const OriginScope& aOther) = delete; 340 }; 341 342 } // namespace mozilla::dom::quota 343 344 #endif // mozilla_dom_quota_originorpatternstring_h__ 345