Firefox · Graphics
CVE-2026-117866
Logic Error in Graphics
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
whilegfx/2d/DrawTargetCairo.cpp |
modified | |
ifgfx/2d/DrawTargetSkia.cpp |
modified |
Files Changed
gfx/2d/DrawTargetCairo.cppgfx/2d/DrawTargetRecording.cppgfx/2d/DrawTargetSkia.cppgfx/2d/DrawTargetSkia.h
Patch
diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp
index 121b0f0f6ef..24c18750d61 100644
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -1720,6 +1720,9 @@ void DrawTargetCairo::PopClip() {
}
bool DrawTargetCairo::RemoveAllClips() {
+ if (!mPushedLayers.empty()) {
+ return false;
+ }
while (mClipDepth > 0) {
PopClip();
}
diff --git a/gfx/2d/DrawTargetRecording.cpp b/gfx/2d/DrawTargetRecording.cpp
index 4d213d393a0..1f8ad9ea5b5 100644
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -765,6 +765,9 @@ void DrawTargetRecording::PopClip() {
}
bool DrawTargetRecording::RemoveAllClips() {
+ if (!mPushedLayers.empty()) {
+ return false;
+ }
RecordEventSelfSkipFlushTransform(RecordedRemoveAllClips());
return true;
}
diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp
index 2d1fdb75aad..2431e8e4e4e 100644
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -2151,11 +2151,18 @@ void DrawTargetSkia::PushClipRect(const Rect& aRect) {
}
void DrawTargetSkia::PopClip() {
+ if (!mPushedLayers.empty() &&
+ mCanvas->getSaveCount() <= mPushedLayers.back().mSaveCount) {
+ return;
+ }
mCanvas->restore();
SetTransform(GetTransform());
}
bool DrawTargetSkia::RemoveAllClips() {
+ if (!mPushedLayers.empty()) {
+ return false;
+ }
mCanvas->restoreToCount(1);
SetTransform(GetTransform());
return true;
@@ -2272,6 +2279,7 @@ void DrawTargetSkia::PushLayerWithBlend(bool aOpaque, Float aOpacity,
(aCopyBackground ? SkCanvas::kInitWithPrevious_SaveLayerFlag : 0));
mCanvas->saveLayer(saveRec);
+ mPushedLayers.back().mSaveCount = mCanvas->getSaveCount();
SetPermitSubpixelAA(aOpaque);
@@ -2307,6 +2315,10 @@ void DrawTargetSkia::PopLayer() {
}
}
+ // Remove any unbalanced saves before the layer restore.
+ if (mCanvas->getSaveCount() > layer.mSaveCount) {
+ mCanvas->restoreToCount(layer.mSaveCount);
+ }
// Restore the layer itself, and the clip we pushed for the mask bounds.
mCanvas->restore();
if (layer.mMask) {
diff --git a/gfx/2d/DrawTargetSkia.h b/gfx/2d/DrawTargetSkia.h
index 34641cd0047..a5b3907a950 100644
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -192,6 +192,7 @@ class DrawTargetSkia : public DrawTarget {
Matrix mMaskToDevice;
CompositionOp mCompositionOp = CompositionOp::OP_OVER;
bool mOldPermitSubpixelAA = false;
+ int mSaveCount = 0;
};
std::vector<PushedLayer> mPushedLayers;
Loading diff…
References
On This Page