OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv
ed. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv
ed. |
6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> | 6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 , m_startLineNumber(WTF::OrdinalNumber::beforeFirst()) | 59 , m_startLineNumber(WTF::OrdinalNumber::beforeFirst()) |
60 , m_parserInserted(parserInserted) | 60 , m_parserInserted(parserInserted) |
61 , m_isExternalScript(false) | 61 , m_isExternalScript(false) |
62 , m_alreadyStarted(alreadyStarted) | 62 , m_alreadyStarted(alreadyStarted) |
63 , m_haveFiredLoad(false) | 63 , m_haveFiredLoad(false) |
64 , m_willBeParserExecuted(false) | 64 , m_willBeParserExecuted(false) |
65 , m_readyToBeParserExecuted(false) | 65 , m_readyToBeParserExecuted(false) |
66 , m_willExecuteWhenDocumentFinishedParsing(false) | 66 , m_willExecuteWhenDocumentFinishedParsing(false) |
67 , m_forceAsync(!parserInserted) | 67 , m_forceAsync(!parserInserted) |
68 , m_willExecuteInOrder(false) | 68 , m_willExecuteInOrder(false) |
| 69 , m_isPotentiallyCORSEnabled(false) |
69 { | 70 { |
70 ASSERT(m_element); | 71 ASSERT(m_element); |
71 if (parserInserted && element->document().scriptableDocumentParser() && !ele
ment->document().isInDocumentWrite()) | 72 if (parserInserted && element->document().scriptableDocumentParser() && !ele
ment->document().isInDocumentWrite()) |
72 m_startLineNumber = element->document().scriptableDocumentParser()->line
Number(); | 73 m_startLineNumber = element->document().scriptableDocumentParser()->line
Number(); |
73 } | 74 } |
74 | 75 |
75 ScriptLoader::~ScriptLoader() | 76 ScriptLoader::~ScriptLoader() |
76 { | 77 { |
77 stopLoadRequest(); | 78 stopLoadRequest(); |
78 } | 79 } |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 m_willExecuteInOrder = true; | 235 m_willExecuteInOrder = true; |
235 contextDocument->scriptRunner()->queueScriptForExecution(this, m_resourc
e, ScriptRunner::IN_ORDER_EXECUTION); | 236 contextDocument->scriptRunner()->queueScriptForExecution(this, m_resourc
e, ScriptRunner::IN_ORDER_EXECUTION); |
236 m_resource->addClient(this); | 237 m_resource->addClient(this); |
237 } else if (client->hasSourceAttribute()) { | 238 } else if (client->hasSourceAttribute()) { |
238 contextDocument->scriptRunner()->queueScriptForExecution(this, m_resourc
e, ScriptRunner::ASYNC_EXECUTION); | 239 contextDocument->scriptRunner()->queueScriptForExecution(this, m_resourc
e, ScriptRunner::ASYNC_EXECUTION); |
239 m_resource->addClient(this); | 240 m_resource->addClient(this); |
240 } else { | 241 } else { |
241 // Reset line numbering for nested writes. | 242 // Reset line numbering for nested writes. |
242 TextPosition position = elementDocument.isInDocumentWrite() ? TextPositi
on() : scriptStartPosition; | 243 TextPosition position = elementDocument.isInDocumentWrite() ? TextPositi
on() : scriptStartPosition; |
243 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInsert
ed) ? elementDocument.url() : KURL(); | 244 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInsert
ed) ? elementDocument.url() : KURL(); |
244 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); | 245 if (!executePotentiallyCrossOriginScript(ScriptSourceCode(scriptContent(
), scriptURL, position))) |
| 246 return false; |
245 } | 247 } |
246 | 248 |
247 return true; | 249 return true; |
248 } | 250 } |
249 | 251 |
250 bool ScriptLoader::fetchScript(const String& sourceUrl) | 252 bool ScriptLoader::fetchScript(const String& sourceUrl) |
251 { | 253 { |
252 ASSERT(m_element); | 254 ASSERT(m_element); |
253 | 255 |
254 RefPtr<Document> elementDocument(m_element->document()); | 256 RefPtr<Document> elementDocument(m_element->document()); |
255 if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) | 257 if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) |
256 return false; | 258 return false; |
257 if (!m_element->inDocument() || m_element->document() != elementDocument) | 259 if (!m_element->inDocument() || m_element->document() != elementDocument) |
258 return false; | 260 return false; |
259 | 261 |
260 ASSERT(!m_resource); | 262 ASSERT(!m_resource); |
261 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { | 263 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { |
262 FetchRequest request(ResourceRequest(elementDocument->completeURL(source
Url)), m_element->localName()); | 264 FetchRequest request(ResourceRequest(elementDocument->completeURL(source
Url)), m_element->localName()); |
263 | 265 |
264 String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossori
ginAttr); | 266 String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossori
ginAttr); |
265 if (!crossOriginMode.isNull()) { | 267 if (!crossOriginMode.isNull()) { |
266 StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMo
de, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; | 268 StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMo
de, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; |
267 request.setPotentiallyCrossOriginEnabled(elementDocument->securityOr
igin(), allowCredentials); | 269 request.setCrossOriginAccessControl(elementDocument->securityOrigin(
), allowCredentials); |
| 270 m_isPotentiallyCORSEnabled = true; |
268 } | 271 } |
269 request.setCharset(scriptCharset()); | 272 request.setCharset(scriptCharset()); |
270 | 273 |
271 bool isValidScriptNonce = elementDocument->contentSecurityPolicy()->allo
wScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); | 274 bool isValidScriptNonce = elementDocument->contentSecurityPolicy()->allo
wScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); |
272 if (isValidScriptNonce) | 275 if (isValidScriptNonce) |
273 request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy); | 276 request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy); |
274 | 277 |
275 m_resource = elementDocument->fetcher()->fetchScript(request); | 278 m_resource = elementDocument->fetcher()->fetchScript(request); |
276 m_isExternalScript = true; | 279 m_isExternalScript = true; |
277 } | 280 } |
278 | 281 |
279 if (m_resource) { | 282 if (m_resource) |
280 return true; | 283 return true; |
281 } | |
282 | 284 |
283 dispatchErrorEvent(); | 285 dispatchErrorEvent(); |
284 return false; | 286 return false; |
285 } | 287 } |
286 | 288 |
287 bool isHTMLScriptLoader(Element* element) | 289 bool isHTMLScriptLoader(Element* element) |
288 { | 290 { |
289 return element->hasTagName(HTMLNames::scriptTag); | 291 return element->hasTagName(HTMLNames::scriptTag); |
290 } | 292 } |
291 | 293 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 ASSERT(resource); | 357 ASSERT(resource); |
356 if (resource->errorOccurred()) { | 358 if (resource->errorOccurred()) { |
357 dispatchErrorEvent(); | 359 dispatchErrorEvent(); |
358 } else if (!resource->wasCanceled()) { | 360 } else if (!resource->wasCanceled()) { |
359 executeScript(ScriptSourceCode(resource)); | 361 executeScript(ScriptSourceCode(resource)); |
360 dispatchLoadEvent(); | 362 dispatchLoadEvent(); |
361 } | 363 } |
362 resource->removeClient(this); | 364 resource->removeClient(this); |
363 } | 365 } |
364 | 366 |
| 367 bool ScriptLoader::executePotentiallyCrossOriginScript(const ScriptSourceCode& s
ourceCode) |
| 368 { |
| 369 if (sourceCode.resource() |
| 370 && isPotentiallyCORSEnabled() |
| 371 && !m_element->document().fetcher()->canAccess(sourceCode.resource(), Po
tentiallyCORSEnabled)) { |
| 372 dispatchErrorEvent(); |
| 373 return false; |
| 374 } |
| 375 executeScript(sourceCode); |
| 376 return true; |
| 377 } |
| 378 |
365 void ScriptLoader::notifyFinished(Resource* resource) | 379 void ScriptLoader::notifyFinished(Resource* resource) |
366 { | 380 { |
367 ASSERT(!m_willBeParserExecuted); | 381 ASSERT(!m_willBeParserExecuted); |
368 | 382 |
369 RefPtr<Document> elementDocument(m_element->document()); | 383 RefPtr<Document> elementDocument(m_element->document()); |
370 RefPtr<Document> contextDocument = elementDocument->contextDocument().get(); | 384 RefPtr<Document> contextDocument = elementDocument->contextDocument().get(); |
371 if (!contextDocument) | 385 if (!contextDocument) |
372 return; | 386 return; |
373 | 387 |
374 // Resource possibly invokes this notifyFinished() more than | 388 // Resource possibly invokes this notifyFinished() more than |
375 // once because ScriptLoader doesn't unsubscribe itself from | 389 // once because ScriptLoader doesn't unsubscribe itself from |
376 // Resource here and does it in execute() instead. | 390 // Resource here and does it in execute() instead. |
377 // We use m_resource to check if this function is already called. | 391 // We use m_resource to check if this function is already called. |
378 ASSERT_UNUSED(resource, resource == m_resource); | 392 ASSERT_UNUSED(resource, resource == m_resource); |
379 if (!m_resource) | 393 if (!m_resource) |
380 return; | 394 return; |
381 if (!elementDocument->fetcher()->canAccess(m_resource.get())) { | 395 CORSEnabled corsEnabled = isPotentiallyCORSEnabled() ? PotentiallyCORSEnable
d : NotCORSEnabled; |
| 396 if (!elementDocument->fetcher()->canAccess(m_resource.get(), corsEnabled)) { |
382 dispatchErrorEvent(); | 397 dispatchErrorEvent(); |
383 return; | 398 return; |
384 } | 399 } |
385 | 400 |
386 if (m_willExecuteInOrder) | 401 if (m_willExecuteInOrder) |
387 contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::I
N_ORDER_EXECUTION); | 402 contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::I
N_ORDER_EXECUTION); |
388 else | 403 else |
389 contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::A
SYNC_EXECUTION); | 404 contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::A
SYNC_EXECUTION); |
390 | 405 |
391 m_resource = 0; | 406 m_resource = 0; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 if (isHTMLScriptLoader(element)) | 449 if (isHTMLScriptLoader(element)) |
435 return toHTMLScriptElement(element)->loader(); | 450 return toHTMLScriptElement(element)->loader(); |
436 | 451 |
437 if (isSVGScriptLoader(element)) | 452 if (isSVGScriptLoader(element)) |
438 return toSVGScriptElement(element)->loader(); | 453 return toSVGScriptElement(element)->loader(); |
439 | 454 |
440 return 0; | 455 return 0; |
441 } | 456 } |
442 | 457 |
443 } | 458 } |
OLD | NEW |