OLD | NEW |
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/ScriptElementBase.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(ScriptElementBase* element, |
37 ScriptResource* resource) { | 37 ScriptResource* resource) { |
38 return new PendingScript(element, resource, TextPosition()); | 38 return new PendingScript(element, resource, TextPosition()); |
39 } | 39 } |
40 | 40 |
41 PendingScript* PendingScript::create(Element* element, | 41 PendingScript* PendingScript::create(ScriptElementBase* element, |
42 const TextPosition& startingPosition) { | 42 const TextPosition& startingPosition) { |
43 return new PendingScript(element, nullptr, startingPosition); | 43 return new PendingScript(element, 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(ScriptElementBase* element, |
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_element(element), |
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) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 ScriptElementBase* PendingScript::element() const { |
115 // As mentioned in the comment at |m_element| declaration, |m_element| | 115 // As mentioned in the comment at |m_element| declaration, |
116 // must points to the corresponding ScriptLoader's element. | 116 // |m_element| must point to the corresponding ScriptLoader's |
| 117 // client. |
117 CHECK(m_element); | 118 CHECK(m_element); |
118 return m_element.get(); | 119 return m_element.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(Resource* resource, |
| 136 ScriptElementBase* element) { |
135 DCHECK_EQ(resource->getType(), Resource::Script); | 137 DCHECK_EQ(resource->getType(), Resource::Script); |
136 ScriptResource* scriptResource = toScriptResource(resource); | 138 ScriptResource* scriptResource = toScriptResource(resource); |
137 String integrityAttr = element->fastGetAttribute(HTMLNames::integrityAttr); | 139 String integrityAttr = element->integrityAttributeValue(); |
138 | 140 |
139 // It is possible to get back a script resource with integrity metadata | 141 // 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 | 142 // for a request with an empty integrity attribute. In that case, the |
141 // integrity check should be skipped, so this check ensures that the | 143 // integrity check should be skipped, so this check ensures that the |
142 // integrity attribute isn't empty in addition to checking if the | 144 // integrity attribute isn't empty in addition to checking if the |
143 // resource has empty integrity metadata. | 145 // resource has empty integrity metadata. |
144 if (integrityAttr.isEmpty() || scriptResource->integrityMetadata().isEmpty()) | 146 if (integrityAttr.isEmpty() || scriptResource->integrityMetadata().isEmpty()) |
145 return true; | 147 return true; |
146 | 148 |
147 switch (scriptResource->integrityDisposition()) { | 149 switch (scriptResource->integrityDisposition()) { |
148 case ResourceIntegrityDisposition::Passed: | 150 case ResourceIntegrityDisposition::Passed: |
149 return true; | 151 return true; |
150 | 152 |
151 case ResourceIntegrityDisposition::Failed: | 153 case ResourceIntegrityDisposition::Failed: |
152 // TODO(jww): This should probably also generate a console | 154 // TODO(jww): This should probably also generate a console |
153 // message identical to the one produced by | 155 // message identical to the one produced by |
154 // CheckSubresourceIntegrity below. See https://crbug.com/585267. | 156 // CheckSubresourceIntegrity below. See https://crbug.com/585267. |
155 return false; | 157 return false; |
156 | 158 |
157 case ResourceIntegrityDisposition::NotChecked: { | 159 case ResourceIntegrityDisposition::NotChecked: { |
158 if (!resource->resourceBuffer()) | 160 if (!resource->resourceBuffer()) |
159 return true; | 161 return true; |
160 | 162 |
161 bool passed = SubresourceIntegrity::CheckSubresourceIntegrity( | 163 bool passed = SubresourceIntegrity::CheckSubresourceIntegrity( |
162 scriptResource->integrityMetadata(), *element, | 164 scriptResource->integrityMetadata(), element->document(), |
163 resource->resourceBuffer()->data(), | 165 resource->resourceBuffer()->data(), |
164 resource->resourceBuffer()->size(), resource->url(), *resource); | 166 resource->resourceBuffer()->size(), resource->url(), *resource); |
165 scriptResource->setIntegrityDisposition( | 167 scriptResource->setIntegrityDisposition( |
166 passed ? ResourceIntegrityDisposition::Passed | 168 passed ? ResourceIntegrityDisposition::Passed |
167 : ResourceIntegrityDisposition::Failed); | 169 : ResourceIntegrityDisposition::Failed); |
168 return passed; | 170 return passed; |
169 } | 171 } |
170 } | 172 } |
171 | 173 |
172 NOTREACHED(); | 174 NOTREACHED(); |
(...skipping 17 matching lines...) Expand all Loading... |
190 // In order to simulate the correct behavior, Blink explicitly does the SRI | 192 // In order to simulate the correct behavior, Blink explicitly does the SRI |
191 // checks here, when a PendingScript tied to a particular request is | 193 // 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), | 194 // 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 | 195 // 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 | 196 // fetch JavaScript API. In a future world where the ResourceFetcher uses |
195 // the Fetch algorithm, this should be fixed by having separate Response | 197 // the Fetch algorithm, this should be fixed by having separate Response |
196 // objects (perhaps attached to identical Resource objects) per request. | 198 // objects (perhaps attached to identical Resource objects) per request. |
197 // | 199 // |
198 // See https://crbug.com/500701 for more information. | 200 // See https://crbug.com/500701 for more information. |
199 checkState(); | 201 checkState(); |
200 if (m_element) | 202 if (m_element) { |
201 m_integrityFailure = !checkScriptResourceIntegrity(resource, m_element); | 203 m_integrityFailure = !checkScriptResourceIntegrity(resource, m_element); |
| 204 } |
202 | 205 |
203 // If script streaming is in use, the client will be notified in | 206 // If script streaming is in use, the client will be notified in |
204 // streamingFinished. | 207 // streamingFinished. |
205 if (m_streamer) | 208 if (m_streamer) |
206 m_streamer->notifyFinished(resource); | 209 m_streamer->notifyFinished(resource); |
207 else if (m_client) | 210 else if (m_client) |
208 m_client->pendingScriptFinished(this); | 211 m_client->pendingScriptFinished(this); |
209 } | 212 } |
210 | 213 |
211 void PendingScript::notifyAppendData(ScriptResource* resource) { | 214 void PendingScript::notifyAppendData(ScriptResource* resource) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 | 266 |
264 void PendingScript::onPurgeMemory() { | 267 void PendingScript::onPurgeMemory() { |
265 checkState(); | 268 checkState(); |
266 if (!m_streamer) | 269 if (!m_streamer) |
267 return; | 270 return; |
268 m_streamer->cancel(); | 271 m_streamer->cancel(); |
269 m_streamer = nullptr; | 272 m_streamer = nullptr; |
270 } | 273 } |
271 | 274 |
272 } // namespace blink | 275 } // namespace blink |
OLD | NEW |