Low firefox Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactlow
DescriptionIncorrect boundary conditions in the Graphics: CanvasWebGL component
ComponentDOM
Bug ClassLogic Error
Tracker2038444
Fix commit05cd902dc0f3 (firefox) +41/-20
CISA KEVNot listed
CreditedMihalis Haatainen
Disclosed2026-06-16

Changed Functions

FunctionChangeNotes
switch
dom/canvas/WebGLTransformFeedback.cpp
modified

Files Changed

  • dom/canvas/WebGLTransformFeedback.cpp
  • dom/canvas/WebGLTransformFeedback.h
diff --git a/dom/canvas/WebGLTransformFeedback.cpp b/dom/canvas/WebGLTransformFeedback.cpp
index 6c4bc590fbd..88bf4274278 100644
--- a/dom/canvas/WebGLTransformFeedback.cpp
+++ b/dom/canvas/WebGLTransformFeedback.cpp
@@ -29,33 +29,24 @@ WebGLTransformFeedback::~WebGLTransformFeedback() {
 
 ////////////////////////////////////////
 
-void WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) {
-  if (mIsActive) return mContext->ErrorInvalidOperation("Already active.");
-
-  switch (primMode) {
-    case LOCAL_GL_POINTS:
-    case LOCAL_GL_LINES:
-    case LOCAL_GL_TRIANGLES:
-      break;
-    default:
-      mContext->ErrorInvalidEnum(
-          "`primitiveMode` must be one of POINTS, LINES, or"
-          " TRIANGLES.");
-      return;
-  }
-
+/// Do some validation when beginning/resuming the TF, and compute the
+/// vertex capacity.
+bool WebGLTransformFeedback::PrepareTransformFeedback() {
   const auto& prog = mContext->mCurrentProgram;
+
   if (!prog || !prog->IsLinked() ||
       prog->LinkInfo()->componentsPerTFVert.empty()) {
     mContext->ErrorInvalidOperation(
         "Current program not valid for transform"
         " feedback.");
-    return;
+    return false;
   }
 
   const auto& linkInfo = prog->LinkInfo();
   const auto& componentsPerTFVert = linkInfo->componentsPerTFVert;
 
+  mActive_VertCapacity = 0;
+
   size_t minVertCapacity = SIZE_MAX;
   for (size_t i = 0; i < componentsPerTFVert.size(); i++) {
     const auto& indexedBinding = mIndexedBindings[i];
@@ -67,7 +58,7 @@ void WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) {
           "No buffer attached to required transform"
           " feedback index %u.",
           (uint32_t)i);
-      return;
+      return false;
     }
 
     for (const auto iBound : IntegerRange(mIndexedBindings.size())) {
@@ -76,7 +67,7 @@ void WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) {
         mContext->GenErrorIllegalUse(
             LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<uint32_t>(i),
             LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<uint32_t>(iBound));
-        return;
+        return false;
       }
     }
 
@@ -84,6 +75,30 @@ void WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) {
     minVertCapacity = std::min(minVertCapacity, vertCapacity);
   }
 
+  mActive_VertCapacity = minVertCapacity;
+
+  return true;
+}
+
+void WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) {
+  if (mIsActive) return mContext->ErrorInvalidOperation("Already active.");
+
+  switch (primMode) {
+    case LOCAL_GL_POINTS:
+    case LOCAL_GL_LINES:
+    case LOCAL_GL_TRIANGLES:
+      break;
+    default:
+      mContext->ErrorInvalidEnum(
+          "`primitiveMode` must be one of POINTS, LINES, or"
+          " TRIANGLES.");
+      return;
+  }
+
+  if (!PrepareTransformFeedback()) {
+    return;
+  }
+
   ////
 
   const auto& gl = mContext->gl;
@@ -94,10 +109,9 @@ void WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) {
   mIsActive = true;
   MOZ_ASSERT(!mIsPaused);
 
-  mActive_Program = prog;
+  mActive_Program = mContext->mCurrentProgram;
   mActive_PrimMode = primMode;
   mActive_VertPosition = 0;
-  mActive_VertCapacity = minVertCapacity;
 
   ////
 
@@ -158,6 +172,12 @@ void WebGLTransformFeedback::ResumeTransformFeedback() {
     return;
   }
 
+  // Re-run prepare in case some of the buffers have been modified
+  // while the TF was paused.
+  if (!PrepareTransformFeedback()) {
+    return;
+  }
+
   ////
 
   const auto& gl = mContext->gl;
diff --git a/dom/canvas/WebGLTransformFeedback.h b/dom/canvas/WebGLTransformFeedback.h
index 30cc8fa34b9..593513589c5 100644
--- a/dom/canvas/WebGLTransformFeedback.h
+++ b/dom/canvas/WebGLTransformFeedback.h
@@ -46,6 +46,7 @@ class WebGLTransformFeedback final : public WebGLContextBoundObject {
 
  private:
   ~WebGLTransformFeedback() override;
+  bool PrepareTransformFeedback();
 
  public:
   bool IsActiveAndNotPaused() const { return mIsActive && !mIsPaused; }
Loading diff…