1 /*
2 * Copyright (C) 2007, 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 COMPUTER, 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 #include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
27
28 #include "base/feature_list.h"
29 #include "third_party/blink/public/common/features.h"
30 #include "third_party/blink/public/platform/web_url_request.h"
31 #include "third_party/blink/renderer/core/css/css_markup.h"
32 #include "third_party/blink/renderer/core/css/style_sheet_contents.h"
33 #include "third_party/blink/renderer/core/dom/document.h"
34 #include "third_party/blink/renderer/core/dom/node.h"
35 #include "third_party/blink/renderer/core/loader/resource/font_resource.h"
36 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
37 #include "third_party/blink/renderer/platform/fonts/font_cache.h"
38 #include "third_party/blink/renderer/platform/fonts/font_custom_platform_data.h"
39 #include "third_party/blink/renderer/platform/loader/fetch/cross_origin_attribute_value.h"
40 #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
41 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
42 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
43 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
44 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
45 #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
46 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
47
48 namespace blink {
49
IsSupportedFormat() const50 bool CSSFontFaceSrcValue::IsSupportedFormat() const {
51 // Normally we would just check the format, but in order to avoid conflicts
52 // with the old WinIE style of font-face, we will also check to see if the URL
53 // ends with .eot. If so, we'll go ahead and assume that we shouldn't load
54 // it.
55 if (format_.IsEmpty()) {
56 return absolute_resource_.StartsWithIgnoringASCIICase("data:") ||
57 !absolute_resource_.EndsWithIgnoringASCIICase(".eot");
58 }
59
60 return FontCustomPlatformData::SupportsFormat(format_);
61 }
62
CustomCSSText() const63 String CSSFontFaceSrcValue::CustomCSSText() const {
64 StringBuilder result;
65 if (IsLocal()) {
66 result.Append("local(");
67 result.Append(SerializeString(absolute_resource_));
68 result.Append(')');
69 } else {
70 result.Append(SerializeURI(specified_resource_));
71 }
72 if (!format_.IsEmpty()) {
73 result.Append(" format(");
74 result.Append(SerializeString(format_));
75 result.Append(')');
76 }
77 return result.ToString();
78 }
79
HasFailedOrCanceledSubresources() const80 bool CSSFontFaceSrcValue::HasFailedOrCanceledSubresources() const {
81 return fetched_ && fetched_->GetResource()->LoadFailedOrCanceled();
82 }
83
Fetch(ExecutionContext * context,FontResourceClient * client) const84 FontResource& CSSFontFaceSrcValue::Fetch(ExecutionContext* context,
85 FontResourceClient* client) const {
86 if (!fetched_) {
87 ResourceRequest resource_request(absolute_resource_);
88 resource_request.SetReferrerPolicy(
89 ReferrerPolicyResolveDefault(referrer_.referrer_policy));
90 resource_request.SetReferrerString(referrer_.referrer);
91 ResourceLoaderOptions options;
92 options.initiator_info.name = fetch_initiator_type_names::kCSS;
93 FetchParameters params(std::move(resource_request), options);
94 if (base::FeatureList::IsEnabled(
95 features::kWebFontsCacheAwareTimeoutAdaption)) {
96 params.SetCacheAwareLoadingEnabled(kIsCacheAwareLoadingEnabled);
97 }
98 params.SetContentSecurityCheck(should_check_content_security_policy_);
99 params.SetFromOriginDirtyStyleSheet(origin_clean_ != OriginClean::kTrue);
100 const SecurityOrigin* security_origin = context->GetSecurityOrigin();
101
102 // Local fonts are accessible from file: URLs even when
103 // allowFileAccessFromFileURLs is false.
104 if (!params.Url().IsLocalFile()) {
105 params.SetCrossOriginAccessControl(security_origin,
106 kCrossOriginAttributeAnonymous);
107 }
108 // For Workers, Fetcher is lazily loaded, so we must ensure it's available
109 // here.
110 if (auto* scope = DynamicTo<WorkerGlobalScope>(context)) {
111 scope->EnsureFetcher();
112 }
113 fetched_ = MakeGarbageCollected<FontResourceHelper>(
114 FontResource::Fetch(params, context->Fetcher(), client),
115 context->GetTaskRunner(TaskType::kInternalLoading).get());
116 } else {
117 // FIXME: CSSFontFaceSrcValue::Fetch is invoked when @font-face rule
118 // is processed by StyleResolver / StyleEngine.
119 RestoreCachedResourceIfNeeded(context);
120 if (client) {
121 client->SetResource(
122 fetched_->GetResource(),
123 context->GetTaskRunner(TaskType::kInternalLoading).get());
124 }
125 }
126 return *ToFontResource(fetched_->GetResource());
127 }
128
RestoreCachedResourceIfNeeded(ExecutionContext * context) const129 void CSSFontFaceSrcValue::RestoreCachedResourceIfNeeded(
130 ExecutionContext* context) const {
131 DCHECK(fetched_);
132 DCHECK(context);
133 DCHECK(context->Fetcher());
134
135 const String resource_url = context->CompleteURL(absolute_resource_);
136 DCHECK_EQ(should_check_content_security_policy_,
137 fetched_->GetResource()->Options().content_security_policy_option);
138 context->Fetcher()->EmulateLoadStartedForInspector(
139 fetched_->GetResource(), KURL(resource_url),
140 mojom::RequestContextType::FONT,
141 network::mojom::RequestDestination::kFont,
142 fetch_initiator_type_names::kCSS);
143 }
144
Equals(const CSSFontFaceSrcValue & other) const145 bool CSSFontFaceSrcValue::Equals(const CSSFontFaceSrcValue& other) const {
146 return is_local_ == other.is_local_ && format_ == other.format_ &&
147 specified_resource_ == other.specified_resource_ &&
148 absolute_resource_ == other.absolute_resource_;
149 }
150
151 } // namespace blink
152