From 1fd58aef7a1787292ac54d4fb61b4efeae9cacd3 Mon Sep 17 00:00:00 2001 From: Tony Parker Date: Mon, 30 Jun 2025 16:15:27 -0700 Subject: [PATCH] Make sure to free the malloced pointer even in case of throwing an error. Resolves rdar://154702045 --- .../Data/Data+Base64.swift | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Sources/FoundationEssentials/Data/Data+Base64.swift b/Sources/FoundationEssentials/Data/Data+Base64.swift index 757edcb76..fb0960f96 100644 --- a/Sources/FoundationEssentials/Data/Data+Base64.swift +++ b/Sources/FoundationEssentials/Data/Data+Base64.swift @@ -490,15 +490,21 @@ extension Base64 { let other = pointer?.bindMemory(to: UInt8.self, capacity: outputLength) let target = UnsafeMutableBufferPointer(start: other, count: outputLength) var length = outputLength - if options.contains(.ignoreUnknownCharacters) { - try Self._decodeIgnoringErrors(from: inBuffer, into: target, length: &length, options: options) - } else { - // for whatever reason I can see this being 10% faster for larger payloads. Maybe better - // branch prediction? - try self._decode(from: inBuffer, into: target, length: &length, options: options) + do { + if options.contains(.ignoreUnknownCharacters) { + try Self._decodeIgnoringErrors(from: inBuffer, into: target, length: &length, options: options) + } else { + // for whatever reason I can see this being 10% faster for larger payloads. Maybe better + // branch prediction? + try self._decode(from: inBuffer, into: target, length: &length, options: options) + } + + return Data(bytesNoCopy: pointer!, count: length, deallocator: .free) + } catch { + // Do not leak the malloc on error + free(pointer) + throw error } - - return Data(bytesNoCopy: pointer!, count: length, deallocator: .free) } static func _decode(