From 4cca88d1c32d8f3a346256716e0e665b0040defc Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 8 Nov 2021 15:55:04 +0100 Subject: [PATCH] [CGPath] Fix leak when creating mutable CGPaths. Fixes #11339. Make the MakeMutable function take into account that the input might have to be released, offer a way to do so, and update all callsites. Fixes https://github.com/xamarin/xamarin-macios/issues/11339. --- src/CoreGraphics/CGPath.cs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/CoreGraphics/CGPath.cs b/src/CoreGraphics/CGPath.cs index fb4e396c5858..41e1aab1fc42 100644 --- a/src/CoreGraphics/CGPath.cs +++ b/src/CoreGraphics/CGPath.cs @@ -506,9 +506,11 @@ public void Apply (ApplierFunction func) gch.Free (); } - static CGPath MakeMutable (IntPtr source) + static CGPath MakeMutable (IntPtr source, bool owns) { var mutable = CGPathCreateMutableCopy (source); + if (owns) + CGPathRelease (source); return new CGPath (mutable, owns: true); } @@ -527,7 +529,7 @@ public CGPath CopyByDashingPath (CGAffineTransform transform, nfloat [] lengths) public unsafe CGPath CopyByDashingPath (CGAffineTransform transform, nfloat [] lengths, nfloat phase) { - return MakeMutable (CGPathCreateCopyByDashingPath (Handle, &transform, phase, lengths, lengths is null ? 0 : lengths.Length)); + return MakeMutable (CGPathCreateCopyByDashingPath (Handle, &transform, phase, lengths, lengths is null ? 0 : lengths.Length), true); } public CGPath CopyByDashingPath (nfloat [] lengths) @@ -538,12 +540,12 @@ public CGPath CopyByDashingPath (nfloat [] lengths) public unsafe CGPath CopyByDashingPath (nfloat [] lengths, nfloat phase) { var path = CGPathCreateCopyByDashingPath (Handle, null, phase, lengths, lengths is null ? 0 : lengths.Length); - return MakeMutable (path); + return MakeMutable (path, true); } public unsafe CGPath Copy () { - return MakeMutable (Handle); + return MakeMutable (Handle, false); } [DllImport (Constants.CoreGraphicsLibrary)] @@ -551,12 +553,12 @@ public unsafe CGPath Copy () public unsafe CGPath CopyByStrokingPath (CGAffineTransform transform, nfloat lineWidth, CGLineCap lineCap, CGLineJoin lineJoin, nfloat miterLimit) { - return MakeMutable (CGPathCreateCopyByStrokingPath (Handle, &transform, lineWidth, lineCap, lineJoin, miterLimit)); + return MakeMutable (CGPathCreateCopyByStrokingPath (Handle, &transform, lineWidth, lineCap, lineJoin, miterLimit), true); } public unsafe CGPath CopyByStrokingPath (nfloat lineWidth, CGLineCap lineCap, CGLineJoin lineJoin, nfloat miterLimit) { - return MakeMutable (CGPathCreateCopyByStrokingPath (Handle, null, lineWidth, lineCap, lineJoin, miterLimit)); + return MakeMutable (CGPathCreateCopyByStrokingPath (Handle, null, lineWidth, lineCap, lineJoin, miterLimit), true); } [DllImport (Constants.CoreGraphicsLibrary)] @@ -564,7 +566,7 @@ public unsafe CGPath CopyByStrokingPath (nfloat lineWidth, CGLineCap lineCap, CG public CGPath CopyByTransformingPath (CGAffineTransform transform) { - return MakeMutable (CGPathCreateCopyByTransformingPath (Handle, ref transform)); + return MakeMutable (CGPathCreateCopyByTransformingPath (Handle, ref transform), true); } [DllImport (Constants.CoreGraphicsLibrary)] @@ -572,12 +574,12 @@ public CGPath CopyByTransformingPath (CGAffineTransform transform) static public unsafe CGPath EllipseFromRect (CGRect boundingRect, CGAffineTransform transform) { - return MakeMutable (CGPathCreateWithEllipseInRect (boundingRect, &transform)); + return MakeMutable (CGPathCreateWithEllipseInRect (boundingRect, &transform), true); } static public unsafe CGPath EllipseFromRect (CGRect boundingRect) { - return MakeMutable (CGPathCreateWithEllipseInRect (boundingRect, null)); + return MakeMutable (CGPathCreateWithEllipseInRect (boundingRect, null), true); } [DllImport (Constants.CoreGraphicsLibrary)] @@ -585,12 +587,12 @@ static public unsafe CGPath EllipseFromRect (CGRect boundingRect) static public unsafe CGPath FromRect (CGRect rectangle, CGAffineTransform transform) { - return MakeMutable (CGPathCreateWithRect (rectangle, &transform)); + return MakeMutable (CGPathCreateWithRect (rectangle, &transform), true); } static public unsafe CGPath FromRect (CGRect rectangle) { - return MakeMutable (CGPathCreateWithRect (rectangle, null)); + return MakeMutable (CGPathCreateWithRect (rectangle, null), true); } [DllImport (Constants.CoreGraphicsLibrary)] @@ -602,7 +604,7 @@ static unsafe CGPath _FromRoundedRect (CGRect rectangle, nfloat cornerWidth, nfl throw new ArgumentException (nameof (cornerWidth)); if ((cornerHeight < 0) || (2 * cornerHeight > rectangle.Height)) throw new ArgumentException (nameof (cornerHeight)); - return MakeMutable (CGPathCreateWithRoundedRect (rectangle, cornerWidth, cornerHeight, transform)); + return MakeMutable (CGPathCreateWithRoundedRect (rectangle, cornerWidth, cornerHeight, transform), true); } #if !NET