Bug 1485730 - [marionette] Limit width and height of created canvas to 32767 pixels. r=ato
authorHenrik Skupin <mail@hskupin.info>
Tue, 28 Aug 2018 13:40:11 +0200
changeset 482180 bd6fb6ab62f4c6ae57923c1ae987fb32c1387563
parent 482179 3eb891993d3e0802ae958cb8256d4e44c3b0817e
child 482181 1a5c43f28e0675a36b3322233e16f9f9ad448548
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewersato
bugs1485730, 32767
milestone63.0a1
Bug 1485730 - [marionette] Limit width and height of created canvas to 32767 pixels. r=ato The Skia GFX backend limits the dimension of canvases to a maximum of 32767 for the width and height.
testing/marionette/capture.js
testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py
--- a/testing/marionette/capture.js
+++ b/testing/marionette/capture.js
@@ -2,23 +2,26 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const {InvalidArgumentError} = ChromeUtils.import("chrome://marionette/content/error.js", {});
+const {Log} = ChromeUtils.import("chrome://marionette/content/log.js", {});
 
+XPCOMUtils.defineLazyGetter(this, "logger", Log.get);
 XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]);
 
 this.EXPORTED_SYMBOLS = ["capture"];
 
 const CONTEXT_2D = "2d";
 const BG_COLOUR = "rgb(255,255,255)";
+const MAX_SKIA_DIMENSIONS = 32767;
 const PNG_MIME = "image/png";
 const XHTML_NS = "http://www.w3.org/1999/xhtml";
 
 /**
  * Provides primitives to capture screenshots.
  *
  * @namespace
  */
@@ -107,19 +110,34 @@ capture.viewport = function(win, highlig
  *     The canvas on which the selection from the window's framebuffer
  *     has been painted on.
  */
 capture.canvas = function(win, left, top, width, height,
     {highlights = [], canvas = null, flags = null} = {}) {
   const scale = win.devicePixelRatio;
 
   if (canvas === null) {
+    let canvasWidth = width * scale;
+    let canvasHeight = height * scale;
+
+    if (canvasWidth > MAX_SKIA_DIMENSIONS) {
+      logger.warn("Reducing screenshot width because it exceeds " +
+          MAX_SKIA_DIMENSIONS + " pixels");
+      canvasWidth = MAX_SKIA_DIMENSIONS;
+    }
+
+    if (canvasHeight > MAX_SKIA_DIMENSIONS) {
+      logger.warn("Reducing screenshot height because it exceeds " +
+          MAX_SKIA_DIMENSIONS + " pixels");
+      canvasHeight = MAX_SKIA_DIMENSIONS;
+    }
+
     canvas = win.document.createElementNS(XHTML_NS, "canvas");
-    canvas.width = width * scale;
-    canvas.height = height * scale;
+    canvas.width = canvasWidth;
+    canvas.height = canvasHeight;
   }
 
   let ctx = canvas.getContext(CONTEXT_2D);
   if (flags === null) {
     flags = ctx.DRAWWINDOW_DRAW_CARET;
     // TODO(ato): https://bugzil.la/1377335
     //
     // Disabled in bug 1243415 for webplatform-test
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py
@@ -289,16 +289,21 @@ class TestScreenCaptureContent(WindowMan
     def test_capture_tab_already_closed(self):
         tab = self.open_tab()
         self.marionette.switch_to_window(tab)
         self.marionette.close()
 
         self.assertRaises(NoSuchWindowException, self.marionette.screenshot)
         self.marionette.switch_to_window(self.start_tab)
 
+    def test_capture_vertical_bounds(self):
+        self.marionette.navigate(inline("<body style='margin-top: 32768px'>foo"))
+        screenshot = self.marionette.screenshot()
+        self.assert_png(screenshot)
+
     def test_capture_element(self):
         self.marionette.navigate(box)
         el = self.marionette.find_element(By.TAG_NAME, "div")
         screenshot = self.marionette.screenshot(element=el)
         self.assert_png(screenshot)
         self.assertEqual(self.scale(self.get_element_dimensions(el)),
                          self.get_image_dimensions(screenshot))