2010-04-20 Justin Schuh <jschuh@chromium.org>
authorjaphet@chromium.org <japhet@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Apr 2010 21:42:20 +0000 (21:42 +0000)
committerjaphet@chromium.org <japhet@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Apr 2010 21:42:20 +0000 (21:42 +0000)
        Reviewed by Adam Barth.

        Invalid cast due to <video> inside <foreignObject> inside <svg> inside <img>
        https://bugs.webkit.org/show_bug.cgi?id=37331

        Added a setting to enable/disable media per-page and have the SVGImage
        disable media for its dummy page. Also found and fixed a related bad
        cast in the V8 bindings (JSC had a custom wrapper for this already).

        Tests: media/svg-as-image-with-media-blocked.html

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@57922 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/media/resources/foreignobject-media.svg [new file with mode: 0644]
LayoutTests/media/svg-as-image-with-media-blocked-expected.txt [new file with mode: 0644]
LayoutTests/media/svg-as-image-with-media-blocked.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/dom/make_names.pl
WebCore/page/Settings.cpp
WebCore/page/Settings.h
WebCore/svg/graphics/SVGImage.cpp

index 08b818b..885be7e 100644 (file)
@@ -1,3 +1,18 @@
+2010-04-20  Justin Schuh  <jschuh@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Invalid cast due to <video> inside <foreignObject> inside <svg> inside <img>
+        https://bugs.webkit.org/show_bug.cgi?id=37331
+
+        Tests for a crash on attempting to load media in a foreignObject inside
+        an SVGImage.
+
+        * media/resources: Added.
+        * media/resources/foreignobject-media.svg: Added.
+        * media/svg-as-image-with-media-blocked-expected.txt: Added.
+        * media/svg-as-image-with-media-blocked.html: Added.
+
 2010-04-20  Dmitry Titov  <dimich@chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/media/resources/foreignobject-media.svg b/LayoutTests/media/resources/foreignobject-media.svg
new file mode 100644 (file)
index 0000000..fb21486
--- /dev/null
@@ -0,0 +1,13 @@
+<svg xmlns = "http://www.w3.org/2000/svg" width="320px" height="480px"> 
+  <rect x="0" y="0" width="320px" height="480px" style="fill:green"/>
+  <foreignObject x="0" y="0" width="100%" height="100%">
+    <body xmlns="http://www.w3.org/1999/xhtml">
+               <video src="test.mp4" autoplay="true" width="320px" height="240px"></video> 
+               <audio src="test.oga" autoplay="true"></audio> 
+               <video autoplay="true" width="320px" height="240px">
+                       <source src='test.ogv' />
+                       <source src='test.mp4' />
+               </video>
+    </body> 
+  </foreignObject> 
+</svg>
\ No newline at end of file
diff --git a/LayoutTests/media/svg-as-image-with-media-blocked-expected.txt b/LayoutTests/media/svg-as-image-with-media-blocked-expected.txt
new file mode 100644 (file)
index 0000000..9dc279c
--- /dev/null
@@ -0,0 +1,3 @@
+This test attempts to load foreignObject audio and video embedded in an SVG file loaded as the src attribute of an img element. If successful, none of these files will load and a green rectangle will be visible below this text. If unsuccessful, the browser will crash while attempting to load the media.
+
+
diff --git a/LayoutTests/media/svg-as-image-with-media-blocked.html b/LayoutTests/media/svg-as-image-with-media-blocked.html
new file mode 100644 (file)
index 0000000..309b928
--- /dev/null
@@ -0,0 +1,17 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+</head>
+<body>
+<p>
+This test attempts to load foreignObject audio and video embedded in an SVG 
+file loaded as the src attribute of an img element. If successful, none of 
+these files will load and a green rectangle will be visible below this text. 
+If unsuccessful, the browser will crash while attempting to load the media.
+</p>
+<img src='resources/foreignobject-media.svg'>
+</body>
+</html>
index bfb5d49..ca93530 100644 (file)
@@ -1,3 +1,25 @@
+2010-04-20  Justin Schuh  <jschuh@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Invalid cast due to <video> inside <foreignObject> inside <svg> inside <img>
+        https://bugs.webkit.org/show_bug.cgi?id=37331
+
+        Added a setting to enable/disable media per-page and have the SVGImage 
+        disable media for its dummy page. Also found and fixed a related bad
+        cast in the V8 bindings (JSC had a custom wrapper for this already).
+
+        Tests: media/svg-as-image-with-media-blocked.html
+
+        * dom/make_names.pl: Added media enabled check and V8 cast wrapper
+        * page/Settings.cpp: Added m_isMediaEnabled (defaults to true)
+        (WebCore::Settings::Settings):
+        (WebCore::Settings::setMediaEnabled):
+        * page/Settings.h:
+        (WebCore::Settings::isMediaEnabled):
+        * svg/graphics/SVGImage.cpp: Disables media in dummy page
+        (WebCore::SVGImage::dataChanged):
+
 2010-04-19  Antonio Gomes  <tonikitoo@webkit.org>
 
         Reviewed by Simon Fraser.
index 7b87681..57006d2 100755 (executable)
@@ -287,8 +287,10 @@ sub printConstructorInterior
     # Handle media elements.
     if ($tags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
         print F <<END
-    if (!MediaPlayer::isAvailable())
+    Settings* settings = document->settings();
+    if (!MediaPlayer::isAvailable() || (settings && !settings->isMediaEnabled()))
         return HTMLElement::create($constructorTagName, document);
+    
 END
 ;
     }
@@ -638,7 +640,7 @@ printElementIncludes($F);
 print F <<END
 #include <wtf/HashMap.h>
 
-#if ENABLE(DASHBOARD_SUPPORT)
+#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(VIDEO)
 #include "Document.h"
 #include "Settings.h"
 #endif
@@ -839,7 +841,8 @@ sub printWrapperFunctions
                 print F <<END
 static JSNode* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
 {
-    if (!MediaPlayer::isAvailable())
+    Settings* settings = element->document()->settings();
+    if (!MediaPlayer::isAvailable() || (settings && !settings->isMediaEnabled()))
         return CREATE_DOM_NODE_WRAPPER(exec, globalObject, $parameters{namespace}Element, element.get());
     return CREATE_DOM_NODE_WRAPPER(exec, globalObject, ${JSInterfaceName}, element.get());
 }
@@ -857,14 +860,29 @@ END
 ;
             }
         } elsif ($wrapperFactoryType eq "V8") {
+            if ($tags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
+                print F <<END
+static v8::Handle<v8::Value> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element)
+{
+    Settings* settings = element->document()->settings();
+    if (!MediaPlayer::isAvailable() || (settings && !settings->isMediaEnabled()))
+        return toV8(static_cast<$parameters{namespace}Element*>(element));
+    return toV8(static_cast<${JSInterfaceName}*>(element));
+}
+
+END
+;
+            } else {
             print F <<END
 static v8::Handle<v8::Value> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element)
 {
     return toV8(static_cast<${JSInterfaceName}*>(element));
 }
 
+
 END
 ;
+            }
         }
 
         if ($conditional) {
@@ -895,7 +913,16 @@ sub printWrapperFactoryCppFile
 
     printElementIncludes($F);
 
-    print F "\n#include <wtf/StdLibExtras.h>\n\n";
+    print F <<END
+#include <wtf/StdLibExtras.h>
+
+#if ENABLE(VIDEO)
+#include "Document.h"
+#include "Settings.h"
+#endif
+
+END
+;
 
     if ($wrapperFactoryType eq "JS") {    
         print F <<END
index a61e40e..fd9f9e3 100644 (file)
@@ -76,6 +76,7 @@ Settings::Settings(Page* page)
     , m_privateBrowsingEnabled(false)
     , m_caretBrowsingEnabled(false)
     , m_areImagesEnabled(true)
+    , m_isMediaEnabled(true)
     , m_arePluginsEnabled(false)
     , m_localStorageEnabled(false)
     , m_isJavaScriptEnabled(false)
@@ -266,6 +267,11 @@ void Settings::setImagesEnabled(bool areImagesEnabled)
     m_areImagesEnabled = areImagesEnabled;
 }
 
+void Settings::setMediaEnabled(bool isMediaEnabled)
+{
+    m_isMediaEnabled = isMediaEnabled;
+}
+
 void Settings::setPluginsEnabled(bool arePluginsEnabled)
 {
     m_arePluginsEnabled = arePluginsEnabled;
index 62ebf32..104decc 100644 (file)
@@ -131,6 +131,9 @@ namespace WebCore {
         void setImagesEnabled(bool);
         bool areImagesEnabled() const { return m_areImagesEnabled; }
 
+        void setMediaEnabled(bool);
+        bool isMediaEnabled() const { return m_isMediaEnabled; }
+
         void setPluginsEnabled(bool);
         bool arePluginsEnabled() const { return m_arePluginsEnabled; }
 
@@ -334,6 +337,7 @@ namespace WebCore {
         bool m_privateBrowsingEnabled : 1;
         bool m_caretBrowsingEnabled : 1;
         bool m_areImagesEnabled : 1;
+        bool m_isMediaEnabled : 1;
         bool m_arePluginsEnabled : 1;
         bool m_localStorageEnabled : 1;
         bool m_isJavaScriptEnabled : 1;
index 3cde619..b63d9c5 100644 (file)
@@ -247,6 +247,7 @@ bool SVGImage::dataChanged(bool allDataReceived)
         // The comment said that the Cache code does not know about CachedImages
         // holding Frames and won't know to break the cycle. But 
         m_page.set(new Page(m_chromeClient.get(), dummyContextMenuClient, dummyEditorClient, dummyDragClient, dummyInspectorClient, 0, 0));
+        m_page->settings()->setMediaEnabled(false);
         m_page->settings()->setJavaScriptEnabled(false);
         m_page->settings()->setPluginsEnabled(false);