Title: [101999] trunk
Revision
101999
Author
[email protected]
Date
2011-12-05 07:38:11 -0800 (Mon, 05 Dec 2011)

Log Message

Out-of-band text tracks may only load from same origin as the media element's Document's origin
https://bugs.webkit.org/show_bug.cgi?id=73184

Reviewed by Sam Weinig.

Source/WebCore: 

Test: http/tests/security/text-track-crossorigin.html

* html/HTMLTrackElement.cpp:
(WebCore::urlForLogging): Debug-only function for logging urls.
(WebCore::HTMLTrackElement::scheduleLoad): Call canLoadUrl() before passing control off to
    the Track.
(WebCore::HTMLTrackElement::canLoadUrl): Don't ask HTMLMediaElement to validate the url, the
    requirements for <track> are different from <video>.
(WebCore::HTMLTrackElement::didCompleteLoad): Change bool param to enum.
(WebCore::HTMLTrackElement::mediaElementCrossOriginAttribute): New, return parent 'crossorigin' 
    attribute value.
* html/HTMLTrackElement.h:

* html/LoadableTextTrack.cpp:
(WebCore::LoadableTextTrack::scheduleLoad): Add comments from the spec.
(WebCore::LoadableTextTrack::loadTimerFired): Always cancel pending loads. Let the caller know 
    if the loader refuses the url immediately.
(WebCore::LoadableTextTrack::cueLoadingStarted): The <track> deals with readyState.
(WebCore::LoadableTextTrack::cueLoadingCompleted): HTMLTrackElement::didCompleteLoad takes
    an enum, not a bool.

* loader/TextTrackLoader.cpp:
(WebCore::TextTrackLoader::corsPolicyPreventedLoad): New, log the error and set m_state.
(WebCore::TextTrackLoader::notifyFinished): Check for CORS failure.
(WebCore::TextTrackLoader::load): Take media element cross-origin attribute as a param so we
    can make the correct checks.
* loader/TextTrackLoader.h:

LayoutTests: 

* http/tests/security/resources/captions-with-access-control-headers.php: Added
* http/tests/security/resources/captions.vtt: Added.
* http/tests/security/text-track-crossorigin-expected.txt: Added.
* http/tests/security/text-track-crossorigin.html: Added.
* media/track/track-add-track-expected.txt: Updated results.
* media/track/track-add-track.html: readyState changes as soon as the track url is set.
* platform/efl/Skipped: Skip new test.
* platform/gtk/Skipped: Ditto.
* platform/mac/Skipped: Ditto.
* platform/qt/Skipped: Ditto.
* platform/win/Skipped: Ditto.
* platform/wincairo/Skipped: Ditto.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (101998 => 101999)


--- trunk/LayoutTests/ChangeLog	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/ChangeLog	2011-12-05 15:38:11 UTC (rev 101999)
@@ -1,3 +1,23 @@
+2011-12-05  Eric Carlson  <[email protected]>
+
+        Out-of-band text tracks may only load from same origin as the media element's Document's origin
+        https://bugs.webkit.org/show_bug.cgi?id=73184
+
+        Reviewed by Sam Weinig.
+
+        * http/tests/security/resources/captions-with-access-control-headers.php: Added
+        * http/tests/security/resources/captions.vtt: Added.
+        * http/tests/security/text-track-crossorigin-expected.txt: Added.
+        * http/tests/security/text-track-crossorigin.html: Added.
+        * media/track/track-add-track-expected.txt: Updated results.
+        * media/track/track-add-track.html: readyState changes as soon as the track url is set.
+        * platform/efl/Skipped: Skip new test.
+        * platform/gtk/Skipped: Ditto.
+        * platform/mac/Skipped: Ditto.
+        * platform/qt/Skipped: Ditto.
+        * platform/win/Skipped: Ditto.
+        * platform/wincairo/Skipped: Ditto.
+
 2011-12-05  Roland Steiner  <[email protected]>
 
         "Raw" pseudo selectors don't match if immediately after a child or descendant combinator

Added: trunk/LayoutTests/http/tests/security/resources/captions-with-access-control-headers.php (0 => 101999)


--- trunk/LayoutTests/http/tests/security/resources/captions-with-access-control-headers.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/captions-with-access-control-headers.php	2011-12-05 15:38:11 UTC (rev 101999)
@@ -0,0 +1,18 @@
+<?php
+
+    $origin = $_GET["origin"];
+    $credentials = $_GET["credentials"];
+
+    if ($origin)
+        header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
+    if ($credentials)
+        header("Access-Control-Allow-Credentials: true");
+    
+    $name = 'captions.vtt';
+    $fp = fopen($name, 'rb');
+    header("Content-Type: text/vtt");
+    header("Content-Length: " . filesize($name));
+    
+    fpassthru($fp);
+    exit;
+?>

Added: trunk/LayoutTests/http/tests/security/resources/captions.vtt (0 => 101999)


--- trunk/LayoutTests/http/tests/security/resources/captions.vtt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/captions.vtt	2011-12-05 15:38:11 UTC (rev 101999)
@@ -0,0 +1,13 @@
+WEBVTT FILE
+
+1
+00:00:00.000 --> 00:00:10.500
+Lorem ipsum dolor sit amet,
+
+2
+00:00:11.000 --> 00:20:00.500
+consectetuer adipiscing elit, 
+
+3
+00:00:21.000 --> 00:30:00.500
+sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

Added: trunk/LayoutTests/http/tests/security/text-track-crossorigin-expected.txt (0 => 101999)


--- trunk/LayoutTests/http/tests/security/text-track-crossorigin-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/text-track-crossorigin-expected.txt	2011-12-05 15:38:11 UTC (rev 101999)
@@ -0,0 +1,34 @@
+CONSOLE MESSAGE: line 1: Cross-origin text track load denied by Cross-Origin Resource Sharing policy.
+CONSOLE MESSAGE: line 1: Cross-origin text track load denied by Cross-Origin Resource Sharing policy.
+Tests loading cross-domain <track>.
+
+Loading without Access-Control-Allow-Origin header, no "crossorigin" attribute on <video>
+EVENT(error)
+PASS: shouldLoad should be 'false' and is.
+PASS: event.target should be '[object HTMLTrackElement]' and is.
+PASS: trackElement.readyState should be '3' and is.
+
+
+Loading without Access-Control-Allow-Origin header, setting video.crossorigin to "anonymous"
+EVENT(error)
+PASS: shouldLoad should be 'false' and is.
+PASS: event.target should be '[object HTMLTrackElement]' and is.
+PASS: trackElement.readyState should be '3' and is.
+
+
+Loading with Access-Control-Allow-Origin header, leaving video.crossorigin as "anonymous"
+EVENT(load)
+PASS: shouldLoad should be 'true' and is.
+PASS: event.target should be '[object HTMLTrackElement]' and is.
+PASS: trackElement.readyState should be '2' and is.
+
+
+Loading with Access-Control-Allow-Origin and Access-Control-Allow-Credentials headers, setting video.crossorigin to "use-credentials"
+EVENT(load)
+PASS: shouldLoad should be 'true' and is.
+PASS: event.target should be '[object HTMLTrackElement]' and is.
+PASS: trackElement.readyState should be '2' and is.
+
+
+END OF TEST
+

Added: trunk/LayoutTests/http/tests/security/text-track-crossorigin.html (0 => 101999)


--- trunk/LayoutTests/http/tests/security/text-track-crossorigin.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/text-track-crossorigin.html	2011-12-05 15:38:11 UTC (rev 101999)
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script src=""
+        <script>
+
+            var shouldLoad = false;
+            var counter = 0;
+
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+
+            function log(msg)
+            {
+                document.getElementById('console').innerHTML += msg + "<br>";
+            }
+
+            function trackLoaded()
+            {
+                log('EVENT(load)');
+                shouldBe('shouldLoad', true);
+
+                trackElement = document.querySelectorAll('track')[0];
+                videoElement = document.querySelectorAll('video')[0];
+                shouldBe('event.target', trackElement);
+                shouldBe('trackElement.readyState', HTMLTrackElement.LOADED);
+
+                log('<br>');
+                switch(counter) {
+                case 2:
+                    log('Loading <b>with</b> Access-Control-Allow-Origin and Access-Control-Allow-Credentials headers, setting video.crossorigin to "use-credentials"');
+                    url = ""
+                    trackElement.setAttribute('crossorigin', 'use-credentials');
+                    trackElement.setAttribute('src', url);
+                    ++counter;
+                    break;
+
+                case 3:
+                    log("END OF TEST");
+                    if (window.layoutTestController)
+                        layoutTestController.notifyDone();
+                }
+            }
+
+            function trackError()
+            {
+                log('EVENT(error)');
+                shouldBe('shouldLoad', false);
+
+                trackElement = document.querySelectorAll('track')[0];
+                videoElement = document.querySelectorAll('video')[0];
+                shouldBe('event.target', trackElement);
+                shouldBe('trackElement.readyState', HTMLTrackElement.ERROR);
+
+                log('<br>');
+                switch(counter) {
+                case 0:
+                    log('Loading <b>without</b> Access-Control-Allow-Origin header, setting video.crossorigin to "anonymous"');
+                    url = "" + counter;
+                    videoElement.setAttribute('crossorigin', 'anonymous');
+                    trackElement.removeAttribute('src');
+                    trackElement.setAttribute('src', url);
+                    ++counter;
+                    break;
+
+                case 1:
+                    log('Loading <b>with</b> Access-Control-Allow-Origin header, leaving video.crossorigin as "anonymous"');
+                    url = ""
+                    trackElement.setAttribute('src', url);
+                    shouldLoad = true;
+                    ++counter;
+                    break;
+                }
+
+            }
+
+            function start()
+            {
+                trackElement = document.querySelectorAll('track')[0];
+                log('Loading <b>without</b> Access-Control-Allow-Origin header, no "crossorigin" attribute on &lt;video&gt;');
+                var url = ""
+                trackElement.setAttribute('src', url);
+            }
+
+        </script>
+    </head>
+    <body _onload_="start()">
+        <p>Tests loading cross-domain &lt;track&gt;.</p>
+        <video >
+            <track kind="captions" _onerror_="trackError()" _onload_="trackLoaded()" >
+        </video>
+        <div id="console"></div>
+    </body>
+</html>

Modified: trunk/LayoutTests/media/track/track-add-track-expected.txt (101998 => 101999)


--- trunk/LayoutTests/media/track/track-add-track-expected.txt	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/media/track/track-add-track-expected.txt	2011-12-05 15:38:11 UTC (rev 101999)
@@ -5,7 +5,7 @@
 RUN(video.appendChild(trackElement))
 RUN(trackElement.src = '')
 EXPECTED (video.textTracks.length == '1') OK
-EXPECTED (trackElement.readyState == '0') OK
+EXPECTED (trackElement.readyState == '1') OK
 EVENT(addtrack)
 EXPECTED (event.target == '[object TextTrackList]') OK
 EXPECTED (event instanceof window.TrackEvent == 'true') OK

Modified: trunk/LayoutTests/media/track/track-add-track.html (101998 => 101999)


--- trunk/LayoutTests/media/track/track-add-track.html	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/media/track/track-add-track.html	2011-12-05 15:38:11 UTC (rev 101999)
@@ -42,7 +42,7 @@
 
                 run("trackElement.src = ''");
                 testExpected("video.textTracks.length", 1);
-                testExpected("trackElement.readyState", HTMLTrackElement.NONE);
+                testExpected("trackElement.readyState", HTMLTrackElement.LOADING);
             }
 
         </script>

Modified: trunk/LayoutTests/platform/efl/Skipped (101998 => 101999)


--- trunk/LayoutTests/platform/efl/Skipped	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/platform/efl/Skipped	2011-12-05 15:38:11 UTC (rev 101999)
@@ -1098,6 +1098,8 @@
 
 # The EFL port has no support for <track> with *.vtt
 media/track
+fast/events/constructors/track-event-constructor.html
+http/tests/security/text-track-crossorigin.html
 
 # The EFL port has no support for loading a PDF as an image
 fast/images/pdf-as-background.html

Modified: trunk/LayoutTests/platform/gtk/Skipped (101998 => 101999)


--- trunk/LayoutTests/platform/gtk/Skipped	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/platform/gtk/Skipped	2011-12-05 15:38:11 UTC (rev 101999)
@@ -368,6 +368,7 @@
 # VIDEO_TRACK is disabled for now
 media/track
 fast/events/constructors/track-event-constructor.html
+http/tests/security/text-track-crossorigin.html
 
 # CSS Filters is disabled
 css3/filters

Modified: trunk/LayoutTests/platform/mac/Skipped (101998 => 101999)


--- trunk/LayoutTests/platform/mac/Skipped	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/platform/mac/Skipped	2011-12-05 15:38:11 UTC (rev 101999)
@@ -447,6 +447,7 @@
 # https://bugs.webkit.org/show_bug.cgi?id=43668
 media/track
 fast/events/constructors/track-event-constructor.html
+http/tests/security/text-track-crossorigin.html
 
 # Tests for MediaSource API. Feature is not yet functional.
 # https://bugs.webkit.org/show_bug.cgi?id=64731

Modified: trunk/LayoutTests/platform/qt/Skipped (101998 => 101999)


--- trunk/LayoutTests/platform/qt/Skipped	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/platform/qt/Skipped	2011-12-05 15:38:11 UTC (rev 101999)
@@ -2443,6 +2443,7 @@
 
 # track not functional yet.
 fast/events/constructors/track-event-constructor.html
+http/tests/security/text-track-crossorigin.html
 
 # Skip because this platform does not support a paging mouse wheel event
 fast/events/platform-wheelevent-paging-x-in-non-scrolling-div.html

Modified: trunk/LayoutTests/platform/win/Skipped (101998 => 101999)


--- trunk/LayoutTests/platform/win/Skipped	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/platform/win/Skipped	2011-12-05 15:38:11 UTC (rev 101999)
@@ -1427,6 +1427,7 @@
 # https://bugs.webkit.org/show_bug.cgi?id=43668
 media/track
 fast/events/constructors/track-event-constructor.html
+http/tests/security/text-track-crossorigin.html
 
 # Tests for MediaSource API. Feature is not yet functional.
 # https://bugs.webkit.org/show_bug.cgi?id=64731

Modified: trunk/LayoutTests/platform/wincairo/Skipped (101998 => 101999)


--- trunk/LayoutTests/platform/wincairo/Skipped	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/LayoutTests/platform/wincairo/Skipped	2011-12-05 15:38:11 UTC (rev 101999)
@@ -1938,6 +1938,7 @@
 # https://bugs.webkit.org/show_bug.cgi?id=43668
 media/track
 fast/events/constructors/track-event-constructor.html
+http/tests/security/text-track-crossorigin.html
 
 # Tests for MediaSource API. Feature is not yet functional.
 # https://bugs.webkit.org/show_bug.cgi?id=64731

Modified: trunk/Source/WebCore/ChangeLog (101998 => 101999)


--- trunk/Source/WebCore/ChangeLog	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/Source/WebCore/ChangeLog	2011-12-05 15:38:11 UTC (rev 101999)
@@ -1,3 +1,38 @@
+2011-12-05  Eric Carlson  <[email protected]>
+
+        Out-of-band text tracks may only load from same origin as the media element's Document's origin
+        https://bugs.webkit.org/show_bug.cgi?id=73184
+
+        Reviewed by Sam Weinig.
+
+        Test: http/tests/security/text-track-crossorigin.html
+
+        * html/HTMLTrackElement.cpp:
+        (WebCore::urlForLogging): Debug-only function for logging urls.
+        (WebCore::HTMLTrackElement::scheduleLoad): Call canLoadUrl() before passing control off to
+            the Track.
+        (WebCore::HTMLTrackElement::canLoadUrl): Don't ask HTMLMediaElement to validate the url, the
+            requirements for <track> are different from <video>.
+        (WebCore::HTMLTrackElement::didCompleteLoad): Change bool param to enum.
+        (WebCore::HTMLTrackElement::mediaElementCrossOriginAttribute): New, return parent 'crossorigin' 
+            attribute value.
+        * html/HTMLTrackElement.h:
+
+        * html/LoadableTextTrack.cpp:
+        (WebCore::LoadableTextTrack::scheduleLoad): Add comments from the spec.
+        (WebCore::LoadableTextTrack::loadTimerFired): Always cancel pending loads. Let the caller know 
+            if the loader refuses the url immediately.
+        (WebCore::LoadableTextTrack::cueLoadingStarted): The <track> deals with readyState.
+        (WebCore::LoadableTextTrack::cueLoadingCompleted): HTMLTrackElement::didCompleteLoad takes
+            an enum, not a bool.
+
+        * loader/TextTrackLoader.cpp:
+        (WebCore::TextTrackLoader::corsPolicyPreventedLoad): New, log the error and set m_state.
+        (WebCore::TextTrackLoader::notifyFinished): Check for CORS failure.
+        (WebCore::TextTrackLoader::load): Take media element cross-origin attribute as a param so we
+            can make the correct checks.
+        * loader/TextTrackLoader.h:
+
 2011-12-05  Roland Steiner  <[email protected]>
 
         "Raw" pseudo selectors don't match if immediately after a child or descendant combinator

Modified: trunk/Source/WebCore/html/HTMLTrackElement.cpp (101998 => 101999)


--- trunk/Source/WebCore/html/HTMLTrackElement.cpp	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/Source/WebCore/html/HTMLTrackElement.cpp	2011-12-05 15:38:11 UTC (rev 101999)
@@ -28,6 +28,7 @@
 #if ENABLE(VIDEO_TRACK)
 #include "HTMLTrackElement.h"
 
+#include "ContentSecurityPolicy.h"
 #include "Event.h"
 #include "HTMLMediaElement.h"
 #include "HTMLNames.h"
@@ -41,6 +42,17 @@
 
 using namespace HTMLNames;
 
+#if !LOG_DISABLED
+static String urlForLogging(const KURL& url)
+{
+    static const unsigned maximumURLLengthForLogging = 128;
+    
+    if (url.string().length() < maximumURLLengthForLogging)
+        return url.string();
+    return url.string().substring(0, maximumURLLengthForLogging) + "...";
+}
+#endif
+    
 inline HTMLTrackElement::HTMLTrackElement(const QualifiedName& tagName, Document* document)
     : HTMLElement(tagName, document)
 {
@@ -192,10 +204,21 @@
     if (!fastHasAttribute(srcAttr))
         return;
 
-    ensureTrack()->scheduleLoad(getNonEmptyURLAttribute(srcAttr));
+    // 4.8.10.12.3 Sourcing out-of-band text tracks
+
+    // 1. Set the text track readiness state to loading.
+    setReadyState(HTMLTrackElement::LOADING);
+
+    KURL url = ""
+    if (!canLoadUrl(url)) {
+        didCompleteLoad(ensureTrack(), HTMLTrackElement::Failure);
+        return;
+    }
+
+    ensureTrack()->scheduleLoad(url);
 }
 
-bool HTMLTrackElement::canLoadUrl(LoadableTextTrack*, const KURL& url)
+bool HTMLTrackElement::canLoadUrl(const KURL& url)
 {
     if (!RuntimeEnabledFeatures::webkitVideoTrackEnabled())
         return false;
@@ -204,18 +227,52 @@
     if (!parent)
         return false;
 
-    if (!parent->isSafeToLoadURL(url, HTMLMediaElement::Complain))
+    // 4.8.10.12.3 Sourcing out-of-band text tracks
+
+    // 4. Download: If URL is not the empty string, perform a potentially CORS-enabled fetch of URL, with the
+    // mode being the state of the media element's crossorigin content attribute, the origin being the
+    // origin of the media element's Document, and the default origin behaviour set to fail.
+    if (url.isEmpty())
         return false;
+
+    if (!document()->contentSecurityPolicy()->allowMediaFromSource(url)) {
+        DEFINE_STATIC_LOCAL(String, consoleMessage, ("Text track load denied by Content Security Policy."));
+        document()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage);
+        LOG(Media, "HTMLTrackElement::canLoadUrl(%s) -> rejected by Content Security Policy", urlForLogging(url).utf8().data());
+        return false;
+    }
     
     return dispatchBeforeLoadEvent(url.string());
 }
 
-void HTMLTrackElement::didCompleteLoad(LoadableTextTrack*, bool loadingFailed)
+void HTMLTrackElement::didCompleteLoad(LoadableTextTrack*, LoadStatus status)
 {
-    loadingFailed ? setReadyState(HTMLTrackElement::TRACK_ERROR) : setReadyState(HTMLTrackElement::LOADED);
+    ExceptionCode ec = 0;
 
-    ExceptionCode ec = 0;
-    dispatchEvent(Event::create(loadingFailed ? eventNames().errorEvent : eventNames().loadEvent, false, false), ec);
+    // 4.8.10.12.3 Sourcing out-of-band text tracks (continued)
+    
+    // 4. Download: ...
+    // If the fetching algorithm fails for any reason (network error, the server returns an error 
+    // code, a cross-origin check fails, etc), or if URL is the empty string or has the wrong origin 
+    // as determined by the condition at the start of this step, or if the fetched resource is not in
+    // a supported format, then queue a task to first change the text track readiness state to failed
+    // to load and then fire a simple event named error at the track element; and then, once that task
+    // is queued, move on to the step below labeled monitoring.
+
+    if (status == Failure) {
+        setReadyState(HTMLTrackElement::TRACK_ERROR);
+        dispatchEvent(Event::create(eventNames().errorEvent, false, false), ec);
+        return;
+    }
+
+    // If the fetching algorithm does not fail, then the final task that is queued by the networking
+    // task source must run the following steps:
+    //     1. Change the text track readiness state to loaded.
+    setReadyState(HTMLTrackElement::LOADED);
+
+    //     2. If the file was successfully processed, fire a simple event named load at the 
+    //        track element.
+    dispatchEvent(Event::create(eventNames().loadEvent, false, false), ec);
 }
 
 // NOTE: The values in the TextTrack::ReadinessState enum must stay in sync with those in HTMLTrackElement::ReadyState.
@@ -235,7 +292,15 @@
 {
     return static_cast<ReadyState>(ensureTrack()->readinessState());
 }
+
+const AtomicString& HTMLTrackElement::mediaElementCrossOriginAttribute() const
+{
+    if (HTMLMediaElement* parent = mediaElement())
+        return parent->fastGetAttribute(HTMLNames::crossoriginAttr);
     
+    return nullAtom;
+}
+
 void HTMLTrackElement::textTrackKindChanged(TextTrack* track)
 {
     if (HTMLMediaElement* parent = mediaElement())

Modified: trunk/Source/WebCore/html/HTMLTrackElement.h (101998 => 101999)


--- trunk/Source/WebCore/html/HTMLTrackElement.h	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/Source/WebCore/html/HTMLTrackElement.h	2011-12-05 15:38:11 UTC (rev 101999)
@@ -60,11 +60,14 @@
     void setReadyState(ReadyState);
 
     TextTrack* track();
-    
+
     void scheduleLoad();
-    virtual bool canLoadUrl(LoadableTextTrack*, const KURL&);
-    virtual void didCompleteLoad(LoadableTextTrack*, bool /* loadingFailed */);
-    
+
+    enum LoadStatus { Failure, Success };
+    virtual void didCompleteLoad(LoadableTextTrack*, LoadStatus);
+
+    const AtomicString& mediaElementCrossOriginAttribute() const;
+
 private:
     HTMLTrackElement(const QualifiedName&, Document*);
     virtual ~HTMLTrackElement();
@@ -92,6 +95,7 @@
     virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>);
 
     LoadableTextTrack* ensureTrack();
+    virtual bool canLoadUrl(const KURL&);
 
     RefPtr<LoadableTextTrack> m_track;
 };

Modified: trunk/Source/WebCore/html/LoadableTextTrack.cpp (101998 => 101999)


--- trunk/Source/WebCore/html/LoadableTextTrack.cpp	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/Source/WebCore/html/LoadableTextTrack.cpp	2011-12-05 15:38:11 UTC (rev 101999)
@@ -57,28 +57,36 @@
 
 void LoadableTextTrack::scheduleLoad(const KURL& url)
 {
+    if (url == m_url)
+        return;
+
+    // 4.8.10.12.3 Sourcing out-of-band text tracks (continued)
+
+    // 2. Let URL be the track URL of the track element.
     m_url = url;
+    
+    // 3. Asynchronously run the remaining steps, while continuing with whatever task 
+    // was responsible for creating the text track or changing the text track mode.
     if (!m_loadTimer.isActive())
         m_loadTimer.startOneShot(0);
 }
 
 void LoadableTextTrack::loadTimerFired(Timer<LoadableTextTrack>*)
 {
-    if (!m_trackElement)
-        return;
-
-    m_trackElement->setReadyState(HTMLTrackElement::LOADING);
-    
     if (m_loader)
         m_loader->cancelLoad();
 
-    if (!m_trackElement->canLoadUrl(this, m_url)) {
-        m_trackElement->setReadyState(HTMLTrackElement::TRACK_ERROR);
+    if (!m_trackElement)
         return;
-    }
 
+    // 4.8.10.12.3 Sourcing out-of-band text tracks (continued)
+
+    // 4. Download: If URL is not the empty string, perform a potentially CORS-enabled fetch of URL, with the
+    // mode being the state of the media element's crossorigin content attribute, the origin being the
+    // origin of the media element's Document, and the default origin behaviour set to fail.
     m_loader = TextTrackLoader::create(this, static_cast<ScriptExecutionContext*>(m_trackElement->document()));
-    m_loader->load(m_url);
+    if (!m_loader->load(m_url, m_trackElement->mediaElementCrossOriginAttribute()))
+        m_trackElement->didCompleteLoad(this, HTMLTrackElement::Failure);
 }
 
 void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader)
@@ -103,10 +111,6 @@
 void LoadableTextTrack::cueLoadingStarted(TextTrackLoader* loader)
 {
     ASSERT_UNUSED(loader, m_loader == loader);
-    
-    if (!m_trackElement)
-        return;
-    m_trackElement->setReadyState(HTMLTrackElement::LOADING);
 }
 
 void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadingFailed)
@@ -115,7 +119,8 @@
 
     if (!m_trackElement)
         return;
-    m_trackElement->didCompleteLoad(this, loadingFailed);
+
+    m_trackElement->didCompleteLoad(this, loadingFailed ? HTMLTrackElement::Failure : HTMLTrackElement::Success);
 }
 
 void LoadableTextTrack::fireCueChangeEvent()

Modified: trunk/Source/WebCore/loader/TextTrackLoader.cpp (101998 => 101999)


--- trunk/Source/WebCore/loader/TextTrackLoader.cpp	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/Source/WebCore/loader/TextTrackLoader.cpp	2011-12-05 15:38:11 UTC (rev 101999)
@@ -31,9 +31,11 @@
 
 #include "CachedResourceLoader.h"
 #include "CachedTextTrack.h"
+#include "CrossOriginAccessControl.h"
 #include "Document.h"
 #include "Logging.h"
 #include "ResourceHandle.h"
+#include "SecurityOrigin.h"
 #include "SharedBuffer.h"
 #include "WebVTTParser.h"
 
@@ -139,32 +141,61 @@
     processNewCueData(resource);
 }
 
+void TextTrackLoader::corsPolicyPreventedLoad()
+{
+    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin text track load denied by Cross-Origin Resource Sharing policy."));
+    Document* document = static_cast<Document*>(m_scriptExecutionContext);
+    document->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage);
+    m_state = Failed;
+}
+
 void TextTrackLoader::notifyFinished(CachedResource* resource)
 {
     ASSERT(m_cachedCueData == resource);
 
-    processNewCueData(resource);
+    Document* document = static_cast<Document*>(m_scriptExecutionContext);
+    if (!m_crossOriginMode.isNull()
+        && !document->securityOrigin()->canRequest(resource->response().url())
+        && !resource->passesAccessControlCheck(document->securityOrigin())) {
 
-    if (m_state != Failed)
-        m_state = resource->errorOccurred() ? Failed : Finished;
+        corsPolicyPreventedLoad();
+    }
 
+    if (m_state != Failed) {
+        processNewCueData(resource);
+        if (m_state != Failed)
+            m_state = resource->errorOccurred() ? Failed : Finished;
+    }
+
     if (!m_cueLoadTimer.isActive())
         m_cueLoadTimer.startOneShot(0);
     
     cancelLoad();
 }
 
-bool TextTrackLoader::load(const KURL& url)
+bool TextTrackLoader::load(const KURL& url, const String& crossOriginMode)
 {
+    cancelLoad();
+
     if (!m_client->shouldLoadCues(this))
         return false;
-    
-    cancelLoad();
-    
+
     ASSERT(m_scriptExecutionContext->isDocument());
     Document* document = static_cast<Document*>(m_scriptExecutionContext);
-    
     ResourceRequest cueRequest(document->completeURL(url));
+
+    if (!crossOriginMode.isNull()) {
+        m_crossOriginMode = crossOriginMode;
+        StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+        updateRequestForAccessControl(cueRequest, document->securityOrigin(), allowCredentials);
+    } else {
+        // Cross-origin resources that are not suitably CORS-enabled may not load.
+        if (!document->securityOrigin()->canRequest(url)) {
+            corsPolicyPreventedLoad();
+            return false;
+        }
+    }
+
     CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
     m_cachedCueData = static_cast<CachedTextTrack*>(cachedResourceLoader->requestTextTrack(cueRequest));
     if (m_cachedCueData)

Modified: trunk/Source/WebCore/loader/TextTrackLoader.h (101998 => 101999)


--- trunk/Source/WebCore/loader/TextTrackLoader.h	2011-12-05 15:30:38 UTC (rev 101998)
+++ trunk/Source/WebCore/loader/TextTrackLoader.h	2011-12-05 15:38:11 UTC (rev 101999)
@@ -61,7 +61,7 @@
     }
     virtual ~TextTrackLoader();
     
-    bool load(const KURL&);
+    bool load(const KURL&, const String& crossOriginMode);
     void cancelLoad();
     void getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues);
     
@@ -78,6 +78,7 @@
     
     void processNewCueData(CachedResource*);
     void cueLoadTimerFired(Timer<TextTrackLoader>*);
+    void corsPolicyPreventedLoad();
 
     enum State { Idle, Loading, Finished, Failed };
     
@@ -86,6 +87,7 @@
     CachedResourceHandle<CachedTextTrack> m_cachedCueData;
     ScriptExecutionContext* m_scriptExecutionContext;
     Timer<TextTrackLoader> m_cueLoadTimer;
+    String m_crossOriginMode;
     State m_state;
     unsigned m_parseOffset;
     bool m_newCuesAvailable;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to