Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/System.Drawing.Common/src/System/Drawing/Graphics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,16 @@ public void FillRectangle(Brush brush, float x, float y, float width, float heig
{
ArgumentNullException.ThrowIfNull(brush);

// GDI+ has a bug where it writes out of bounds when using AntiAlias smoothing mode
// on a 24bppRgb bitmap, causing an AccessViolationException (or ExecutionEngineException in .NET 9+).
// We validate the parameters here to prevent the crash.
if (SmoothingMode == System.Drawing.Drawing2D.SmoothingMode.AntiAlias &&
_backingImage is { PixelFormat: PixelFormat.Format24bppRgb } &&
(x < 0 || y < 0 || x + width > _backingImage.Width || y + height > _backingImage.Height))
{
throw new ArgumentException("Drawing operation exceeds the bounds of the image. This is a known GDI+ limitation with AntiAlias smoothing mode and Format24bppRgb pixel format.");
}

CheckErrorStatus(PInvokeGdiPlus.GdipFillRectangle(
NativeGraphics,
brush.NativeBrush,
Expand Down
14 changes: 14 additions & 0 deletions src/System.Drawing.Common/tests/System/Drawing/GraphicsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3002,5 +3002,19 @@ public void Graphics_FillRoundedRectangle_Float()
graphics.FillRoundedRectangle(Brushes.Green, new RectangleF(0, 0, 10, 10), new(2, 2));
VerifyBitmapNotEmpty(bitmap);
}

[Fact]
public void FillRectangle_AntiAlias_24bppRgb_OutOfBounds_ThrowsArgumentException()
{
using Bitmap bmp = new(256, 256, PixelFormat.Format24bppRgb);
using Graphics graphics = Graphics.FromImage(bmp);
graphics.SmoothingMode = SmoothingMode.AntiAlias;

// This combination causes a crash in GDI+ on .NET 9+ (ExecutionEngineException)
// and AccessViolationException on .NET 8.
// We expect our fix to throw ArgumentException instead.
Assert.Throws<ArgumentException>(() =>
graphics.FillRectangle(Brushes.Green, new RectangleF(190.5f, 180.5f, 100, 100)));
}
#endif
}
Loading