1 /* 2 * Copyright (C) 2010 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 */ 26 27 #include "config.h" 28 #include "weborigin/SchemeRegistry.h" 29 30 #include "wtf/MainThread.h" 31 32 namespace WebCore { 33 34 static URLSchemesMap& localURLSchemes() 35 { 36 DEFINE_STATIC_LOCAL(URLSchemesMap, localSchemes, ()); 37 38 if (localSchemes.isEmpty()) 39 localSchemes.add("file"); 40 41 return localSchemes; 42 } 43 44 static URLSchemesMap& displayIsolatedURLSchemes() 45 { 46 DEFINE_STATIC_LOCAL(URLSchemesMap, displayIsolatedSchemes, ()); 47 return displayIsolatedSchemes; 48 } 49 50 static URLSchemesMap& secureSchemes() 51 { 52 DEFINE_STATIC_LOCAL(URLSchemesMap, secureSchemes, ()); 53 54 if (secureSchemes.isEmpty()) { 55 secureSchemes.add("https"); 56 secureSchemes.add("about"); 57 secureSchemes.add("data"); 58 } 59 60 return secureSchemes; 61 } 62 63 static URLSchemesMap& schemesWithUniqueOrigins() 64 { 65 DEFINE_STATIC_LOCAL(URLSchemesMap, schemesWithUniqueOrigins, ()); 66 67 if (schemesWithUniqueOrigins.isEmpty()) { 68 schemesWithUniqueOrigins.add("about"); 69 schemesWithUniqueOrigins.add("javascript"); 70 // This is a willful violation of HTML5. 71 // See https://bugs.webkit.org/show_bug.cgi?id=11885 72 schemesWithUniqueOrigins.add("data"); 73 } 74 75 return schemesWithUniqueOrigins; 76 } 77 78 static URLSchemesMap& emptyDocumentSchemes() 79 { 80 DEFINE_STATIC_LOCAL(URLSchemesMap, emptyDocumentSchemes, ()); 81 82 if (emptyDocumentSchemes.isEmpty()) 83 emptyDocumentSchemes.add("about"); 84 85 return emptyDocumentSchemes; 86 } 87 88 static HashSet<String>& schemesForbiddenFromDomainRelaxation() 89 { 90 DEFINE_STATIC_LOCAL(HashSet<String>, schemes, ()); 91 return schemes; 92 } 93 94 static URLSchemesMap& canDisplayOnlyIfCanRequestSchemes() 95 { 96 DEFINE_STATIC_LOCAL(URLSchemesMap, canDisplayOnlyIfCanRequestSchemes, ()); 97 98 if (canDisplayOnlyIfCanRequestSchemes.isEmpty()) { 99 canDisplayOnlyIfCanRequestSchemes.add("blob"); 100 canDisplayOnlyIfCanRequestSchemes.add("filesystem"); 101 } 102 103 return canDisplayOnlyIfCanRequestSchemes; 104 } 105 106 static URLSchemesMap& notAllowingJavascriptURLsSchemes() 107 { 108 DEFINE_STATIC_LOCAL(URLSchemesMap, notAllowingJavascriptURLsSchemes, ()); 109 return notAllowingJavascriptURLsSchemes; 110 } 111 112 void SchemeRegistry::registerURLSchemeAsLocal(const String& scheme) 113 { 114 localURLSchemes().add(scheme); 115 } 116 117 void SchemeRegistry::removeURLSchemeRegisteredAsLocal(const String& scheme) 118 { 119 if (scheme == "file") 120 return; 121 localURLSchemes().remove(scheme); 122 } 123 124 const URLSchemesMap& SchemeRegistry::localSchemes() 125 { 126 return localURLSchemes(); 127 } 128 129 static URLSchemesMap& CORSEnabledSchemes() 130 { 131 // FIXME: http://bugs.webkit.org/show_bug.cgi?id=77160 132 DEFINE_STATIC_LOCAL(URLSchemesMap, CORSEnabledSchemes, ()); 133 134 if (CORSEnabledSchemes.isEmpty()) { 135 CORSEnabledSchemes.add("http"); 136 CORSEnabledSchemes.add("https"); 137 } 138 139 return CORSEnabledSchemes; 140 } 141 142 static URLSchemesMap& ContentSecurityPolicyBypassingSchemes() 143 { 144 DEFINE_STATIC_LOCAL(URLSchemesMap, schemes, ()); 145 return schemes; 146 } 147 148 bool SchemeRegistry::shouldTreatURLSchemeAsLocal(const String& scheme) 149 { 150 if (scheme.isEmpty()) 151 return false; 152 return localURLSchemes().contains(scheme); 153 } 154 155 void SchemeRegistry::registerURLSchemeAsNoAccess(const String& scheme) 156 { 157 schemesWithUniqueOrigins().add(scheme); 158 } 159 160 bool SchemeRegistry::shouldTreatURLSchemeAsNoAccess(const String& scheme) 161 { 162 if (scheme.isEmpty()) 163 return false; 164 return schemesWithUniqueOrigins().contains(scheme); 165 } 166 167 void SchemeRegistry::registerURLSchemeAsDisplayIsolated(const String& scheme) 168 { 169 displayIsolatedURLSchemes().add(scheme); 170 } 171 172 bool SchemeRegistry::shouldTreatURLSchemeAsDisplayIsolated(const String& scheme) 173 { 174 if (scheme.isEmpty()) 175 return false; 176 return displayIsolatedURLSchemes().contains(scheme); 177 } 178 179 void SchemeRegistry::registerURLSchemeAsSecure(const String& scheme) 180 { 181 secureSchemes().add(scheme); 182 } 183 184 bool SchemeRegistry::shouldTreatURLSchemeAsSecure(const String& scheme) 185 { 186 if (scheme.isEmpty()) 187 return false; 188 return secureSchemes().contains(scheme); 189 } 190 191 void SchemeRegistry::registerURLSchemeAsEmptyDocument(const String& scheme) 192 { 193 emptyDocumentSchemes().add(scheme); 194 } 195 196 bool SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(const String& scheme) 197 { 198 if (scheme.isEmpty()) 199 return false; 200 return emptyDocumentSchemes().contains(scheme); 201 } 202 203 void SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String& scheme) 204 { 205 if (scheme.isEmpty()) 206 return; 207 208 if (forbidden) 209 schemesForbiddenFromDomainRelaxation().add(scheme); 210 else 211 schemesForbiddenFromDomainRelaxation().remove(scheme); 212 } 213 214 bool SchemeRegistry::isDomainRelaxationForbiddenForURLScheme(const String& scheme) 215 { 216 if (scheme.isEmpty()) 217 return false; 218 return schemesForbiddenFromDomainRelaxation().contains(scheme); 219 } 220 221 bool SchemeRegistry::canDisplayOnlyIfCanRequest(const String& scheme) 222 { 223 if (scheme.isEmpty()) 224 return false; 225 return canDisplayOnlyIfCanRequestSchemes().contains(scheme); 226 } 227 228 void SchemeRegistry::registerAsCanDisplayOnlyIfCanRequest(const String& scheme) 229 { 230 canDisplayOnlyIfCanRequestSchemes().add(scheme); 231 } 232 233 void SchemeRegistry::registerURLSchemeAsNotAllowingJavascriptURLs(const String& scheme) 234 { 235 notAllowingJavascriptURLsSchemes().add(scheme); 236 } 237 238 bool SchemeRegistry::shouldTreatURLSchemeAsNotAllowingJavascriptURLs(const String& scheme) 239 { 240 if (scheme.isEmpty()) 241 return false; 242 return notAllowingJavascriptURLsSchemes().contains(scheme); 243 } 244 245 void SchemeRegistry::registerURLSchemeAsCORSEnabled(const String& scheme) 246 { 247 CORSEnabledSchemes().add(scheme); 248 } 249 250 bool SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(const String& scheme) 251 { 252 if (scheme.isEmpty()) 253 return false; 254 return CORSEnabledSchemes().contains(scheme); 255 } 256 257 void SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme) 258 { 259 ContentSecurityPolicyBypassingSchemes().add(scheme); 260 } 261 262 void SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme) 263 { 264 ContentSecurityPolicyBypassingSchemes().remove(scheme); 265 } 266 267 bool SchemeRegistry::schemeShouldBypassContentSecurityPolicy(const String& scheme) 268 { 269 if (scheme.isEmpty()) 270 return false; 271 return ContentSecurityPolicyBypassingSchemes().contains(scheme); 272 } 273 274 } // namespace WebCore 275