Firefox · Layout
CVE-2026-117913
Logic Error in Layout
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
forlayout/svg/crashtests/2079252.html |
modified |
Files Changed
layout/svg/SVGTextFrame.cpplayout/svg/crashtests/2079252.htmllayout/svg/crashtests/crashtests.list
Patch
diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp
index 548b4ce31ee..fe6b97aa55e 100644
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3994,6 +3994,8 @@ already_AddRefed<DOMSVGPoint> SVGTextFrame::GetEndPositionOfChar(
return nullptr;
}
+ RefPtr<const gfxTextRun> textRun = it.TextRun();
+
// We need to return the end position of the whole glyph.
uint32_t startIndex = it.GlyphStartTextElementCharIndex();
float zoom = it.GetTextFrame()->Style()->EffectiveZoom().ToFloat();
@@ -4003,7 +4005,6 @@ already_AddRefed<DOMSVGPoint> SVGTextFrame::GetEndPositionOfChar(
GetGlyphAdvance(this, aElement, startIndex,
it.IsClusterAndLigatureGroupStart() ? &it : nullptr) /
mFontSizeScaleFactor;
- const gfxTextRun* textRun = it.TextRun();
if (textRun->IsInlineReversed()) {
advance = -advance;
}
@@ -4046,7 +4047,7 @@ already_AddRefed<SVGRect> SVGTextFrame::GetExtentOfChar(
nsTextFrame* textFrame = it.GetTextFrame();
uint32_t startIndex = it.GlyphStartTextElementCharIndex();
- const gfxTextRun* textRun = it.TextRun();
+ RefPtr<const gfxTextRun> textRun = it.TextRun();
// Get the glyph advance.
gfxFloat advance =
@@ -4762,7 +4763,7 @@ void SVGTextFrame::DoTextPathLayout() {
MOZ_ASSERT(!mPositions[i].mClusterOrLigatureGroupMiddle);
- const gfxTextRun* textRun = it.TextRun();
+ RefPtr<const gfxTextRun> textRun = it.TextRun();
bool vertical = textRun->IsVertical();
// Compute cumulative advances for each character of the cluster or
diff --git a/layout/svg/crashtests/2079252.html b/layout/svg/crashtests/2079252.html
new file mode 100644
index 00000000000..a8d78aae061
--- /dev/null
+++ b/layout/svg/crashtests/2079252.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head><meta charset="utf-8"></head>
+<body>
+<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600"><text id="t" y="20" style="white-space:pre"></text></svg>
+<script>
+const NS = "http://www.w3.org/2000/svg", t = document.getElementById("t"), m = 48;
+for (let i = 0; i < m; i++) {
+ const s = document.createElementNS(NS, "tspan");
+ s.setAttribute("style", i % 2 ? "font-size:20px" : "font-size:24px");
+ s.textContent = "x\ne" + String.fromCharCode(0x301);
+ t.appendChild(s);
+}
+const d = document.createElementNS(NS, "tspan");
+d.setAttribute("style", "font-size:30px");
+d.textContent = "w";
+t.appendChild(d);
+const total = t.getNumberOfChars();
+const per = (total - 1) / m;
+d.firstChild.data = "ww";
+for (let i = 0; i < m; i++) {
+ try { t.getExtentOfChar(i * per + per - 1); } catch (e) {}
+}
+</script>
+</body>
+</html>
diff --git a/layout/svg/crashtests/crashtests.list b/layout/svg/crashtests/crashtests.list
index 901a2eb7ab9..08618a4b31e 100644
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -282,3 +282,4 @@ skip-if(isDebugBuild&&Android) load 1993379-1.html # bug 1467887
load 1906769-1.html
load 2073222.html
load 2076198.html
+load 2079252.html
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/layout/svg/crashtests/2079252.html b/layout/svg/crashtests/2079252.html
new file mode 100644
index 00000000000..a8d78aae061
--- /dev/null
+++ b/layout/svg/crashtests/2079252.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head><meta charset="utf-8"></head>
+<body>
+<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600"><text id="t" y="20" style="white-space:pre"></text></svg>
+<script>
+const NS = "http://www.w3.org/2000/svg", t = document.getElementById("t"), m = 48;
+for (let i = 0; i < m; i++) {
+ const s = document.createElementNS(NS, "tspan");
+ s.setAttribute("style", i % 2 ? "font-size:20px" : "font-size:24px");
+ s.textContent = "x\ne" + String.fromCharCode(0x301);
+ t.appendChild(s);
+}
+const d = document.createElementNS(NS, "tspan");
+d.setAttribute("style", "font-size:30px");
+d.textContent = "w";
+t.appendChild(d);
+const total = t.getNumberOfChars();
+const per = (total - 1) / m;
+d.firstChild.data = "ww";
+for (let i = 0; i < m; i++) {
+ try { t.getExtentOfChar(i * per + per - 1); } catch (e) {}
+}
+</script>
+</body>
+</html>
diff --git a/layout/svg/crashtests/crashtests.list b/layout/svg/crashtests/crashtests.list
index 901a2eb7ab9..08618a4b31e 100644
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -282,3 +282,4 @@ skip-if(isDebugBuild&&Android) load 1993379-1.html # bug 1467887
load 1906769-1.html
load 2073222.html
load 2076198.html
+load 2079252.html
Loading diff…
References
On This Page