Medium chrome Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactPolicy bypass in Canvas
DescriptionPolicy bypass in Canvas
ComponentCanvas
Bug ClassLogic Error
Tracker500076131
Fix commit613498bb6a1e (chromium/src) +87/-129
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-02

Changed Functions

FunctionChangeNotes
if
third_party/blink/renderer/core/frame/local_frame_view.cc
modified

Files Changed

  • third_party/blink/renderer/core/frame/local_frame_view.cc
  • third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
  • third_party/blink/web_tests/TestExpectations
  • third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html
  • third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html
  • third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas-ref.html
  • third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html
From 613498bb6a1e36ea9f50deecb9c84fa1789466a5 Mon Sep 17 00:00:00 2001
From: Philip Rogers <[email protected]>
Date: Tue, 07 Apr 2026 17:46:40 -0700
Subject: [PATCH] [html-in-canvas] Prevent nested html-in-canvas

This patch disables nested html-in-canvas and causes the API to
throw exceptions when used.

Fixed: 489358151, 500076131, 477575513
Change-Id: If66ef646ad20556111a7b7dfe7e1345f50462d4d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7732722
Auto-Submit: Philip Rogers <[email protected]>
Reviewed-by: Stephen Chenney <[email protected]>
Commit-Queue: Stephen Chenney <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1611091}
---

diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index b930ef7..f5aa730 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -5088,6 +5088,9 @@
                                          Element& child) {
   DCHECK(RuntimeEnabledFeatures::CanvasDrawElementEnabled(
       GetFrame().GetDocument()->GetExecutionContext()));
+  if (canvas.IsInCanvasSubtree()) {
+    return;
+  }
   if (IsUpdatingLifecycle()) {
     auto add_result = canvas_elements_needing_onpaint_.insert(&canvas, nullptr);
     if (add_result.is_new_entry) {
@@ -5101,6 +5104,9 @@
 void LocalFrameView::RequestCanvasOnpaint(HTMLCanvasElement& canvas) {
   DCHECK(RuntimeEnabledFeatures::CanvasDrawElementEnabled(
       GetFrame().GetDocument()->GetExecutionContext()));
+  if (canvas.IsInCanvasSubtree()) {
+    return;
+  }
   auto add_result = canvas_elements_needing_onpaint_.insert(&canvas, nullptr);
   if (add_result.is_new_entry) {
     add_result.stored_value->value =
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 6a7419e..042b6c43 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -976,6 +976,11 @@
     Element* element,
     const String& func_name,
     ExceptionState& exception_state) const {
+  if (IsInCanvasSubtree()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+                                      "Nested canvases are not supported.");
+    return false;
+  }
   if (element->parentElement() != this) {
     exception_state.ThrowTypeError(
         "Only immediate children of the <canvas> element can be passed to " +
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 66bf9e8..7d93c031 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -721,11 +721,6 @@
 
 ### ====== Payments related tests end =======
 
-### ====== HTML-in-Canvas
-crbug.com/477575513 wpt_internal/html/canvas/drawElementImage/nested-webgl-canvas.html [ Skip Timeout ]
-crbug.com/435609887 wpt_internal/html/canvas/drawElementImage/nested-canvas.html [ Skip Timeout ]
-crbug.com/435609887 wpt_internal/html/canvas/drawElementImage/nested-div-canvas.html [ Skip Timeout ]
-
 # WPT speculative-parsing tests failing
 crbug.com/1144176 external/wpt/html/syntax/speculative-parsing/generated/document-write/link-rel-alternate-stylesheet.tentative.sub.html [ Crash Failure ]
 crbug.com/1144176 external/wpt/html/syntax/speculative-parsing/generated/document-write/link-rel-stylesheet-nomatch-media.tentative.sub.html [ Failure ]
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html
index 4fb65d5..eb61174a 100644
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html
+++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html
@@ -116,4 +116,28 @@
     () => canvas.getContext('2d').drawElementImage(elementImage, 0, 0),
     'A closed ElementImage cannot be drawn.');
 }, 'ElementImage.close() invalidates the image for drawing');
+
+promise_test(async t => {
+  const nestedCanvas = document.createElement('canvas');
+  nestedCanvas.layoutSubtree = true;
+  nestedCanvas.width = 100;
+  nestedCanvas.height = 100;
+  const childDiv = document.createElement('div');
+  childDiv.style.width = '100px';
+  childDiv.style.height = '100px';
+  nestedCanvas.appendChild(childDiv);
+
+  const outerCanvas = document.getElementById('canvas');
+  outerCanvas.appendChild(nestedCanvas);
+
+  t.add_cleanup(() => {
+    nestedCanvas.remove();
+  });
+
+  await waitForOneFrame();
+
+  assert_throws_dom('NotSupportedError',
+    () => nestedCanvas.captureElementImage(childDiv),
+    'captureElementImage on a nested canvas should throw NotSupportedError.');
+}, 'captureElementImage should throw if called on a nested canvas');
 </script>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html
index 180ef74..924ac01a 100644
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html
+++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html
@@ -1,26 +1,29 @@
 <!DOCTYPE html>
-<html class="reftest-wait">
-<title>drawElementImage should support rendering a nested canvas that was moved under the canvas</title>
+<title>drawElementImage should throw if a canvas is moved to be nested inside another canvas</title>
 <link rel="help" href="https://github.com/WICG/html-in-canvas">
-<link rel="match" href="nested-canvas-ref.html">
-<script src="/common/reftest-wait.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <canvas id="canvas_a" layoutsubtree="true" width="100" height="100">
-  <div id="div" style="width: 100px; height: 100px; background: radial-gradient(lightgreen, green);"></div>
+  <div id="div" style="width: 100px; height: 100px;"></div>
 </canvas>
-<canvas id="canvas_b" layoutsubtree="true" width="100" height="100" style="background: red;">
+<canvas id="canvas_b" layoutsubtree="true" width="100" height="100">
 </canvas>
 <script>
-async function runTest() {
+promise_test(async (t) => {
   await new Promise(requestAnimationFrame);
   await new Promise(setTimeout);
-  canvas_a.getContext('2d').drawElementImage(div, 0, 0, 100, 100);
+  const ctxA = canvas_a.getContext('2d');
+  // Initial draw should succeed.
+  ctxA.drawElementImage(div, 0, 0, 100, 100);
+
   canvas_b.appendChild(canvas_a);
   await new Promise(requestAnimationFrame);
   await new Promise(setTimeout);
-  canvas_b.getContext('2d').drawElementImage(canvas_a, 0, 0, 100, 100);
-  takeScreenshot();
-}
-onload = () => runTest();
+
+  // Now it is nested, so it should throw.
+  assert_throws_dom("NotSupportedError", () => {
+    ctxA.drawElementImage(div, 0, 0, 100, 100);
+  });
+}, "drawElementImage should throw if a canvas is moved to be nested");
 </script>
-</html>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas-ref.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas-ref.html
deleted file mode 100644
index c7cec7f..0000000
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas-ref.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<canvas style="width: 100px; height: 100px; background: radial-gradient(lightgreen, green);"></canvas>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html
index 5d95362..4ddb968a 100644
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html
+++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html
@@ -1,25 +1,21 @@
 <!DOCTYPE html>
-<html class="reftest-wait">
-<title>drawElementImage should support rendering a nested canvas</title>
+<title>drawElementImage should throw if the canvas is nested inside another canvas</title>
 <link rel="help" href="https://github.com/WICG/html-in-canvas">
-<link rel="match" href="nested-canvas-ref.html">
-<script src="/common/reftest-wait.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
-<canvas id="canvas" layoutsubtree="true" width="100" height="100" style="background: red;">
+<canvas id="canvas" layoutsubtree="true" width="100" height="100">
   <canvas id="nested_canvas" layoutsubtree="true" width="100" height="100">
-    <div id="inner_div" style="width: 100px; height: 100px; background: radial-gradient(lightgreen, green);"></div>
+    <div id="inner_div" style="width: 100px; height: 100px;"></div>
   </canvas>
 </canvas>
 <script>
-async function runTest() {
+promise_test(async (t) => {
   await new Promise(requestAnimationFrame);
   await new Promise(setTimeout);
-  nested_canvas.getContext('2d').drawElementImage(inner_div, 0, 0, 100, 100);
-  await new Promise(requestAnimationFrame);
-  await new Promise(setTimeout);
-  canvas.getContext('2d').drawElementImage(nested_canvas, 0, 0, 100, 100);
-  takeScreenshot();
-}
-onload = () => runTest();
+  const ctx = nested_canvas.getContext('2d');
+  assert_throws_dom("NotSupportedError", () => {
+    ctx.drawElementImage(inner_div, 0, 0, 100, 100);
+  });
+}, "drawElementImage should throw if called on a nested canvas");
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 66bf9e8..7d93c031 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -721,11 +721,6 @@
 
 ### ====== Payments related tests end =======
 
-### ====== HTML-in-Canvas
-crbug.com/477575513 wpt_internal/html/canvas/drawElementImage/nested-webgl-canvas.html [ Skip Timeout ]
-crbug.com/435609887 wpt_internal/html/canvas/drawElementImage/nested-canvas.html [ Skip Timeout ]
-crbug.com/435609887 wpt_internal/html/canvas/drawElementImage/nested-div-canvas.html [ Skip Timeout ]
-
 # WPT speculative-parsing tests failing
 crbug.com/1144176 external/wpt/html/syntax/speculative-parsing/generated/document-write/link-rel-alternate-stylesheet.tentative.sub.html [ Crash Failure ]
 crbug.com/1144176 external/wpt/html/syntax/speculative-parsing/generated/document-write/link-rel-stylesheet-nomatch-media.tentative.sub.html [ Failure ]
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html
index 4fb65d5..eb61174a 100644
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html
+++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/captureElementImage.html
@@ -116,4 +116,28 @@
     () => canvas.getContext('2d').drawElementImage(elementImage, 0, 0),
     'A closed ElementImage cannot be drawn.');
 }, 'ElementImage.close() invalidates the image for drawing');
+
+promise_test(async t => {
+  const nestedCanvas = document.createElement('canvas');
+  nestedCanvas.layoutSubtree = true;
+  nestedCanvas.width = 100;
+  nestedCanvas.height = 100;
+  const childDiv = document.createElement('div');
+  childDiv.style.width = '100px';
+  childDiv.style.height = '100px';
+  nestedCanvas.appendChild(childDiv);
+
+  const outerCanvas = document.getElementById('canvas');
+  outerCanvas.appendChild(nestedCanvas);
+
+  t.add_cleanup(() => {
+    nestedCanvas.remove();
+  });
+
+  await waitForOneFrame();
+
+  assert_throws_dom('NotSupportedError',
+    () => nestedCanvas.captureElementImage(childDiv),
+    'captureElementImage on a nested canvas should throw NotSupportedError.');
+}, 'captureElementImage should throw if called on a nested canvas');
 </script>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html
index 180ef74..924ac01a 100644
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html
+++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/moved-nested-canvas.html
@@ -1,26 +1,29 @@
 <!DOCTYPE html>
-<html class="reftest-wait">
-<title>drawElementImage should support rendering a nested canvas that was moved under the canvas</title>
+<title>drawElementImage should throw if a canvas is moved to be nested inside another canvas</title>
 <link rel="help" href="https://github.com/WICG/html-in-canvas">
-<link rel="match" href="nested-canvas-ref.html">
-<script src="/common/reftest-wait.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
 <canvas id="canvas_a" layoutsubtree="true" width="100" height="100">
-  <div id="div" style="width: 100px; height: 100px; background: radial-gradient(lightgreen, green);"></div>
+  <div id="div" style="width: 100px; height: 100px;"></div>
 </canvas>
-<canvas id="canvas_b" layoutsubtree="true" width="100" height="100" style="background: red;">
+<canvas id="canvas_b" layoutsubtree="true" width="100" height="100">
 </canvas>
 <script>
-async function runTest() {
+promise_test(async (t) => {
   await new Promise(requestAnimationFrame);
   await new Promise(setTimeout);
-  canvas_a.getContext('2d').drawElementImage(div, 0, 0, 100, 100);
+  const ctxA = canvas_a.getContext('2d');
+  // Initial draw should succeed.
+  ctxA.drawElementImage(div, 0, 0, 100, 100);
+
   canvas_b.appendChild(canvas_a);
   await new Promise(requestAnimationFrame);
   await new Promise(setTimeout);
-  canvas_b.getContext('2d').drawElementImage(canvas_a, 0, 0, 100, 100);
-  takeScreenshot();
-}
-onload = () => runTest();
+
+  // Now it is nested, so it should throw.
+  assert_throws_dom("NotSupportedError", () => {
+    ctxA.drawElementImage(div, 0, 0, 100, 100);
+  });
+}, "drawElementImage should throw if a canvas is moved to be nested");
 </script>
-</html>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas-ref.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas-ref.html
deleted file mode 100644
index c7cec7f..0000000
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas-ref.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<canvas style="width: 100px; height: 100px; background: radial-gradient(lightgreen, green);"></canvas>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html
index 5d95362..4ddb968a 100644
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html
+++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-canvas.html
@@ -1,25 +1,21 @@
 <!DOCTYPE html>
-<html class="reftest-wait">
-<title>drawElementImage should support rendering a nested canvas</title>
+<title>drawElementImage should throw if the canvas is nested inside another canvas</title>
 <link rel="help" href="https://github.com/WICG/html-in-canvas">
-<link rel="match" href="nested-canvas-ref.html">
-<script src="/common/reftest-wait.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
-<canvas id="canvas" layoutsubtree="true" width="100" height="100" style="background: red;">
+<canvas id="canvas" layoutsubtree="true" width="100" height="100">
   <canvas id="nested_canvas" layoutsubtree="true" width="100" height="100">
-    <div id="inner_div" style="width: 100px; height: 100px; background: radial-gradient(lightgreen, green);"></div>
+    <div id="inner_div" style="width: 100px; height: 100px;"></div>
   </canvas>
 </canvas>
 <script>
-async function runTest() {
+promise_test(async (t) => {
   await new Promise(requestAnimationFrame);
   await new Promise(setTimeout);
-  nested_canvas.getContext('2d').drawElementImage(inner_div, 0, 0, 100, 100);
-  await new Promise(requestAnimationFrame);
-  await new Promise(setTimeout);
-  canvas.getContext('2d').drawElementImage(nested_canvas, 0, 0, 100, 100);
-  takeScreenshot();
-}
-onload = () => runTest();
+  const ctx = nested_canvas.getContext('2d');
+  assert_throws_dom("NotSupportedError", () => {
+    ctx.drawElementImage(inner_div, 0, 0, 100, 100);
+  });
+}, "drawElementImage should throw if called on a nested canvas");
 </script>
-</html>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-div-canvas.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-div-canvas.html
index da66600..aaa9f16 100644
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-div-canvas.html
+++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-div-canvas.html
@@ -1,27 +1,23 @@
 <!DOCTYPE html>
-<html class="reftest-wait">
-<title>drawElementImage should support rendering a div containing a canvas, all under a canvas</title>
+<title>drawElementImage should throw if the canvas is nested inside another canvas</title>
 <link rel="help" href="https://github.com/WICG/html-in-canvas">
-<link rel="match" href="nested-canvas-ref.html">
-<script src="/common/reftest-wait.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
-<canvas id="canvas" layoutsubtree="true" width="100" height="100" style="background: red;">
-  <div id="nested_div" style="width: 100px; height: 100px;">
+<canvas id="canvas" layoutsubtree="true" width="100" height="100">
+  <div id="nested_div">
     <canvas id="nested_canvas" layoutsubtree="true" width="100" height="100">
-      <div id="inner_div" style="width: 100px; height: 100px; background: radial-gradient(lightgreen, green);"></div>
+      <div id="inner_div" style="width: 100px; height: 100px;"></div>
     </canvas>
   </div>
 </canvas>
 <script>
-async function runTest() {
+promise_test(async (t) => {
   await new Promise(requestAnimationFrame);
   await new Promise(setTimeout);
-  nested_canvas.getContext('2d').drawElementImage(inner_div, 0, 0, 100, 100);
-  await new Promise(requestAnimationFrame);
-  await new Promise(setTimeout);
-  canvas.getContext('2d').drawElementImage(nested_div, 0, 0, 100, 100);
-  takeScreenshot();
-}
-onload = () => runTest();
+  const ctx = nested_canvas.getContext('2d');
+  assert_throws_dom("NotSupportedError", () => {
+    ctx.drawElementImage(inner_div, 0, 0, 100, 100);
+  });
+}, "drawElementImage should throw if called on a nested canvas in a div");
 </script>
-</html>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-webgl-canvas.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-webgl-canvas.html
index f5cdf69..851a9ca 100644
--- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-webgl-canvas.html
+++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElementImage/nested-webgl-canvas.html
@@ -1,88 +1,23 @@
 <!DOCTYPE html>
-<html class="reftest-wait">
-<title>drawElementImage should support rendering a nested webgl canvas</title>
+<title>texElementImage2D should throw if the canvas is nested inside another canvas</title>
 <link rel="help" href="https://github.com/WICG/html-in-canvas">
-<link rel="match" href="nested-canvas-ref.html">
-<script src="/common/reftest-wait.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 
-<canvas id="webgl_canvas" layoutsubtree="true" width="100" height="100" style="background: red;">
+<canvas id="webgl_canvas" layoutsubtree="true" width="100" height="100">
   <canvas id="nested_webgl_canvas" layoutsubtree="true" width="100" height="100">
-    <div id="inner_div" style="width: 100px; height: 100px; background: radial-gradient(lightgreen, green);"></div>
+    <div id="inner_div" style="width: 100px; height: 100px;"></div>
   </canvas>
 </canvas>
 <script>
-  function drawWebGLElementImage(canvas, child) {
-    const gl = canvas.getContext('webgl2', {preserveDrawingBuffer:true});
-    const vsSrc = `#version 300 es
-      in vec2 a_pos;
-      in vec2 a_uv;
-      out vec2 v_uv;
-      void main(){
-        gl_Position = vec4(a_pos, 0.0, 1.0);
-        v_uv = a_uv;
-      }`;
-    const fsSrc = `#version 300 es
-      precision mediump float;
-      in vec2 v_uv;
-      uniform sampler2D u_tex;
-      out vec4 fragColor;
-      void main(){
-        fragColor = texture(u_tex, v_uv);
-      }`;
-
-    const vs = gl.createShader(gl.VERTEX_SHADER);
-    gl.shaderSource(vs, vsSrc);
-    gl.compileShader(vs);
-    const fs = gl.createShader(gl.FRAGMENT_SHADER);
-    gl.shaderSource(fs, fsSrc);
-    gl.compileShader(fs);
-
-    const prog = gl.createProgram();
-    gl.attachShader(prog, vs);
-    gl.attachShader(prog, fs);
-    gl.linkProgram(prog);
-    gl.useProgram(prog);
-
-    const vao = gl.createVertexArray();
-    gl.bindVertexArray(vao);
-    const vbo = gl.createBuffer();
-    gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
-    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-      -1,-1,0,0,  1,-1,1,0,  -1,1,0,1,
-      -1,1,0,1,   1,-1,1,0,   1,1,1,1
-    ]), gl.STATIC_DRAW);
-
-    const posLoc = gl.getAttribLocation(prog, 'a_pos');
-    const uvLoc = gl.getAttribLocation(prog, 'a_uv');
-    gl.enableVertexAttribArray(posLoc);
-    gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 16, 0);
-    gl.enableVertexAttribArray(uvLoc);
-    gl.vertexAttribPointer(uvLoc, 2, gl.FLOAT, false, 16, 8);
-
-    const tex = gl.createTexture();
-    gl.bindTexture(gl.TEXTURE_2D, tex);
-    const level = 0;
-    const internalformat = gl.RGBA;
-    const format = gl.RGBA;
-    const type = gl.UNSIGNED_BYTE;
-    gl.texElementImage2D(gl.TEXTURE_2D, level, internalformat, format, type, child);
-
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-
-    gl.uniform1i(gl.getUniformLocation(prog, 'u_tex'), 0);
-    gl.drawArrays(gl.TRIANGLES, 0, 6);
-  }
-
-async function runTest() {
+promise_test(async (t) => {
   await new Promise(requestAnimationFrame);
   await new Promise(setTimeout);
-  drawWebGLElementImage(nested_webgl_canvas, inner_div);
-  await new Promise(requestAnimationFrame);
-  await new Promise(setTimeout);
-  drawWebGLElementImage(webgl_canvas, nested_webgl_canvas);
-  takeScreenshot();
-}
-onload = () => runTest();
+  const gl = nested_webgl_canvas.getContext('webgl2', {preserveDrawingBuffer:true});
+  const tex = gl.createTexture();
+  gl.bindTexture(gl.TEXTURE_2D, tex);
+  assert_throws_dom("NotSupportedError", () => {
+    gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, inner_div);
+  });
+}, "texElementImage2D should throw if called on a nested webgl canvas");
 </script>
-</html>
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.