Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(541)

Side by Side Diff: third_party/WebKit/Source/core/dom/PendingScript.cpp

Issue 2723793002: De-Element ScriptLoader (Closed)
Patch Set: De-Element ScriptLoader Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "core/dom/PendingScript.h" 26 #include "core/dom/PendingScript.h"
27 27
28 #include "bindings/core/v8/ScriptSourceCode.h" 28 #include "bindings/core/v8/ScriptSourceCode.h"
29 #include "core/dom/Element.h" 29 #include "core/dom/ScriptLoaderClient.h"
30 #include "core/frame/SubresourceIntegrity.h" 30 #include "core/frame/SubresourceIntegrity.h"
31 #include "platform/SharedBuffer.h" 31 #include "platform/SharedBuffer.h"
32 #include "wtf/CurrentTime.h" 32 #include "wtf/CurrentTime.h"
33 33
34 namespace blink { 34 namespace blink {
35 35
36 PendingScript* PendingScript::create(Element* element, 36 PendingScript* PendingScript::create(ScriptLoaderClient* scriptLoaderClient,
37 ScriptResource* resource) { 37 ScriptResource* resource) {
38 return new PendingScript(element, resource, TextPosition()); 38 return new PendingScript(scriptLoaderClient, resource, TextPosition());
39 } 39 }
40 40
41 PendingScript* PendingScript::create(Element* element, 41 PendingScript* PendingScript::create(ScriptLoaderClient* scriptLoaderClient,
42 const TextPosition& startingPosition) { 42 const TextPosition& startingPosition) {
43 return new PendingScript(element, nullptr, startingPosition); 43 return new PendingScript(scriptLoaderClient, nullptr, startingPosition);
44 } 44 }
45 45
46 PendingScript* PendingScript::createForTesting(ScriptResource* resource) { 46 PendingScript* PendingScript::createForTesting(ScriptResource* resource) {
47 return new PendingScript(nullptr, resource, TextPosition(), true); 47 return new PendingScript(nullptr, resource, TextPosition(), true);
48 } 48 }
49 49
50 PendingScript::PendingScript(Element* element, 50 PendingScript::PendingScript(ScriptLoaderClient* scriptLoaderClient,
51 ScriptResource* resource, 51 ScriptResource* resource,
52 const TextPosition& startingPosition, 52 const TextPosition& startingPosition,
53 bool isForTesting) 53 bool isForTesting)
54 : m_watchingForLoad(false), 54 : m_watchingForLoad(false),
55 m_element(element), 55 m_scriptLoaderClient(scriptLoaderClient),
56 m_startingPosition(startingPosition), 56 m_startingPosition(startingPosition),
57 m_integrityFailure(false), 57 m_integrityFailure(false),
58 m_parserBlockingLoadStartTime(0), 58 m_parserBlockingLoadStartTime(0),
59 m_client(nullptr), 59 m_client(nullptr),
60 m_isForTesting(isForTesting) { 60 m_isForTesting(isForTesting) {
61 checkState(); 61 checkState();
62 setResource(resource); 62 setResource(resource);
63 MemoryCoordinator::instance().registerClient(this); 63 MemoryCoordinator::instance().registerClient(this);
64 } 64 }
65 65
66 PendingScript::~PendingScript() {} 66 PendingScript::~PendingScript() {}
67 67
68 NOINLINE void PendingScript::checkState() const { 68 NOINLINE void PendingScript::checkState() const {
69 // TODO(hiroshige): Turn these CHECK()s into DCHECK() before going to beta. 69 // TODO(hiroshige): Turn these CHECK()s into DCHECK() before going to beta.
70 CHECK(m_isForTesting || m_element); 70 CHECK(m_isForTesting || m_scriptLoaderClient);
71 CHECK(resource() || !m_streamer); 71 CHECK(resource() || !m_streamer);
72 CHECK(!m_streamer || m_streamer->resource() == resource()); 72 CHECK(!m_streamer || m_streamer->resource() == resource());
73 } 73 }
74 74
75 void PendingScript::dispose() { 75 void PendingScript::dispose() {
76 stopWatchingForLoad(); 76 stopWatchingForLoad();
77 DCHECK(!m_client); 77 DCHECK(!m_client);
78 DCHECK(!m_watchingForLoad); 78 DCHECK(!m_watchingForLoad);
79 79
80 setResource(nullptr); 80 setResource(nullptr);
81 m_startingPosition = TextPosition::belowRangePosition(); 81 m_startingPosition = TextPosition::belowRangePosition();
82 m_integrityFailure = false; 82 m_integrityFailure = false;
83 m_parserBlockingLoadStartTime = 0; 83 m_parserBlockingLoadStartTime = 0;
84 if (m_streamer) 84 if (m_streamer)
85 m_streamer->cancel(); 85 m_streamer->cancel();
86 m_streamer = nullptr; 86 m_streamer = nullptr;
87 m_element = nullptr; 87 m_scriptLoaderClient = nullptr;
88 } 88 }
89 89
90 void PendingScript::watchForLoad(PendingScriptClient* client) { 90 void PendingScript::watchForLoad(PendingScriptClient* client) {
91 checkState(); 91 checkState();
92 92
93 DCHECK(!m_watchingForLoad); 93 DCHECK(!m_watchingForLoad);
94 // addClient() will call streamingFinished() if the load is complete. Callers 94 // addClient() will call streamingFinished() if the load is complete. Callers
95 // who do not expect to be re-entered from this call should not call 95 // who do not expect to be re-entered from this call should not call
96 // watchForLoad for a PendingScript which isReady. We also need to set 96 // watchForLoad for a PendingScript which isReady. We also need to set
97 // m_watchingForLoad early, since addClient() can result in calling 97 // m_watchingForLoad early, since addClient() can result in calling
98 // notifyFinished and further stopWatchingForLoad(). 98 // notifyFinished and further stopWatchingForLoad().
99 m_watchingForLoad = true; 99 m_watchingForLoad = true;
100 m_client = client; 100 m_client = client;
101 if (isReady()) 101 if (isReady())
102 m_client->pendingScriptFinished(this); 102 m_client->pendingScriptFinished(this);
103 } 103 }
104 104
105 void PendingScript::stopWatchingForLoad() { 105 void PendingScript::stopWatchingForLoad() {
106 if (!m_watchingForLoad) 106 if (!m_watchingForLoad)
107 return; 107 return;
108 checkState(); 108 checkState();
109 DCHECK(resource()); 109 DCHECK(resource());
110 m_client = nullptr; 110 m_client = nullptr;
111 m_watchingForLoad = false; 111 m_watchingForLoad = false;
112 } 112 }
113 113
114 Element* PendingScript::element() const { 114 ScriptLoaderClient* PendingScript::scriptLoaderClient() const {
115 // As mentioned in the comment at |m_element| declaration, |m_element| 115 // As mentioned in the comment at |m_scriptLoaderClient| declaration,
116 // must points to the corresponding ScriptLoader's element. 116 // |m_scriptLoaderClient| must point to the corresponding ScriptLoader's
117 CHECK(m_element); 117 // client.
118 return m_element.get(); 118 CHECK(m_scriptLoaderClient);
119 return m_scriptLoaderClient.get();
119 } 120 }
120 121
121 void PendingScript::streamingFinished() { 122 void PendingScript::streamingFinished() {
122 checkState(); 123 checkState();
123 DCHECK(resource()); 124 DCHECK(resource());
124 if (m_client) 125 if (m_client)
125 m_client->pendingScriptFinished(this); 126 m_client->pendingScriptFinished(this);
126 } 127 }
127 128
128 void PendingScript::markParserBlockingLoadStartTime() { 129 void PendingScript::markParserBlockingLoadStartTime() {
129 DCHECK_EQ(m_parserBlockingLoadStartTime, 0.0); 130 DCHECK_EQ(m_parserBlockingLoadStartTime, 0.0);
130 m_parserBlockingLoadStartTime = monotonicallyIncreasingTime(); 131 m_parserBlockingLoadStartTime = monotonicallyIncreasingTime();
131 } 132 }
132 133
133 // Returns true if SRI check passed. 134 // Returns true if SRI check passed.
134 static bool checkScriptResourceIntegrity(Resource* resource, Element* element) { 135 static bool checkScriptResourceIntegrity(
136 Resource* resource,
137 ScriptLoaderClient* scriptLoaderClient) {
135 DCHECK_EQ(resource->getType(), Resource::Script); 138 DCHECK_EQ(resource->getType(), Resource::Script);
136 ScriptResource* scriptResource = toScriptResource(resource); 139 ScriptResource* scriptResource = toScriptResource(resource);
137 String integrityAttr = element->fastGetAttribute(HTMLNames::integrityAttr); 140 String integrityAttr = scriptLoaderClient->integrityAttributeValue();
138 141
139 // It is possible to get back a script resource with integrity metadata 142 // It is possible to get back a script resource with integrity metadata
140 // for a request with an empty integrity attribute. In that case, the 143 // for a request with an empty integrity attribute. In that case, the
141 // integrity check should be skipped, so this check ensures that the 144 // integrity check should be skipped, so this check ensures that the
142 // integrity attribute isn't empty in addition to checking if the 145 // integrity attribute isn't empty in addition to checking if the
143 // resource has empty integrity metadata. 146 // resource has empty integrity metadata.
144 if (integrityAttr.isEmpty() || scriptResource->integrityMetadata().isEmpty()) 147 if (integrityAttr.isEmpty() || scriptResource->integrityMetadata().isEmpty())
145 return true; 148 return true;
146 149
147 switch (scriptResource->integrityDisposition()) { 150 switch (scriptResource->integrityDisposition()) {
148 case ResourceIntegrityDisposition::Passed: 151 case ResourceIntegrityDisposition::Passed:
149 return true; 152 return true;
150 153
151 case ResourceIntegrityDisposition::Failed: 154 case ResourceIntegrityDisposition::Failed:
152 // TODO(jww): This should probably also generate a console 155 // TODO(jww): This should probably also generate a console
153 // message identical to the one produced by 156 // message identical to the one produced by
154 // CheckSubresourceIntegrity below. See https://crbug.com/585267. 157 // CheckSubresourceIntegrity below. See https://crbug.com/585267.
155 return false; 158 return false;
156 159
157 case ResourceIntegrityDisposition::NotChecked: { 160 case ResourceIntegrityDisposition::NotChecked: {
158 if (!resource->resourceBuffer()) 161 if (!resource->resourceBuffer())
159 return true; 162 return true;
160 163
161 bool passed = SubresourceIntegrity::CheckSubresourceIntegrity( 164 bool passed = SubresourceIntegrity::CheckSubresourceIntegrity(
162 scriptResource->integrityMetadata(), *element, 165 scriptResource->integrityMetadata(), scriptLoaderClient->document(),
163 resource->resourceBuffer()->data(), 166 resource->resourceBuffer()->data(),
164 resource->resourceBuffer()->size(), resource->url(), *resource); 167 resource->resourceBuffer()->size(), resource->url(), *resource);
165 scriptResource->setIntegrityDisposition( 168 scriptResource->setIntegrityDisposition(
166 passed ? ResourceIntegrityDisposition::Passed 169 passed ? ResourceIntegrityDisposition::Passed
167 : ResourceIntegrityDisposition::Failed); 170 : ResourceIntegrityDisposition::Failed);
168 return passed; 171 return passed;
169 } 172 }
170 } 173 }
171 174
172 NOTREACHED(); 175 NOTREACHED();
(...skipping 17 matching lines...) Expand all
190 // In order to simulate the correct behavior, Blink explicitly does the SRI 193 // In order to simulate the correct behavior, Blink explicitly does the SRI
191 // checks here, when a PendingScript tied to a particular request is 194 // checks here, when a PendingScript tied to a particular request is
192 // finished (and in the case of a StyleSheet, at the point of execution), 195 // finished (and in the case of a StyleSheet, at the point of execution),
193 // while having proper Fetch checks in the fetch module for use in the 196 // while having proper Fetch checks in the fetch module for use in the
194 // fetch JavaScript API. In a future world where the ResourceFetcher uses 197 // fetch JavaScript API. In a future world where the ResourceFetcher uses
195 // the Fetch algorithm, this should be fixed by having separate Response 198 // the Fetch algorithm, this should be fixed by having separate Response
196 // objects (perhaps attached to identical Resource objects) per request. 199 // objects (perhaps attached to identical Resource objects) per request.
197 // 200 //
198 // See https://crbug.com/500701 for more information. 201 // See https://crbug.com/500701 for more information.
199 checkState(); 202 checkState();
200 if (m_element) 203 if (m_scriptLoaderClient) {
201 m_integrityFailure = !checkScriptResourceIntegrity(resource, m_element); 204 m_integrityFailure =
205 !checkScriptResourceIntegrity(resource, m_scriptLoaderClient);
206 }
202 207
203 // If script streaming is in use, the client will be notified in 208 // If script streaming is in use, the client will be notified in
204 // streamingFinished. 209 // streamingFinished.
205 if (m_streamer) 210 if (m_streamer)
206 m_streamer->notifyFinished(resource); 211 m_streamer->notifyFinished(resource);
207 else if (m_client) 212 else if (m_client)
208 m_client->pendingScriptFinished(this); 213 m_client->pendingScriptFinished(this);
209 } 214 }
210 215
211 void PendingScript::notifyAppendData(ScriptResource* resource) { 216 void PendingScript::notifyAppendData(ScriptResource* resource) {
212 if (m_streamer) 217 if (m_streamer)
213 m_streamer->notifyAppendData(resource); 218 m_streamer->notifyAppendData(resource);
214 } 219 }
215 220
216 DEFINE_TRACE(PendingScript) { 221 DEFINE_TRACE(PendingScript) {
217 visitor->trace(m_element); 222 visitor->trace(m_scriptLoaderClient);
218 visitor->trace(m_streamer); 223 visitor->trace(m_streamer);
219 visitor->trace(m_client); 224 visitor->trace(m_client);
220 ResourceOwner<ScriptResource>::trace(visitor); 225 ResourceOwner<ScriptResource>::trace(visitor);
221 MemoryCoordinatorClient::trace(visitor); 226 MemoryCoordinatorClient::trace(visitor);
222 } 227 }
223 228
224 ScriptSourceCode PendingScript::getSource(const KURL& documentURL, 229 ScriptSourceCode PendingScript::getSource(const KURL& documentURL,
225 bool& errorOccurred) const { 230 bool& errorOccurred) const {
226 checkState(); 231 checkState();
227 232
228 errorOccurred = this->errorOccurred(); 233 errorOccurred = this->errorOccurred();
229 if (resource()) { 234 if (resource()) {
230 DCHECK(resource()->isLoaded()); 235 DCHECK(resource()->isLoaded());
231 if (m_streamer && !m_streamer->streamingSuppressed()) 236 if (m_streamer && !m_streamer->streamingSuppressed())
232 return ScriptSourceCode(m_streamer, resource()); 237 return ScriptSourceCode(m_streamer, resource());
233 return ScriptSourceCode(resource()); 238 return ScriptSourceCode(resource());
234 } 239 }
235 240
236 return ScriptSourceCode(m_element->textContent(), documentURL, 241 return ScriptSourceCode(m_scriptLoaderClient->textContent(), documentURL,
237 startingPosition()); 242 startingPosition());
238 } 243 }
239 244
240 void PendingScript::setStreamer(ScriptStreamer* streamer) { 245 void PendingScript::setStreamer(ScriptStreamer* streamer) {
241 DCHECK(!m_streamer); 246 DCHECK(!m_streamer);
242 DCHECK(!m_watchingForLoad); 247 DCHECK(!m_watchingForLoad);
243 m_streamer = streamer; 248 m_streamer = streamer;
244 checkState(); 249 checkState();
245 } 250 }
246 251
(...skipping 16 matching lines...) Expand all
263 268
264 void PendingScript::onPurgeMemory() { 269 void PendingScript::onPurgeMemory() {
265 checkState(); 270 checkState();
266 if (!m_streamer) 271 if (!m_streamer)
267 return; 272 return;
268 m_streamer->cancel(); 273 m_streamer->cancel();
269 m_streamer = nullptr; 274 m_streamer = nullptr;
270 } 275 }
271 276
272 } // namespace blink 277 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698