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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 if (frame) { | 259 if (frame) { |
260 ScriptStreamer::startStreaming(m_pendingScript, frame->settings(), S
criptState::forMainWorld(frame)); | 260 ScriptStreamer::startStreaming(m_pendingScript, frame->settings(), S
criptState::forMainWorld(frame)); |
261 } | 261 } |
262 contextDocument->scriptRunner()->queueScriptForExecution(this, ScriptRun
ner::ASYNC_EXECUTION); | 262 contextDocument->scriptRunner()->queueScriptForExecution(this, ScriptRun
ner::ASYNC_EXECUTION); |
263 // Note that watchForLoad can immediately call notifyFinished. | 263 // Note that watchForLoad can immediately call notifyFinished. |
264 m_pendingScript.watchForLoad(this); | 264 m_pendingScript.watchForLoad(this); |
265 } else { | 265 } else { |
266 // Reset line numbering for nested writes. | 266 // Reset line numbering for nested writes. |
267 TextPosition position = elementDocument.isInDocumentWrite() ? TextPositi
on() : scriptStartPosition; | 267 TextPosition position = elementDocument.isInDocumentWrite() ? TextPositi
on() : scriptStartPosition; |
268 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInsert
ed) ? elementDocument.url() : KURL(); | 268 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInsert
ed) ? elementDocument.url() : KURL(); |
269 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); | 269 if (!executeScript(ScriptSourceCode(scriptContent(), scriptURL, position
))) |
| 270 return false; |
270 } | 271 } |
271 | 272 |
272 return true; | 273 return true; |
273 } | 274 } |
274 | 275 |
275 bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOptio
n defer) | 276 bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOptio
n defer) |
276 { | 277 { |
277 ASSERT(m_element); | 278 ASSERT(m_element); |
278 | 279 |
279 RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); | 280 RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); |
(...skipping 30 matching lines...) Expand all Loading... |
310 ASSERT(element); | 311 ASSERT(element); |
311 return isHTMLScriptElement(*element); | 312 return isHTMLScriptElement(*element); |
312 } | 313 } |
313 | 314 |
314 bool isSVGScriptLoader(Element* element) | 315 bool isSVGScriptLoader(Element* element) |
315 { | 316 { |
316 ASSERT(element); | 317 ASSERT(element); |
317 return isSVGScriptElement(*element); | 318 return isSVGScriptElement(*element); |
318 } | 319 } |
319 | 320 |
320 void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode, double* com
pilationFinishTime) | 321 bool ScriptLoader::executeScript(const ScriptSourceCode& sourceCode, double* com
pilationFinishTime) |
321 { | 322 { |
322 ASSERT(m_alreadyStarted); | 323 ASSERT(m_alreadyStarted); |
323 | 324 |
324 if (sourceCode.isEmpty()) | 325 if (sourceCode.isEmpty()) |
325 return; | 326 return true; |
326 | 327 |
327 RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); | 328 RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); |
328 RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocum
ent().get(); | 329 RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocum
ent().get(); |
329 if (!contextDocument) | 330 if (!contextDocument) |
330 return; | 331 return true; |
331 | 332 |
332 LocalFrame* frame = contextDocument->frame(); | 333 LocalFrame* frame = contextDocument->frame(); |
333 | 334 |
334 const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy(); | 335 const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy(); |
335 bool shouldBypassMainWorldCSP = (frame && frame->script().shouldBypassMainWo
rldCSP()) | 336 bool shouldBypassMainWorldCSP = (frame && frame->script().shouldBypassMainWo
rldCSP()) |
336 || csp->allowScriptWithNonce(m_element->fastGetAttribute(HTMLNames::nonc
eAttr)) | 337 || csp->allowScriptWithNonce(m_element->fastGetAttribute(HTMLNames::nonc
eAttr)) |
337 || csp->allowScriptWithHash(sourceCode.source()); | 338 || csp->allowScriptWithHash(sourceCode.source()); |
338 | 339 |
339 if (!m_isExternalScript && (!shouldBypassMainWorldCSP && !csp->allowInlineSc
ript(elementDocument->url(), m_startLineNumber, sourceCode.source()))) | 340 if (!m_isExternalScript && (!shouldBypassMainWorldCSP && !csp->allowInlineSc
ript(elementDocument->url(), m_startLineNumber, sourceCode.source()))) |
340 return; | 341 return true; |
341 | 342 |
342 if (m_isExternalScript) { | 343 if (m_isExternalScript) { |
343 ScriptResource* resource = m_resource ? m_resource.get() : sourceCode.re
source(); | 344 ScriptResource* resource = m_resource ? m_resource.get() : sourceCode.re
source(); |
344 if (resource && !resource->mimeTypeAllowedByNosniff()) { | 345 if (resource && !resource->mimeTypeAllowedByNosniff()) { |
345 contextDocument->addConsoleMessage(ConsoleMessage::create(SecurityMe
ssageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->u
rl().elidedString() + "' because its MIME type ('" + resource->mimeType() + "')
is not executable, and strict MIME type checking is enabled.")); | 346 contextDocument->addConsoleMessage(ConsoleMessage::create(SecurityMe
ssageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->u
rl().elidedString() + "' because its MIME type ('" + resource->mimeType() + "')
is not executable, and strict MIME type checking is enabled.")); |
346 return; | 347 return true; |
347 } | 348 } |
348 | 349 |
349 if (resource && resource->mimeType().lower().startsWith("image/")) { | 350 if (resource && resource->mimeType().lower().startsWith("image/")) { |
350 contextDocument->addConsoleMessage(ConsoleMessage::create(SecurityMe
ssageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->u
rl().elidedString() + "' because its MIME type ('" + resource->mimeType() + "')
is not executable.")); | 351 contextDocument->addConsoleMessage(ConsoleMessage::create(SecurityMe
ssageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->u
rl().elidedString() + "' because its MIME type ('" + resource->mimeType() + "')
is not executable.")); |
351 UseCounter::count(frame, UseCounter::BlockedSniffingImageToScript); | 352 UseCounter::count(frame, UseCounter::BlockedSniffingImageToScript); |
352 return; | 353 return true; |
353 } | 354 } |
354 } | 355 } |
355 | 356 |
356 // FIXME: Can this be moved earlier in the function? | 357 // FIXME: Can this be moved earlier in the function? |
357 // Why are we ever attempting to execute scripts without a frame? | 358 // Why are we ever attempting to execute scripts without a frame? |
358 if (!frame) | 359 if (!frame) |
359 return; | 360 return true; |
360 | 361 |
361 AccessControlStatus corsCheck = NotSharableCrossOrigin; | 362 AccessControlStatus corsCheck = NotSharableCrossOrigin; |
362 if (!m_isExternalScript || (sourceCode.resource() && sourceCode.resource()->
passesAccessControlCheck(&m_element->document(), m_element->document().securityO
rigin()))) | 363 if (!m_isExternalScript || (sourceCode.resource() && sourceCode.resource()->
passesAccessControlCheck(&m_element->document(), m_element->document().securityO
rigin()))) |
363 corsCheck = SharableCrossOrigin; | 364 corsCheck = SharableCrossOrigin; |
364 | 365 |
365 if (m_isExternalScript) { | 366 if (m_isExternalScript) { |
366 const KURL resourceUrl = sourceCode.resource()->resourceRequest().url(); | 367 const KURL resourceUrl = sourceCode.resource()->resourceRequest().url(); |
367 if (!SubresourceIntegrity::CheckSubresourceIntegrity(*m_element, sourceC
ode.source(), sourceCode.resource()->url(), sourceCode.resource()->mimeType(), *
sourceCode.resource())) { | 368 if (!SubresourceIntegrity::CheckSubresourceIntegrity(*m_element, sourceC
ode.source(), sourceCode.resource()->url(), sourceCode.resource()->mimeType(), *
sourceCode.resource())) { |
368 return; | 369 return false; |
369 } | 370 } |
370 } | 371 } |
371 | 372 |
372 const bool isImportedScript = contextDocument != elementDocument; | 373 const bool isImportedScript = contextDocument != elementDocument; |
373 // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-blo
ck step 2.3 | 374 // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-blo
ck step 2.3 |
374 // with additional support for HTML imports. | 375 // with additional support for HTML imports. |
375 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncremente
r(m_isExternalScript || isImportedScript ? contextDocument.get() : 0); | 376 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncremente
r(m_isExternalScript || isImportedScript ? contextDocument.get() : 0); |
376 | 377 |
377 if (isHTMLScriptLoader(m_element)) | 378 if (isHTMLScriptLoader(m_element)) |
378 contextDocument->pushCurrentScript(toHTMLScriptElement(m_element)); | 379 contextDocument->pushCurrentScript(toHTMLScriptElement(m_element)); |
379 | 380 |
380 // Create a script from the script element node, using the script | 381 // Create a script from the script element node, using the script |
381 // block's source and the script block's type. | 382 // block's source and the script block's type. |
382 // Note: This is where the script is compiled and actually executed. | 383 // Note: This is where the script is compiled and actually executed. |
383 frame->script().executeScriptInMainWorld(sourceCode, corsCheck, compilationF
inishTime); | 384 frame->script().executeScriptInMainWorld(sourceCode, corsCheck, compilationF
inishTime); |
384 | 385 |
385 if (isHTMLScriptLoader(m_element)) { | 386 if (isHTMLScriptLoader(m_element)) { |
386 ASSERT(contextDocument->currentScript() == m_element); | 387 ASSERT(contextDocument->currentScript() == m_element); |
387 contextDocument->popCurrentScript(); | 388 contextDocument->popCurrentScript(); |
388 } | 389 } |
| 390 |
| 391 return true; |
389 } | 392 } |
390 | 393 |
391 void ScriptLoader::execute() | 394 void ScriptLoader::execute() |
392 { | 395 { |
393 ASSERT(!m_willBeParserExecuted); | 396 ASSERT(!m_willBeParserExecuted); |
394 ASSERT(m_pendingScript.resource()); | 397 ASSERT(m_pendingScript.resource()); |
395 bool errorOccurred = false; | 398 bool errorOccurred = false; |
396 ScriptSourceCode source = m_pendingScript.getSource(KURL(), errorOccurred); | 399 ScriptSourceCode source = m_pendingScript.getSource(KURL(), errorOccurred); |
397 RefPtrWillBeRawPtr<Element> element = m_pendingScript.releaseElementAndClear
(); | 400 RefPtrWillBeRawPtr<Element> element = m_pendingScript.releaseElementAndClear
(); |
398 ALLOW_UNUSED_LOCAL(element); | 401 ALLOW_UNUSED_LOCAL(element); |
399 if (errorOccurred) { | 402 if (errorOccurred) { |
400 dispatchErrorEvent(); | 403 dispatchErrorEvent(); |
401 } else if (!m_resource->wasCanceled()) { | 404 } else if (!m_resource->wasCanceled()) { |
402 executeScript(source); | 405 if (executeScript(source)) |
403 dispatchLoadEvent(); | 406 dispatchLoadEvent(); |
| 407 else |
| 408 dispatchErrorEvent(); |
404 } | 409 } |
405 m_resource = 0; | 410 m_resource = 0; |
406 } | 411 } |
407 | 412 |
408 void ScriptLoader::notifyFinished(Resource* resource) | 413 void ScriptLoader::notifyFinished(Resource* resource) |
409 { | 414 { |
410 ASSERT(!m_willBeParserExecuted); | 415 ASSERT(!m_willBeParserExecuted); |
411 | 416 |
412 RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); | 417 RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); |
413 RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocum
ent().get(); | 418 RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocum
ent().get(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 if (isHTMLScriptLoader(element)) | 483 if (isHTMLScriptLoader(element)) |
479 return toHTMLScriptElement(element)->loader(); | 484 return toHTMLScriptElement(element)->loader(); |
480 | 485 |
481 if (isSVGScriptLoader(element)) | 486 if (isSVGScriptLoader(element)) |
482 return toSVGScriptElement(element)->loader(); | 487 return toSVGScriptElement(element)->loader(); |
483 | 488 |
484 return 0; | 489 return 0; |
485 } | 490 } |
486 | 491 |
487 } // namespace blink | 492 } // namespace blink |
OLD | NEW |