High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionUse-after-free in the Layout component
ComponentLayout
Bug ClassLogic Error
Tracker2082064
Fix commit00484f32e8fb (firefox) +35/-2
CISA KEVNot listed
CreditedOpenAI Codex Security (kylebot)
Disclosed2026-10-27

Changed Functions

FunctionChangeNotes
if
layout/generic/MiddleCroppingBlockFrame.cpp
modified
if
testing/web-platform/tests/html/rendering/widgets/file-type-label-update-crash.https.html
modified

Files Changed

  • layout/generic/MiddleCroppingBlockFrame.cpp
  • testing/web-platform/tests/html/rendering/widgets/file-type-label-update-crash.https.html
diff --git a/layout/generic/MiddleCroppingBlockFrame.cpp b/layout/generic/MiddleCroppingBlockFrame.cpp
index fa975759fe7..f48bc82c9e9 100644
--- a/layout/generic/MiddleCroppingBlockFrame.cpp
+++ b/layout/generic/MiddleCroppingBlockFrame.cpp
@@ -31,7 +31,10 @@ MiddleCroppingBlockFrame::~MiddleCroppingBlockFrame() = default;
 void MiddleCroppingBlockFrame::UpdateDisplayedValue(const nsAString& aValue,
                                                     bool aIsCropped,
                                                     bool aNotify) {
-  auto* text = mTextNode.get();
+  // If we notify, we might be dead after SetText().
+  mCropped = aIsCropped;
+
+  RefPtr text = mTextNode;
   uint32_t oldLength = aNotify ? 0 : text->TextLength();
   text->SetText(aValue, aNotify);
   if (!aNotify) {
@@ -45,7 +48,6 @@ void MiddleCroppingBlockFrame::UpdateDisplayedValue(const nsAString& aValue,
       LinesBegin()->MarkDirty();
     }
   }
-  mCropped = aIsCropped;
 }
 
 void MiddleCroppingBlockFrame::UpdateDisplayedValueToUncroppedValue(
diff --git a/testing/web-platform/tests/html/rendering/widgets/file-type-label-update-crash.https.html b/testing/web-platform/tests/html/rendering/widgets/file-type-label-update-crash.https.html
new file mode 100644
index 00000000000..d1580fc52b4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/file-type-label-update-crash.https.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<meta charset="utf-8">
+<body>
+<script>
+// Use application/xml rather than application/xhtml+xml so that editing setup
+// is retried during the file input's native-anonymous text update.
+const xml = `<?xml version="1.0"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title>child</title></head>
+<body><div contenteditable="true">edit</div>
+<input type="file" id="file" style="width:200px"/></body></html>`;
+const frame = document.createElement("iframe");
+frame.onload = () => {
+  const doc = frame.contentDocument;
+  if (doc.contentType !== "application/xml") {
+    return;
+  }
+  const input = doc.getElementById("file");
+  input.getBoundingClientRect();
+  const dt = new DataTransfer();
+  dt.items.add(new File(["test"], "a-long-file-name-for-middle-cropping.txt"));
+  // Leave this style change pending until the label's text mutation flushes it.
+  frame.style.display = "none";
+  input.files = dt.files;
+  document.documentElement.classList.remove("reftest-wait");
+};
+frame.src = URL.createObjectURL(new Blob([xml], {type: "application/xml"}));
+document.body.append(frame);
+</script>
+</html>
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/testing/web-platform/tests/html/rendering/widgets/file-type-label-update-crash.https.html b/testing/web-platform/tests/html/rendering/widgets/file-type-label-update-crash.https.html
new file mode 100644
index 00000000000..d1580fc52b4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/file-type-label-update-crash.https.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<meta charset="utf-8">
+<body>
+<script>
+// Use application/xml rather than application/xhtml+xml so that editing setup
+// is retried during the file input's native-anonymous text update.
+const xml = `<?xml version="1.0"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title>child</title></head>
+<body><div contenteditable="true">edit</div>
+<input type="file" id="file" style="width:200px"/></body></html>`;
+const frame = document.createElement("iframe");
+frame.onload = () => {
+  const doc = frame.contentDocument;
+  if (doc.contentType !== "application/xml") {
+    return;
+  }
+  const input = doc.getElementById("file");
+  input.getBoundingClientRect();
+  const dt = new DataTransfer();
+  dt.items.add(new File(["test"], "a-long-file-name-for-middle-cropping.txt"));
+  // Leave this style change pending until the label's text mutation flushes it.
+  frame.style.display = "none";
+  input.files = dt.files;
+  document.documentElement.classList.remove("reftest-wait");
+};
+frame.src = URL.createObjectURL(new Blob([xml], {type: "application/xml"}));
+document.body.append(frame);
+</script>
+</html>
Loading diff…