changeset 10937:77a9be043f2c

8203698: JavaFX WebView crashes when visiting certain web sites Reviewed-by: kcr, arajkumar Contributed-by: murali.billa@oracle.com, arunprasad.rajkumar@oracle.com
author mbilla
date Fri, 01 Jun 2018 11:38:40 +0530
parents 54f4e9759fa1
children 46bd0ff75f66
files modules/javafx.web/src/main/native/Source/WebCore/platform/java/ScrollbarThemeJava.cpp modules/javafx.web/src/main/native/Source/WebCore/platform/java/ScrollbarThemeJava.h tests/system/src/test/java/test/javafx/scene/web/SVGTest.java tests/system/src/test/resources/test/javafx/scene/web/crash-on-scrollable-svg.html
diffstat 4 files changed, 176 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/modules/javafx.web/src/main/native/Source/WebCore/platform/java/ScrollbarThemeJava.cpp	Thu May 31 15:55:34 2018 +0200
+++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/java/ScrollbarThemeJava.cpp	Fri Jun 01 11:38:40 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,16 +62,26 @@
 
 JLObject getJScrollBarTheme(Scrollbar& sb)
 {
-    FrameView* fv = sb.root();
+    FrameView* fv = sb.enabled() ? sb.root() : nullptr;
     if (!fv) {
         // the scrollbar has been detached
         return 0;
     }
+
     Page* page = fv->frame().page();
-    JLObject jWebPage = ((ChromeClientJava*)&page->chrome().client())->platformPage();
+    if (!page) {
+        return 0;
+    }
+
+    auto& chromeClient = page->chrome().client();
+    if (!chromeClient.isJavaChromeClient()) {
+        // Non Java ChromeClient, might be a utility Page(svg?), refer Page::isUtilityPage
+        return 0;
+    }
+
+    JLObject jWebPage = static_cast<ChromeClientJava&>(chromeClient).platformPage();
 
     JNIEnv* env = WebCore_GetJavaEnv();
-
     static jmethodID mid  = env->GetMethodID(
         PG_GetWebPageClass(env),
         "getScrollBarTheme",
--- a/modules/javafx.web/src/main/native/Source/WebCore/platform/java/ScrollbarThemeJava.h	Thu May 31 15:55:34 2018 +0200
+++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/java/ScrollbarThemeJava.h	Fri Jun 01 11:38:40 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
     IntRect backButtonRect(Scrollbar&, ScrollbarPart, bool painting = false) override;
     IntRect forwardButtonRect(Scrollbar&, ScrollbarPart, bool painting = false) override;
     IntRect trackRect(Scrollbar&, bool painting = false) override;
+    bool usesOverlayScrollbars() const final { return true; }
 };
 
 } // namespace WebCore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/system/src/test/java/test/javafx/scene/web/SVGTest.java	Fri Jun 01 11:38:40 2018 +0530
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.javafx.scene.web;
+
+import java.net.URL;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.scene.Scene;
+import javafx.scene.image.Image;
+import javafx.scene.image.PixelReader;
+import javafx.scene.paint.Color;
+import javafx.scene.web.WebView;
+import javafx.stage.Stage;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import test.util.Util;
+
+import static javafx.concurrent.Worker.State.SUCCEEDED;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static test.util.Util.TIMEOUT;
+
+public class SVGTest {
+    private static final CountDownLatch launchLatch = new CountDownLatch(1);
+
+    // Maintain one application instance
+    static TestApp testApp;
+
+    private static WebView webView;
+
+    public static class TestApp extends Application {
+        Stage primaryStage = null;
+
+        public TestApp() {
+            super();
+        }
+
+        @Override
+        public void init() {
+            SVGTest.testApp = this;
+        }
+
+        @Override
+        public void start(Stage primaryStage) throws Exception {
+            final WebView webView = new WebView();
+
+            Platform.setImplicitExit(false);
+            primaryStage.setWidth(800);
+            primaryStage.setHeight(600);
+            primaryStage.setScene(new Scene(webView));
+            primaryStage.show();
+
+            SVGTest.webView = webView;
+            this.primaryStage = primaryStage;
+
+            launchLatch.countDown();
+        }
+    }
+
+    @BeforeClass
+    public static void setupOnce() throws InterruptedException {
+        // Start the Test Application
+        new Thread(() -> Application.launch(TestApp.class,
+            (String[]) null)).start();
+
+        assertTrue("Timeout waiting for FX runtime to start",
+            launchLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)
+        );
+    }
+
+    @AfterClass
+    public static void tearDownOnce() {
+        Platform.exit();
+    }
+
+    @Test public void testCrashOnScrollableSVG() throws InterruptedException {
+        final CountDownLatch loadComplete = new CountDownLatch(1);
+        Util.runAndWait(() -> {
+            webView.getEngine().getLoadWorker().stateProperty().
+                addListener((observable, oldValue, newValue) -> {
+                if (newValue == SUCCEEDED) {
+                    loadComplete.countDown();
+                }
+            });
+            final URL url = TestApp.class.getResource(
+                "crash-on-scrollable-svg.html"
+            );
+            assertNotNull(url);
+            webView.getEngine().load(url.toExternalForm());
+        });
+
+        assertTrue("Timeout waiting for page load", loadComplete.await(TIMEOUT, TimeUnit.MILLISECONDS));
+
+        // Check pixel is as expected to ensure SVG image rendering
+        Util.runAndWait(() -> {
+            final Image snap = webView.snapshot(null, null);
+            assertNotNull(snap);
+            assertTrue(snap.getWidth() > 100);
+            assertTrue(snap.getHeight() > 100);
+            final PixelReader reader = snap.getPixelReader();
+            assertNotNull(reader);
+            assertEquals(String.format("Pixel (50, 50) is not RED"),
+                    Color.RED, reader.getColor(50, 50));
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/system/src/test/resources/test/javafx/scene/web/crash-on-scrollable-svg.html	Fri Jun 01 11:38:40 2018 +0530
@@ -0,0 +1,26 @@
+<html>
+<head>
+<style>
+.bg {
+  /* set overflow property on svg element to trigger the scrollbar rendering */
+  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewbox='0 0 1024 1024' overflow='scroll'><rect width='100' height='100' fill='red' /></svg>") no-repeat;
+  width: 100px;
+  height: 100px;
+}
+
+body {
+  margin-left: 0px; margin-top: 0px;
+}
+</style>
+</head>
+<!-- scroll to div which has svg as background to ease the pixel comparison-->
+<body onload='window.scrollTo(0, 800)'>
+<div style="height: 800px">
+</div>
+<div class="bg" ></div>
+<div style="height: 100%">
+Red rectangle must appear and shouldn't crash
+</div>
+</body>
+</html>
+