Crash in GraphicsContext3D::getInternalFramebufferSize
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Jun 2015 22:11:32 +0000 (22:11 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Jun 2015 22:11:32 +0000 (22:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=145479
<rdar://problem/16461048>

Reviewed by Eric Carlson.

Source/WebCore:

If we are in an unitialized or lost state, don't try to access the context.

In order to test this, I added an Internal setting that always
forces WebGL into a pending state.

Test: fast/canvas/webgl/useWhilePending.html

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::create): Check internal settings for
a forced pending state.
(WebCore::WebGLRenderingContextBase::drawingBufferWidth): Guard against a pending state.
(WebCore::WebGLRenderingContextBase::drawingBufferHeight): Ditto.
* page/Settings.cpp: New Internal setting for forcing a pending policy.
(WebCore::Settings::Settings):
(WebCore::Settings::setForcePendingWebGLPolicy):
* page/Settings.h:
(WebCore::Settings::isForcePendingWebGLPolicy):
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup):
(WebCore::InternalSettings::Backup::restoreTo):
(WebCore::InternalSettings::setForcePendingWebGLPolicy):
* testing/InternalSettings.h:
* testing/InternalSettings.idl:

LayoutTests:

Attemps to use a WebGL context while it is in the pending state.

* fast/canvas/webgl/useWhilePending-expected.txt: Added.
* fast/canvas/webgl/useWhilePending.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/canvas/webgl/useWhilePending-expected.txt [new file with mode: 0644]
LayoutTests/fast/canvas/webgl/useWhilePending.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
Source/WebCore/page/Settings.cpp
Source/WebCore/page/Settings.h
Source/WebCore/testing/InternalSettings.cpp
Source/WebCore/testing/InternalSettings.h
Source/WebCore/testing/InternalSettings.idl

index 24bc685..e2586c5 100644 (file)
@@ -1,3 +1,16 @@
+2015-06-02  Dean Jackson  <dino@apple.com>
+
+        Crash in GraphicsContext3D::getInternalFramebufferSize
+        https://bugs.webkit.org/show_bug.cgi?id=145479
+        <rdar://problem/16461048>
+
+        Reviewed by Eric Carlson.
+
+        Attemps to use a WebGL context while it is in the pending state.
+
+        * fast/canvas/webgl/useWhilePending-expected.txt: Added.
+        * fast/canvas/webgl/useWhilePending.html: Added.
+
 2015-06-02  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         Fix Windows layout test failure following <http://trac.webkit.org/changeset/185095>
diff --git a/LayoutTests/fast/canvas/webgl/useWhilePending-expected.txt b/LayoutTests/fast/canvas/webgl/useWhilePending-expected.txt
new file mode 100644 (file)
index 0000000..3b3302d
--- /dev/null
@@ -0,0 +1 @@
+Should not crash.
diff --git a/LayoutTests/fast/canvas/webgl/useWhilePending.html b/LayoutTests/fast/canvas/webgl/useWhilePending.html
new file mode 100644 (file)
index 0000000..74edcaa
--- /dev/null
@@ -0,0 +1,23 @@
+<script>
+if (window.testRunner) {
+    window.internals.settings.setForcePendingWebGLPolicy(true);
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+window.addEventListener("load", function () {
+
+    var canvas = document.createElement("canvas");
+    canvas.width = 100;
+    canvas.height = 100;
+    var gl = canvas.getContext("webgl");
+    var foo = gl.drawingBufferWidth;
+    foo = gl.drawingBufferHeight;
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+
+}, false);
+</script>
+
+Should not crash.
index 702bc5d..9be5b45 100644 (file)
@@ -1,3 +1,35 @@
+2015-06-02  Dean Jackson  <dino@apple.com>
+
+        Crash in GraphicsContext3D::getInternalFramebufferSize
+        https://bugs.webkit.org/show_bug.cgi?id=145479
+        <rdar://problem/16461048>
+
+        Reviewed by Eric Carlson.
+
+        If we are in an unitialized or lost state, don't try to access the context.
+
+        In order to test this, I added an Internal setting that always
+        forces WebGL into a pending state.
+
+        Test: fast/canvas/webgl/useWhilePending.html
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::create): Check internal settings for
+        a forced pending state.
+        (WebCore::WebGLRenderingContextBase::drawingBufferWidth): Guard against a pending state.
+        (WebCore::WebGLRenderingContextBase::drawingBufferHeight): Ditto.
+        * page/Settings.cpp: New Internal setting for forcing a pending policy.
+        (WebCore::Settings::Settings):
+        (WebCore::Settings::setForcePendingWebGLPolicy):
+        * page/Settings.h:
+        (WebCore::Settings::isForcePendingWebGLPolicy):
+        * testing/InternalSettings.cpp:
+        (WebCore::InternalSettings::Backup::Backup):
+        (WebCore::InternalSettings::Backup::restoreTo):
+        (WebCore::InternalSettings::setForcePendingWebGLPolicy):
+        * testing/InternalSettings.h:
+        * testing/InternalSettings.idl:
+
 2015-06-02  Matt Rajca  <mrajca@apple.com>
 
         Added a stub implementation of MediaSession, part of the Media Session spec.
index efcc54a..e681921 100644 (file)
@@ -362,8 +362,10 @@ std::unique_ptr<WebGLRenderingContextBase> WebGLRenderingContextBase::create(HTM
     bool isPendingPolicyResolution = false;
     Document& topDocument = document.topDocument();
     Page* page = topDocument.page();
-    if (page && !topDocument.url().isLocalFile()) {
-        WebGLLoadPolicy policy = page->mainFrame().loader().client().webGLPolicyForURL(topDocument.url());
+    bool forcingPendingPolicy = frame->settings().isForcePendingWebGLPolicy();
+
+    if (forcingPendingPolicy || (page && !topDocument.url().isLocalFile())) {
+        WebGLLoadPolicy policy = forcingPendingPolicy ? WebGLPendingCreation : page->mainFrame().loader().client().webGLPolicyForURL(topDocument.url());
 
         if (policy == WebGLBlockCreation) {
             LOG(WebGL, "The policy for this URL (%s) is to block WebGL.", topDocument.url().host().utf8().data());
@@ -779,11 +781,17 @@ void WebGLRenderingContextBase::reshape(int width, int height)
 
 int WebGLRenderingContextBase::drawingBufferWidth() const
 {
+    if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution)
+        return 0;
+
     return m_context->getInternalFramebufferSize().width();
 }
 
 int WebGLRenderingContextBase::drawingBufferHeight() const
 {
+    if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution)
+        return 0;
+
     return m_context->getInternalFramebufferSize().height();
 }
 
index f478f40..ff9b22b 100644 (file)
@@ -201,6 +201,7 @@ Settings::Settings(Page* page)
 #endif
     , m_hiddenPageCSSAnimationSuspensionEnabled(false)
     , m_fontFallbackPrefersPictographs(false)
+    , m_forcePendingWebGLPolicy(false)
 {
     // A Frame may not have been created yet, so we initialize the AtomicString
     // hash before trying to use it.
@@ -424,6 +425,11 @@ void Settings::setImagesEnabled(bool areImagesEnabled)
     m_setImageLoadingSettingsTimer.startOneShot(0);
 }
 
+void Settings::setForcePendingWebGLPolicy(bool forced)
+{
+    m_forcePendingWebGLPolicy = forced;
+}
+
 void Settings::setPluginsEnabled(bool arePluginsEnabled)
 {
     if (m_arePluginsEnabled == arePluginsEnabled)
index 8e0b529..b5a17a8 100644 (file)
@@ -270,6 +270,9 @@ public:
     const String& mediaKeysStorageDirectory() const { return m_mediaKeysStorageDirectory; }
 #endif
 
+    WEBCORE_EXPORT void setForcePendingWebGLPolicy(bool);
+    bool isForcePendingWebGLPolicy() const { return m_forcePendingWebGLPolicy; }
+
 private:
     explicit Settings(Page*);
 
@@ -323,6 +326,8 @@ private:
     bool m_hiddenPageCSSAnimationSuspensionEnabled : 1;
     bool m_fontFallbackPrefersPictographs : 1;
 
+    bool m_forcePendingWebGLPolicy : 1;
+
 #if USE(AVFOUNDATION)
     WEBCORE_EXPORT static bool gAVFoundationEnabled;
 #endif
index c5984e3..5861175 100644 (file)
@@ -85,6 +85,7 @@ InternalSettings::Backup::Backup(Settings& settings)
     , m_shouldDisplayTextDescriptions(settings.shouldDisplayTextDescriptions())
 #endif
     , m_defaultVideoPosterURL(settings.defaultVideoPosterURL())
+    , m_forcePendingWebGLPolicy(settings.isForcePendingWebGLPolicy())
     , m_originalTimeWithoutMouseMovementBeforeHidingControls(settings.timeWithoutMouseMovementBeforeHidingControls())
     , m_useLegacyBackgroundSizeShorthandBehavior(settings.useLegacyBackgroundSizeShorthandBehavior())
     , m_autoscrollForDragAndDropEnabled(settings.autoscrollForDragAndDropEnabled())
@@ -152,6 +153,7 @@ void InternalSettings::Backup::restoreTo(Settings& settings)
     settings.setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions);
 #endif
     settings.setDefaultVideoPosterURL(m_defaultVideoPosterURL);
+    settings.setForcePendingWebGLPolicy(m_forcePendingWebGLPolicy);
     settings.setTimeWithoutMouseMovementBeforeHidingControls(m_originalTimeWithoutMouseMovementBeforeHidingControls);
     settings.setUseLegacyBackgroundSizeShorthandBehavior(m_useLegacyBackgroundSizeShorthandBehavior);
     settings.setAutoscrollForDragAndDropEnabled(m_autoscrollForDragAndDropEnabled);
@@ -210,6 +212,7 @@ void InternalSettings::resetToConsistentState()
 {
     page()->setPageScaleFactor(1, IntPoint(0, 0));
     page()->setCanStartMedia(true);
+    page()->settings().setForcePendingWebGLPolicy(false);
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     m_page->settings().setAllowsAirPlayForMediaPlayback(false);
 #endif
@@ -468,6 +471,12 @@ void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionCode
     settings()->setDefaultVideoPosterURL(url);
 }
 
+void InternalSettings::setForcePendingWebGLPolicy(bool forced, ExceptionCode& ec)
+{
+    InternalSettingsGuardForSettings();
+    settings()->setForcePendingWebGLPolicy(forced);
+}
+
 void InternalSettings::setTimeWithoutMouseMovementBeforeHidingControls(double time, ExceptionCode& ec)
 {
     InternalSettingsGuardForSettings();
index 68e2c94..144b663 100644 (file)
@@ -83,6 +83,7 @@ public:
         bool m_shouldDisplayTextDescriptions;
 #endif
         String m_defaultVideoPosterURL;
+        bool m_forcePendingWebGLPolicy;
         bool m_originalTimeWithoutMouseMovementBeforeHidingControls;
         bool m_useLegacyBackgroundSizeShorthandBehavior;
         bool m_autoscrollForDragAndDropEnabled;
@@ -134,6 +135,7 @@ public:
     void setImagesEnabled(bool, ExceptionCode&);
     void setMinimumTimerInterval(double intervalInSeconds, ExceptionCode&);
     void setDefaultVideoPosterURL(const String& url, ExceptionCode&);
+    void setForcePendingWebGLPolicy(bool, ExceptionCode&);
     void setTimeWithoutMouseMovementBeforeHidingControls(double time, ExceptionCode&);
     void setUseLegacyBackgroundSizeShorthandBehavior(bool, ExceptionCode&);
     void setAutoscrollForDragAndDropEnabled(bool, ExceptionCode&);
index 78e250d..309e89e 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -55,6 +56,8 @@
     [RaisesException] void setMediaTypeOverride(DOMString mediaTypeOverride);
     void setWirelessPlaybackDisabled(boolean available);
 
+    [RaisesException] void setForcePendingWebGLPolicy(boolean forced);
+
     void setPluginReplacementEnabled(boolean enabled);
 
     // Editing, forms