bool MediaElementSession::wirelessVideoPlaybackDisabled(const HTMLMediaElement& element) const { Settings* settings = element.document().settings(); if (!settings || !settings->allowsAirPlayForMediaPlayback()) { LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning TRUE because of settings"); return true; } if (element.fastHasAttribute(HTMLNames::webkitwirelessvideoplaybackdisabledAttr)) { LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning TRUE because of attribute"); return true; } #if PLATFORM(IOS) String legacyAirplayAttributeValue = element.fastGetAttribute(HTMLNames::webkitairplayAttr); if (equalLettersIgnoringASCIICase(legacyAirplayAttributeValue, "deny")) { LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning TRUE because of legacy attribute"); return true; } if (equalLettersIgnoringASCIICase(legacyAirplayAttributeValue, "allow")) { LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning FALSE because of legacy attribute"); return false; } #endif MediaPlayer* player = element.player(); if (!player) return true; bool disabled = player->wirelessVideoPlaybackDisabled(); LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning %s because media engine says so", disabled ? "TRUE" : "FALSE"); return disabled; }
bool EventSource::responseIsValid(const ResourceResponse& response) const { // Logs to the console as a side effect. // To keep the signal-to-noise ratio low, we don't log anything if the status code is not 200. if (response.httpStatusCode() != 200) return false; if (!equalLettersIgnoringASCIICase(response.mimeType(), "text/event-stream")) { auto message = makeString("EventSource's response has a MIME type (\"", response.mimeType(), "\") that is not \"text/event-stream\". Aborting the connection."); // FIXME: Console message would be better with a source code location; where would we get that? scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, WTFMove(message)); return false; } // If we have a charset, the only allowed value is UTF-8 (case-insensitive). auto& charset = response.textEncodingName(); if (!charset.isEmpty() && !equalLettersIgnoringASCIICase(charset, "utf-8")) { auto message = makeString("EventSource's response has a charset (\"", charset, "\") that is not UTF-8. Aborting the connection."); // FIXME: Console message would be better with a source code location; where would we get that? scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, WTFMove(message)); return false; } return true; }
bool FontCustomPlatformData::supportsFormat(const String& format) { return equalLettersIgnoringASCIICase(format, "truetype") || equalLettersIgnoringASCIICase(format, "opentype") #if (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || equalLettersIgnoringASCIICase(format, "woff2") #endif || equalLettersIgnoringASCIICase(format, "woff"); }
void SchemeRegistry::removeURLSchemeRegisteredAsLocal(const String& scheme) { if (equalLettersIgnoringASCIICase(scheme, "file")) return; #if PLATFORM(COCOA) if (equalLettersIgnoringASCIICase(scheme, "applewebdata")) return; #endif localURLSchemes().remove(scheme); }
static inline bool shouldCacheSchemeIndefinitely(StringView scheme) { #if PLATFORM(COCOA) if (equalLettersIgnoringASCIICase(scheme, "applewebdata")) return true; #endif #if USE(SOUP) if (equalLettersIgnoringASCIICase(scheme, "resource")) return true; #endif return equalLettersIgnoringASCIICase(scheme, "data"); }
static Optional<bool> boolFeature(const DialogFeaturesMap& features, const char* key) { auto it = features.find(key); if (it == features.end()) return Nullopt; auto& value = it->value; return value.isNull() || value == "1" || equalLettersIgnoringASCIICase(value, "yes") || equalLettersIgnoringASCIICase(value, "on"); }
ExceptionOr<void> InternalSettings::setUserInterfaceDirectionPolicy(const String& policy) { if (!m_page) return Exception { INVALID_ACCESS_ERR }; if (equalLettersIgnoringASCIICase(policy, "content")) { settings().setUserInterfaceDirectionPolicy(UserInterfaceDirectionPolicy::Content); return { }; } if (equalLettersIgnoringASCIICase(policy, "view")) { settings().setUserInterfaceDirectionPolicy(UserInterfaceDirectionPolicy::System); return { }; } return Exception { INVALID_ACCESS_ERR }; }
ExceptionOr<void> InternalSettings::setSystemLayoutDirection(const String& direction) { if (!m_page) return Exception { INVALID_ACCESS_ERR }; if (equalLettersIgnoringASCIICase(direction, "ltr")) { settings().setSystemLayoutDirection(LTR); return { }; } if (equalLettersIgnoringASCIICase(direction, "rtl")) { settings().setSystemLayoutDirection(RTL); return { }; } return Exception { INVALID_ACCESS_ERR }; }
void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const { String message; if (equalLettersIgnoringASCIICase(name, "allow")) message = ASCIILiteral("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect."); else if (equalLettersIgnoringASCIICase(name, "options")) message = ASCIILiteral("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect."); else if (equalLettersIgnoringASCIICase(name, "policy-uri")) message = ASCIILiteral("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header."); else message = makeString("Unrecognized Content-Security-Policy directive '", name, "'.\n"); // FIXME: Why does this include a newline? logToConsole(message); }
bool ScriptElement::isScriptForEventSupported() const { String eventAttribute = eventAttributeValue(); String forAttribute = forAttributeValue(); if (!eventAttribute.isNull() && !forAttribute.isNull()) { forAttribute = stripLeadingAndTrailingHTMLSpaces(forAttribute); if (!equalLettersIgnoringASCIICase(forAttribute, "window")) return false; eventAttribute = stripLeadingAndTrailingHTMLSpaces(eventAttribute); if (!equalLettersIgnoringASCIICase(eventAttribute, "onload") && !equalLettersIgnoringASCIICase(eventAttribute, "onload()")) return false; } return true; }
static AtomicString alternateFamilyName(const AtomicString& familyName) { switch (familyName.length()) { case 5: if (equalLettersIgnoringASCIICase(familyName, "arial")) return AtomicString("Helvetica", AtomicString::ConstructFromLiteral); if (equalLettersIgnoringASCIICase(familyName, "times")) return AtomicString("Times New Roman", AtomicString::ConstructFromLiteral); break; case 7: if (equalLettersIgnoringASCIICase(familyName, "courier")) return AtomicString("Courier New", AtomicString::ConstructFromLiteral); break; #if OS(WINDOWS) // On Windows, we don't support bitmap fonts, but legacy content expects support. // Thus we allow Times New Roman as an alternative for the bitmap font MS Serif, // even if the webpage does not specify fallback. // FIXME: Seems unlikely this is still needed. If it was really needed, I think we // would need it on other platforms too. case 8: if (equalLettersIgnoringASCIICase(familyName, "ms serif")) return AtomicString("Times New Roman", AtomicString::ConstructFromLiteral); break; #endif case 9: if (equalLettersIgnoringASCIICase(familyName, "helvetica")) return AtomicString("Arial", AtomicString::ConstructFromLiteral); break; #if !OS(WINDOWS) // On Windows, Courier New is a TrueType font that is always present and // Courier is a bitmap font that we do not support. So, we don't want to map // Courier New to Courier. // FIXME: Not sure why this is harmful on Windows, since the alternative will // only be tried if Courier New is not found. case 11: if (equalLettersIgnoringASCIICase(familyName, "courier new")) return AtomicString("Courier", AtomicString::ConstructFromLiteral); break; #endif #if OS(WINDOWS) // On Windows, we don't support bitmap fonts, but legacy content expects support. // Thus we allow Microsoft Sans Serif as an alternative for the bitmap font MS Sans Serif, // even if the webpage does not specify fallback. // FIXME: Seems unlikely this is still needed. If it was really needed, I think we // would need it on other platforms too. case 13: if (equalLettersIgnoringASCIICase(familyName, "ms sans serif")) return AtomicString("Microsoft Sans Serif", AtomicString::ConstructFromLiteral); break; #endif case 15: if (equalLettersIgnoringASCIICase(familyName, "times new roman")) return AtomicString("Times", AtomicString::ConstructFromLiteral); break; } return nullAtom; }
bool MockCDM::supportsKeySystemAndMimeType(const String& keySystem, const String& mimeType) { if (!supportsKeySystem(keySystem)) return false; return equalLettersIgnoringASCIICase(mimeType, "video/mock"); }
Optional<ScriptElement::ScriptType> ScriptElement::determineScriptType(LegacyTypeSupport supportLegacyTypes) const { // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used here to maintain backwards compatibility with existing layout tests. The specific violations are: // - Allowing type=javascript. type= should only support MIME types, such as text/javascript. // - Allowing a different set of languages for language= and type=. language= supports Javascript 1.1 and 1.4-1.6, but type= does not. String type = typeAttributeValue(); String language = languageAttributeValue(); if (type.isEmpty()) { if (language.isEmpty()) return ScriptType::Classic; // Assume text/javascript. if (MIMETypeRegistry::isSupportedJavaScriptMIMEType("text/" + language)) return ScriptType::Classic; if (isLegacySupportedJavaScriptLanguage(language)) return ScriptType::Classic; return Nullopt; } if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace())) return ScriptType::Classic; if (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type)) return ScriptType::Classic; #if ENABLE(ES6_MODULES) // https://html.spec.whatwg.org/multipage/scripting.html#attr-script-type // Setting the attribute to an ASCII case-insensitive match for the string "module" means that the script is a module script. if (equalLettersIgnoringASCIICase(type, "module")) return ScriptType::Module; #endif return Nullopt; }
RefPtr<PlatformMediaResource> MediaResourceLoader::requestResource(const ResourceRequest& request, LoadOptions options) { if (!m_document) return nullptr; DataBufferingPolicy bufferingPolicy = options & LoadOption::BufferData ? WebCore::BufferData : WebCore::DoNotBufferData; RequestOriginPolicy corsPolicy = !m_crossOriginMode.isNull() ? PotentiallyCrossOriginEnabled : UseDefaultOriginRestrictionsForType; StoredCredentials allowCredentials = m_crossOriginMode.isNull() || equalLettersIgnoringASCIICase(m_crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; // FIXME: Skip Content Security Policy check if the element that inititated this request // is in a user-agent shadow tree. See <https://bugs.webkit.org/show_bug.cgi?id=155505>. CachedResourceRequest cacheRequest(request, ResourceLoaderOptions(SendCallbacks, DoNotSniffContent, bufferingPolicy, allowCredentials, DoNotAskClientForCrossOriginCredentials, ClientDidNotRequestCredentials, DoSecurityCheck, corsPolicy, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching)); if (!m_crossOriginMode.isNull()) updateRequestForAccessControl(cacheRequest.mutableResourceRequest(), m_document->securityOrigin(), allowCredentials); CachedResourceHandle<CachedRawResource> resource = m_document->cachedResourceLoader().requestMedia(cacheRequest); if (!resource) return nullptr; Ref<MediaResource> mediaResource = MediaResource::create(*this, resource); m_resources.add(mediaResource.ptr()); return WTFMove(mediaResource); }
bool TextTrackLoader::load(const URL& url, const String& crossOriginMode, bool isInitiatingElementInUserAgentShadowTree) { cancelLoad(); ASSERT(is<Document>(m_scriptExecutionContext)); Document* document = downcast<Document>(m_scriptExecutionContext); ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions(); options.setContentSecurityPolicyImposition(isInitiatingElementInUserAgentShadowTree ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck); CachedResourceRequest cueRequest(ResourceRequest(document->completeURL(url)), options); if (!crossOriginMode.isNull()) { m_crossOriginMode = crossOriginMode; StoredCredentials allowCredentials = equalLettersIgnoringASCIICase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; updateRequestForAccessControl(cueRequest.mutableResourceRequest(), document->securityOrigin(), allowCredentials); } else { // Cross-origin resources that are not suitably CORS-enabled may not load. if (!document->securityOrigin()->canRequest(url)) { corsPolicyPreventedLoad(); return false; } } m_resource = document->cachedResourceLoader().requestTextTrack(cueRequest); if (!m_resource) return false; m_resource->addClient(this); return true; }
MediaPlayer::SupportsType MediaPlayer::supportsType(const MediaEngineSupportParameters& parameters, const MediaPlayerSupportsTypeClient* client) { // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty string if type is a type that the // user agent knows it cannot render or is the type "application/octet-stream" if (parameters.type == applicationOctetStream()) return IsNotSupported; const MediaPlayerFactory* engine = bestMediaEngineForSupportParameters(parameters); if (!engine) return IsNotSupported; #if PLATFORM(COCOA) // YouTube will ask if the HTMLMediaElement canPlayType video/webm, then // video/x-flv, then finally video/mp4, and will then load a URL of the first type // in that list which returns "probably". When Perian is installed, // MediaPlayerPrivateQTKit claims to support both video/webm and video/x-flv, but // due to a bug in Perian, loading media in these formats will sometimes fail on // slow connections. <https://bugs.webkit.org/show_bug.cgi?id=86409> if (client && client->mediaPlayerNeedsSiteSpecificHacks()) { String host = client->mediaPlayerDocumentHost(); if ((host.endsWith(".youtube.com", false) || equalLettersIgnoringASCIICase(host, "youtube.com")) && (parameters.type.startsWith("video/webm", false) || parameters.type.startsWith("video/x-flv", false))) return IsNotSupported; } #else UNUSED_PARAM(client); #endif return engine->supportsTypeAndCodecs(parameters); }
void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiveName, const String& source) const { String message = makeString("The source list for Content Security Policy directive '", directiveName, "' contains an invalid source: '", source, "'. It will be ignored."); if (equalLettersIgnoringASCIICase(source, "'none'")) message = makeString(message, " Note that 'none' has no effect unless it is the only expression in the source list."); logToConsole(message); }
ExceptionOr<void> InternalSettings::setPDFImageCachingPolicy(const String& policy) { if (!m_page) return Exception { INVALID_ACCESS_ERR }; if (equalLettersIgnoringASCIICase(policy, "disabled")) settings().setPdfImageCachingPolicy(PDFImageCachingDisabled); else if (equalLettersIgnoringASCIICase(policy, "belowmemorylimit")) settings().setPdfImageCachingPolicy(PDFImageCachingBelowMemoryLimit); else if (equalLettersIgnoringASCIICase(policy, "clipboundsonly")) settings().setPdfImageCachingPolicy(PDFImageCachingClipBoundsOnly); else if (equalLettersIgnoringASCIICase(policy, "enabled")) settings().setPdfImageCachingPolicy(PDFImageCachingEnabled); else return Exception { SYNTAX_ERR }; return { }; }
ExceptionOr<void> InternalSettings::setEditingBehavior(const String& editingBehavior) { if (!m_page) return Exception { INVALID_ACCESS_ERR }; if (equalLettersIgnoringASCIICase(editingBehavior, "win")) settings().setEditingBehaviorType(EditingWindowsBehavior); else if (equalLettersIgnoringASCIICase(editingBehavior, "mac")) settings().setEditingBehaviorType(EditingMacBehavior); else if (equalLettersIgnoringASCIICase(editingBehavior, "unix")) settings().setEditingBehaviorType(EditingUnixBehavior); else if (equalLettersIgnoringASCIICase(editingBehavior, "ios")) settings().setEditingBehaviorType(EditingIOSBehavior); else return Exception { SYNTAX_ERR }; return { }; }
void WTFInitializeLogChannelStatesFromString(WTFLogChannel* channels[], size_t count, const char* logLevel) { String logLevelString = logLevel; Vector<String> components; logLevelString.split(',', components); for (size_t i = 0; i < components.size(); ++i) { String component = components[i]; WTFLogChannelState logChannelState = WTFLogChannelOn; if (component.startsWith('-')) { logChannelState = WTFLogChannelOff; component = component.substring(1); } if (equalLettersIgnoringASCIICase(component, "all")) { setStateOfAllChannels(channels, count, logChannelState); continue; } if (WTFLogChannel* channel = WTFLogChannelByName(channels, count, component.utf8().data())) channel->state = logChannelState; else WTFLogAlways("Unknown logging channel: %s", component.utf8().data()); } }
bool WebSocketHandshake::checkResponseHeaders() { const String& serverWebSocketProtocol = this->serverWebSocketProtocol(); const String& serverUpgrade = this->serverUpgrade(); const String& serverConnection = this->serverConnection(); const String& serverWebSocketAccept = this->serverWebSocketAccept(); if (serverUpgrade.isNull()) { m_failureReason = ASCIILiteral("Error during WebSocket handshake: 'Upgrade' header is missing"); return false; } if (serverConnection.isNull()) { m_failureReason = ASCIILiteral("Error during WebSocket handshake: 'Connection' header is missing"); return false; } if (serverWebSocketAccept.isNull()) { m_failureReason = ASCIILiteral("Error during WebSocket handshake: 'Sec-WebSocket-Accept' header is missing"); return false; } if (!equalLettersIgnoringASCIICase(serverUpgrade, "websocket")) { m_failureReason = ASCIILiteral("Error during WebSocket handshake: 'Upgrade' header value is not 'WebSocket'"); return false; } if (!equalLettersIgnoringASCIICase(serverConnection, "upgrade")) { m_failureReason = ASCIILiteral("Error during WebSocket handshake: 'Connection' header value is not 'Upgrade'"); return false; } if (serverWebSocketAccept != m_expectedAccept) { m_failureReason = ASCIILiteral("Error during WebSocket handshake: Sec-WebSocket-Accept mismatch"); return false; } if (!serverWebSocketProtocol.isNull()) { if (m_clientProtocol.isEmpty()) { m_failureReason = ASCIILiteral("Error during WebSocket handshake: Sec-WebSocket-Protocol mismatch"); return false; } Vector<String> result; m_clientProtocol.split(WebSocket::subprotocolSeparator(), result); if (!result.contains(serverWebSocketProtocol)) { m_failureReason = ASCIILiteral("Error during WebSocket handshake: Sec-WebSocket-Protocol mismatch"); return false; } } return true; }
PassRefPtr<BlobResourceHandle> BlobResourceHandle::createAsync(BlobData* blobData, const ResourceRequest& request, ResourceHandleClient* client) { // FIXME: Should probably call didFail() instead of blocking the load without explanation. if (!equalLettersIgnoringASCIICase(request.httpMethod(), "get")) return nullptr; return adoptRef(new BlobResourceHandle(blobData, request, client, true)); }
bool ContentSecurityPolicy::protocolMatchesSelf(const URL& url) const { #if ENABLE(CSP_NEXT) if (equalLettersIgnoringASCIICase(m_selfSourceProtocol, "http")) return url.protocolIsInHTTPFamily(); #endif return equalIgnoringASCIICase(url.protocol(), m_selfSourceProtocol); }
void CSSPreloadScanner::emitRule() { StringView rule(m_rule.data(), m_rule.size()); if (equalLettersIgnoringASCIICase(rule, "import")) { String url = parseCSSStringOrURL(m_ruleValue.data(), m_ruleValue.size()); if (!url.isEmpty()) { URL baseElementURL; // FIXME: This should be passed in from the HTMLPreloadScanner via scan(): without it we will get relative URLs wrong. // FIXME: Should this be including the charset in the preload request? m_requests->append(std::make_unique<PreloadRequest>("css", url, baseElementURL, CachedResource::CSSStyleSheet, String())); } m_state = Initial; } else if (equalLettersIgnoringASCIICase(rule, "charset")) m_state = Initial; else m_state = DoneParsingImportRules; m_rule.clear(); m_ruleValue.clear(); }
inline bool isValidCSSContentType(Element& element, const AtomicString& type) { if (type.isEmpty()) return true; // FIXME: Should MIME types really be case sensitive in XML documents? Doesn't seem like they should, // even though other things are case sensitive in that context. MIME types should never be case sensitive. // We should verify this and then remove the isHTMLElement check here. static NeverDestroyed<const AtomicString> cssContentType("text/css", AtomicString::ConstructFromLiteral); return element.isHTMLElement() ? equalLettersIgnoringASCIICase(type, "text/css") : type == cssContentType; }
void CachedResourceRequest::setAsPotentiallyCrossOrigin(const String& mode, Document& document) { ASSERT(m_options.mode == FetchOptions::Mode::NoCors); ASSERT(document.securityOrigin()); m_origin = document.securityOrigin(); if (mode.isNull()) return; m_options.mode = FetchOptions::Mode::Cors; FetchOptions::Credentials credentials = equalLettersIgnoringASCIICase(mode, "omit") ? FetchOptions::Credentials::Omit : equalLettersIgnoringASCIICase(mode, "use-credentials") ? FetchOptions::Credentials::Include : FetchOptions::Credentials::SameOrigin; m_options.credentials = credentials; m_options.allowCredentials = credentials == FetchOptions::Credentials::Include ? AllowStoredCredentials : DoNotAllowStoredCredentials; WebCore::updateRequestForAccessControl(m_resourceRequest, *document.securityOrigin(), m_options.allowCredentials); }
ExceptionOr<bool> InternalSettings::shouldDisplayTrackKind(const String& kind) { if (!m_page) return Exception { INVALID_ACCESS_ERR }; #if ENABLE(VIDEO_TRACK) auto& captionPreferences = m_page->group().captionPreferences(); if (equalLettersIgnoringASCIICase(kind, "subtitles")) return captionPreferences.userPrefersSubtitles(); if (equalLettersIgnoringASCIICase(kind, "captions")) return captionPreferences.userPrefersCaptions(); if (equalLettersIgnoringASCIICase(kind, "textdescriptions")) return captionPreferences.userPrefersTextDescriptions(); return Exception { SYNTAX_ERR }; #else UNUSED_PARAM(kind); return false; #endif }
int DatabaseAuthorizer::dropVTable(const String& tableName, const String& moduleName) { if (!allowWrite()) return SQLAuthDeny; // Allow only the FTS3 extension if (!equalLettersIgnoringASCIICase(moduleName, "fts3")) return SQLAuthDeny; return updateDeletesBasedOnTableName(tableName); }
void BlobResourceHandle::loadResourceSynchronously(BlobData* blobData, const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data) { if (!equalLettersIgnoringASCIICase(request.httpMethod(), "get")) { error = ResourceError(webKitBlobResourceDomain, methodNotAllowed, response.url(), "Request method must be GET"); return; } BlobResourceSynchronousLoader loader(error, response, data); RefPtr<BlobResourceHandle> handle = adoptRef(new BlobResourceHandle(blobData, request, &loader, false)); handle->start(); }
int DatabaseAuthorizer::createVTable(const String& tableName, const String& moduleName) { if (!allowWrite()) return SQLAuthDeny; // Allow only the FTS3 extension if (!equalLettersIgnoringASCIICase(moduleName, "fts3")) return SQLAuthDeny; m_lastActionChangedDatabase = true; return denyBasedOnTableName(tableName); }