Skip to content

Commit acac6ef

Browse files
committed
[src] Fix numerous memory leaks.
1 parent 8b7d841 commit acac6ef

File tree

8 files changed

+40
-16
lines changed

8 files changed

+40
-16
lines changed

src/AddressBook/ABAddressBook.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ public nint PeopleCount {
422422
public ABPerson [] GetPeople ()
423423
{
424424
var cfArrayRef = ABAddressBookCopyArrayOfAllPeople (GetCheckedHandle ());
425-
return NSArray.ArrayFromHandle (cfArrayRef, h => new ABPerson (h, this));
425+
return NSArray.ArrayFromHandle (cfArrayRef, h => new ABPerson (h, this), releaseHandle: true);
426426
}
427427

428428
[DllImport (Constants.AddressBookLibrary)]
@@ -438,7 +438,7 @@ public ABPerson [] GetPeople (ABRecord source)
438438
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (source));
439439
var cfArrayRef = ABAddressBookCopyArrayOfAllPeopleInSource (GetCheckedHandle (), source.Handle);
440440
GC.KeepAlive (source);
441-
return NSArray.ArrayFromHandle (cfArrayRef, l => new ABPerson (l, this));
441+
return NSArray.ArrayFromHandle (cfArrayRef, l => new ABPerson (l, this), releaseHandle: true);
442442
}
443443

444444
[DllImport (Constants.AddressBookLibrary)]
@@ -455,7 +455,7 @@ public ABPerson [] GetPeople (ABRecord source, ABPersonSortBy sortOrdering)
455455
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (source));
456456
var cfArrayRef = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering (GetCheckedHandle (), source.Handle, sortOrdering);
457457
GC.KeepAlive (source);
458-
return NSArray.ArrayFromHandle (cfArrayRef, l => new ABPerson (l, this));
458+
return NSArray.ArrayFromHandle (cfArrayRef, l => new ABPerson (l, this), releaseHandle: true);
459459
}
460460

461461
[DllImport (Constants.AddressBookLibrary)]
@@ -490,7 +490,7 @@ public nint GroupCount {
490490
public ABGroup [] GetGroups ()
491491
{
492492
var cfArrayRef = ABAddressBookCopyArrayOfAllGroups (GetCheckedHandle ());
493-
return NSArray.ArrayFromHandle (cfArrayRef, h => new ABGroup (h, this));
493+
return NSArray.ArrayFromHandle (cfArrayRef, h => new ABGroup (h, this), releaseHandle: true);
494494
}
495495

496496
[DllImport (Constants.AddressBookLibrary)]
@@ -507,7 +507,7 @@ public ABGroup [] GetGroups (ABRecord source)
507507

508508
var cfArrayRef = ABAddressBookCopyArrayOfAllGroupsInSource (GetCheckedHandle (), source.Handle);
509509
GC.KeepAlive (source);
510-
return NSArray.ArrayFromHandle (cfArrayRef, l => new ABGroup (l, this));
510+
return NSArray.ArrayFromHandle (cfArrayRef, l => new ABGroup (l, this), releaseHandle: true);
511511
}
512512

513513
[DllImport (Constants.AddressBookLibrary)]
@@ -720,7 +720,7 @@ public ABPerson [] GetPeopleWithName (string name)
720720
var nameHandle = CFString.CreateNative (name);
721721
try {
722722
var cfArrayRef = ABAddressBookCopyPeopleWithName (Handle, nameHandle);
723-
return NSArray.ArrayFromHandle (cfArrayRef, h => new ABPerson (h, this));
723+
return NSArray.ArrayFromHandle (cfArrayRef, h => new ABPerson (h, this), releaseHandle: true);
724724
} finally {
725725
CFString.ReleaseNative (nameHandle);
726726
}
@@ -739,7 +739,7 @@ public ABPerson [] GetPeopleWithName (string name)
739739
public ABSource []? GetAllSources ()
740740
{
741741
var cfArrayRef = ABAddressBookCopyArrayOfAllSources (GetCheckedHandle ());
742-
return NSArray.ArrayFromHandle (cfArrayRef, h => new ABSource (h, this));
742+
return NSArray.ArrayFromHandle (cfArrayRef, h => new ABSource (h, this), releaseHandle: true);
743743
}
744744

745745
[DllImport (Constants.AddressBookLibrary)]

src/AddressBook/ABGroup.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ public IEnumerator<ABRecord> GetEnumerator ()
223223
if (cfArrayRef == IntPtr.Zero)
224224
e = new ABRecord [0];
225225
else
226-
e = NSArray.ArrayFromHandle (cfArrayRef, h => ABRecord.FromHandle (h, AddressBook));
226+
e = NSArray.ArrayFromHandle (cfArrayRef, h => ABRecord.FromHandle (h, AddressBook), releaseHandle: true);
227227
return e.GetEnumerator ();
228228
}
229229

@@ -250,7 +250,7 @@ public ABRecord [] GetMembers (ABPersonSortBy sortOrdering)
250250
var cfArrayRef = ABGroupCopyArrayOfAllMembersWithSortOrdering (Handle, sortOrdering);
251251
if (cfArrayRef == IntPtr.Zero)
252252
return new ABRecord [0];
253-
return NSArray.ArrayFromHandle (cfArrayRef, h => ABRecord.FromHandle (h, AddressBook));
253+
return NSArray.ArrayFromHandle (cfArrayRef, h => ABRecord.FromHandle (h, AddressBook), releaseHandle: true);
254254
}
255255

256256
[DllImport (Constants.AddressBookLibrary)]

src/CoreServices/LaunchServices.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ public static NSUrl [] GetApplicationUrlsForUrl (NSUrl url, LSRoles roles = LSRo
190190
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (url));
191191

192192
var result = NSArray.ArrayFromHandle<NSUrl> (
193-
LSCopyApplicationURLsForURL (url.Handle, roles)
193+
LSCopyApplicationURLsForURL (url.Handle, roles),
194+
releaseHandle: true
194195
);
195196
GC.KeepAlive (url);
196197
return result;
@@ -260,7 +261,8 @@ public static NSUrl [] GetApplicationUrlsForBundleIdentifier (string bundleIdent
260261
var bundleIdentifierHandle = CFString.CreateNative (bundleIdentifier);
261262
try {
262263
return NSArray.ArrayFromHandle<NSUrl> (
263-
LSCopyApplicationURLsForBundleIdentifier (bundleIdentifierHandle, IntPtr.Zero)
264+
LSCopyApplicationURLsForBundleIdentifier (bundleIdentifierHandle, IntPtr.Zero),
265+
releaseHandle: true
264266
);
265267
} finally {
266268
CFString.ReleaseNative (bundleIdentifierHandle);

src/CoreText/CTFontManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static NSArray EnsureNonNullArray (object [] items, string name)
161161
return NSArray.ArrayFromHandle<T> (handle);
162162
} finally {
163163
if (releaseAfterUse)
164-
CFObject.CFRetain (handle);
164+
CFObject.CFRelease (handle);
165165
}
166166
}
167167

src/CoreVideo/CVPixelFormatDescription.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ static CVPixelFormatDescription ()
281281
/// <summary>Get all the known pixel format types.</summary>
282282
public static NSNumber [] AllTypes {
283283
get {
284-
return NSArray.ArrayFromHandle<NSNumber> (CVPixelFormatDescriptionArrayCreateWithAllPixelFormatTypes (IntPtr.Zero));
284+
return NSArray.ArrayFromHandle<NSNumber> (CVPixelFormatDescriptionArrayCreateWithAllPixelFormatTypes (IntPtr.Zero), releaseHandle: true);
285285
}
286286
}
287287

src/Foundation/NSArray.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,28 @@ static public T [] ArrayFromHandle<T> (NativeHandle handle) where T : class, INa
469469
return ret;
470470
}
471471

472+
/// <summary>Returns a strongly-typed C# array of the parametrized type from a handle to an NSArray.</summary>
473+
/// <typeparam name="T">Parameter type, determines the kind of array returned.</typeparam>
474+
/// <param name="handle">Pointer (handle) to the unmanaged object.</param>
475+
/// <param name="releaseHandle">Whether the native NSArray instance should be released before returning or not.</param>
476+
/// <returns>A C# array with the values.</returns>
477+
/// <remarks>
478+
/// <para>Use this method to get a set of NSObject arrays from a handle to an NSArray</para>
479+
/// <example>
480+
/// <code lang="c#"><![CDATA[
481+
/// var someHandle = GetCopyOfNativeArray (...);
482+
/// var values = NSArray.ArrayFromHandle<NSString> (someHandle, releaseHandle: true);
483+
/// ]]></code>
484+
/// </example>
485+
/// </remarks>
486+
public static T [] ArrayFromHandle<T> (NativeHandle handle, bool releaseHandle) where T : class, INativeObject
487+
{
488+
var rv = ArrayFromHandle<T> (handle);
489+
if (releaseHandle && handle != NativeHandle.Zero)
490+
NSObject.DangerousRelease (handle);
491+
return rv;
492+
}
493+
472494
static Array ArrayFromHandle (NativeHandle handle, Type elementType)
473495
{
474496
if (handle == NativeHandle.Zero)

src/Security/SecTrust.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public SecPolicy [] GetPolicies ()
6161
}
6262
if (result != SecStatusCode.Success)
6363
throw new InvalidOperationException (result.ToString ());
64-
return NSArray.ArrayFromHandle<SecPolicy> (p);
64+
return NSArray.ArrayFromHandle<SecPolicy> (p, releaseHandle: true);
6565
}
6666

6767
[DllImport (Constants.SecurityLibrary)]
@@ -173,7 +173,7 @@ public SecCertificate [] GetCustomAnchorCertificates ()
173173
}
174174
if (result != SecStatusCode.Success)
175175
throw new InvalidOperationException (result.ToString ());
176-
return NSArray.ArrayFromHandle<SecCertificate> (p);
176+
return NSArray.ArrayFromHandle<SecCertificate> (p, releaseHandle: true);
177177
}
178178

179179
[SupportedOSPlatform ("ios")]

src/Security/Trust.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public SecCertificate this [nint index] {
239239
[SupportedOSPlatform ("ios15.0")]
240240
[SupportedOSPlatform ("maccatalyst")]
241241
public SecCertificate [] GetCertificateChain ()
242-
=> NSArray.ArrayFromHandle<SecCertificate> (SecTrustCopyCertificateChain (Handle));
242+
=> NSArray.ArrayFromHandle<SecCertificate> (SecTrustCopyCertificateChain (Handle), releaseHandle: true);
243243

244244
[SupportedOSPlatform ("ios")]
245245
[SupportedOSPlatform ("maccatalyst")]

0 commit comments

Comments
 (0)