Firefox · Graphics
CVE-2026-4686
Logic Error in Graphics
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
switchgfx/2d/FilterNodeSoftware.cpp |
modified |
Files Changed
gfx/2d/FilterNodeSoftware.cppgfx/2d/FilterNodeSoftware.h
Patch
diff --git a/gfx/2d/FilterNodeSoftware.cpp b/gfx/2d/FilterNodeSoftware.cpp
index 0130e7853b1..1d4a61cf49a 100644
--- a/gfx/2d/FilterNodeSoftware.cpp
+++ b/gfx/2d/FilterNodeSoftware.cpp
@@ -3313,7 +3313,8 @@ static inline Point3D Normalized(const Point3D& vec) {
template <typename LightType, typename LightingType>
FilterNodeLightingSoftware<LightType, LightingType>::FilterNodeLightingSoftware(
const char* aTypeName)
- : mSurfaceScale(0)
+ : mSurfaceScale(0),
+ mKernelUnitLength(1.0f, 1.0f)
#if defined(MOZILLA_INTERNAL_API) && defined(NS_BUILD_REFCNT_LOGGING)
,
mTypeName(aTypeName)
@@ -3366,6 +3367,23 @@ void FilterNodeLightingSoftware<LightType, LightingType>::SetAttribute(
switch (aIndex) {
case ATT_LIGHTING_KERNEL_UNIT_LENGTH:
mKernelUnitLength = aKernelUnitLength;
+ // Spec for fe*Lighting:
+ // The first number is the <dx> value. The second number is the <dy>
+ // value. If the <dy> value is not specified, it defaults to the same
+ // value as <dx>. If kernelUnitLength is not specified, the dx and dy
+ // values should represent very small deltas relative to a given (x,y)
+ // position, which might be implemented in some cases as one pixel in the
+ // intermediate image offscreen bitmap, which is a pixel-based coordinate
+ // system, and thus potentially not scalable. If a negative or zero value
+ // is specified the default value will be used instead.
+ if (mKernelUnitLength.width <= 0.0f ||
+ !std::isfinite(mKernelUnitLength.width)) {
+ mKernelUnitLength.width = 1.0f;
+ }
+ if (mKernelUnitLength.height <= 0.0f ||
+ !std::isfinite(mKernelUnitLength.height)) {
+ mKernelUnitLength.height = mKernelUnitLength.width;
+ }
break;
default:
MOZ_CRASH("GFX: FilterNodeLightingSoftware::SetAttribute size");
@@ -3522,22 +3540,33 @@ FilterNodeLightingSoftware<LightType, LightingType>::Render(
return DoRender(aRect, mKernelUnitLength.width, mKernelUnitLength.height);
}
+template <typename LightType, typename LightingType>
+MarginDouble FilterNodeLightingSoftware<
+ LightType, LightingType>::GetInflateSourceMargin() const {
+ double kulX = ceil(double(mKernelUnitLength.width));
+ double kulY = ceil(double(mKernelUnitLength.height));
+ return MarginDouble(kulY, kulX, kulY, kulX);
+}
+
+template <typename LightType, typename LightingType>
+IntRect FilterNodeLightingSoftware<LightType, LightingType>::InflatedSourceRect(
+ const IntRect& aDestRect) {
+ RectDouble srcRect(aDestRect);
+ srcRect.Inflate(GetInflateSourceMargin());
+ return RectIsInt32Safe(srcRect) ? TruncatedToInt(srcRect) : aDestRect;
+}
+
template <typename LightType, typename LightingType>
void FilterNodeLightingSoftware<
LightType, LightingType>::RequestFromInputsForRect(const IntRect& aRect) {
- IntRect srcRect = aRect;
- srcRect.Inflate(ceil(mKernelUnitLength.width),
- ceil(mKernelUnitLength.height));
- RequestInputRect(IN_LIGHTING_IN, srcRect);
+ RequestInputRect(IN_LIGHTING_IN, InflatedSourceRect(aRect));
}
template <typename LightType, typename LightingType>
IntRect FilterNodeLightingSoftware<LightType, LightingType>::MapRectToSource(
const IntRect& aRect, const IntRect& aMax, FilterNode* aSourceNode) {
- IntRect srcRect = aRect;
- srcRect.Inflate(ceil(mKernelUnitLength.width),
- ceil(mKernelUnitLength.height));
- return MapInputRectToSource(IN_LIGHTING_IN, srcRect, aMax, aSourceNode);
+ return MapInputRectToSource(IN_LIGHTING_IN, InflatedSourceRect(aRect), aMax,
+ aSourceNode);
}
template <typename LightType, typename LightingType>
@@ -3551,14 +3580,17 @@ FilterNodeLightingSoftware<LightType, LightingType>::DoRender(
MOZ_ASSERT(aKernelUnitLengthY > 0,
"aKernelUnitLengthY can be a negative or zero value");
- IntRect srcRect = aRect;
- IntSize size = aRect.Size();
- srcRect.Inflate(ceil(float(aKernelUnitLengthX)),
- ceil(float(aKernelUnitLengthY)));
-
+ RectDouble srcRectD(aRect);
+ srcRectD.Inflate(GetInflateSourceMargin());
// Inflate the source rect by another pixel because the bilinear filtering in
// ColorComponentAtPoint may want to access the margins.
- srcRect.Inflate(1);
+ srcRectD.Inflate(1);
+ if (!RectIsInt32Safe(srcRectD)) {
+ return nullptr;
+ }
+ IntRect srcRect = TruncatedToInt(srcRectD);
+
+ IntSize size = aRect.Size();
IntRect srcRectInRenderRect = srcRect.Intersect(mRenderRect);
diff --git a/gfx/2d/FilterNodeSoftware.h b/gfx/2d/FilterNodeSoftware.h
index 280320bd148..6c655d74ae3 100644
--- a/gfx/2d/FilterNodeSoftware.h
+++ b/gfx/2d/FilterNodeSoftware.h
@@ -766,6 +766,9 @@ class FilterNodeLightingSoftware : public FilterNodeSoftware {
CoordType aKernelUnitLengthX,
CoordType aKernelUnitLengthY);
+ MarginDouble GetInflateSourceMargin() const;
+ IntRect InflatedSourceRect(const IntRect& aDestRect);
+
LightType mLight;
LightingType mLighting;
Float mSurfaceScale;
Loading diff…
References
On This Page