From 7302ee18a137f6810ef1cc40a395f99d2f46a644 Mon Sep 17 00:00:00 2001 From: Tobias Markmann <tm@ayena.de> Date: Tue, 3 Nov 2015 13:20:20 +0100 Subject: Fix potential memory leaks in Cocoa API usage These errors were reported by Clang Analyzer. Test-Information: Verified that behavior is still as expected and Clang Analyzer does not report the warnings anymore. Change-Id: I149d75241f7680a6d2f2b6b710dd38d1ed81a209 diff --git a/SwifTools/Notifier/NotificationCenterNotifier.mm b/SwifTools/Notifier/NotificationCenterNotifier.mm index 28cacb6..74d814e 100644 --- a/SwifTools/Notifier/NotificationCenterNotifier.mm +++ b/SwifTools/Notifier/NotificationCenterNotifier.mm @@ -57,23 +57,25 @@ void NotificationCenterNotifier::showMessage(Type type, const std::string& subje if (std::find(defaultTypes.begin(), defaultTypes.end(), type) == defaultTypes.end()) { return; } - + NSImage* image = [[NSImage alloc] initWithContentsOfFile: STD2NSSTRING(picture.string())]; NSUserNotification* notification = [[NSUserNotification alloc] init]; - notification.title = STD2NSSTRING(typeToString(type)); - notification.subtitle = STD2NSSTRING(subject); - notification.informativeText = STD2NSSTRING(description); - notification.contentImage = [[NSImage alloc] initWithContentsOfFile: STD2NSSTRING(picture.string())]; + [notification setTitle:STD2NSSTRING(typeToString(type))]; + [notification setSubtitle:STD2NSSTRING(subject)]; + [notification setInformativeText:STD2NSSTRING(description)]; + [notification setContentImage: image]; + [image release]; // The OS X Notification Center API does not allow to attach custom data, like a pointer to a callback function, // to the NSUserNotification object. Therefore we maintain a mapping from a NSUserNotification instance's identification // to their respective callbacks. - notification.identifier = [[NSUUID UUID] UUIDString]; + [notification setIdentifier:[[NSUUID UUID] UUIDString]]; /// \todo Currently the elements are only removed on application exit. Ideally the notifications not required anymore /// are removed from the map; e.g. when visiting a chat view, all notifications from that view can be removed from /// the map and the NSUserNotificationCenter. p->callbacksForNotifications[NS2STDSTRING(notification.identifier)] = boost::make_shared<Context>(callback); [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; + [notification release]; } void NotificationCenterNotifier::purgeCallbacks() { diff --git a/Swiften/TLS/SecureTransport/SecureTransportCertificate.mm b/Swiften/TLS/SecureTransport/SecureTransportCertificate.mm index 3b4e00f..4270a6f 100644 --- a/Swiften/TLS/SecureTransport/SecureTransportCertificate.mm +++ b/Swiften/TLS/SecureTransport/SecureTransportCertificate.mm @@ -38,6 +38,7 @@ SecureTransportCertificate::SecureTransportCertificate(SecCertificateRef certifi SecureTransportCertificate::SecureTransportCertificate(const ByteArray& der) { CFDataRef derData = CFDataCreateWithBytesNoCopy(NULL, der.data(), static_cast<CFIndex>(der.size()), NULL); SecCertificateRef certificate = SecCertificateCreateWithData(NULL, derData); + CFRelease(derData); if (certificate) { certificateHandle_ = boost::shared_ptr<SecCertificate>(certificate, CFRelease); parse(); @@ -57,10 +58,7 @@ void SecureTransportCertificate::parse() { // The SecCertificateCopyValues function is not part of the iOS Secure Transport API. CFDictionaryRef valueDict = SecCertificateCopyValues(certificateHandle_.get(), 0, &error); - if (error) { - CFRelease(error); - } - else { + if (valueDict) { // Handle subject. CFStringRef subject = SecCertificateCopySubjectSummary(certificateHandle_.get()); if (subject) { @@ -70,11 +68,13 @@ void SecureTransportCertificate::parse() { } // Handle a single Common Name. - CFStringRef commonName; + CFStringRef commonName = NULL; OSStatus error = SecCertificateCopyCommonName(certificateHandle_.get(), &commonName); - if (!error) { + if (!error && commonName) { NSString* commonNameStr = bridge_cast<NSString*>(commonName); commonNames_.push_back(NS2STDSTRING(commonNameStr)); + } + if (commonName) { CFRelease(commonName); } @@ -95,6 +95,10 @@ void SecureTransportCertificate::parse() { } CFRelease(valueDict); } + + if (error) { + CFRelease(error); + } } std::string SecureTransportCertificate::getSubjectName() const { diff --git a/Swiften/TLS/SecureTransport/SecureTransportContext.mm b/Swiften/TLS/SecureTransport/SecureTransportContext.mm index 7f44f7d..a702cde 100644 --- a/Swiften/TLS/SecureTransport/SecureTransportContext.mm +++ b/Swiften/TLS/SecureTransport/SecureTransportContext.mm @@ -38,7 +38,7 @@ namespace Swift { namespace { -CFArrayRef getClientCertificateChainAsCFArrayRef(CertificateWithKey::ref key) { +CFArrayRef CreateClientCertificateChainAsCFArrayRef(CertificateWithKey::ref key) { boost::shared_ptr<PKCS12Certificate> pkcs12 = boost::dynamic_pointer_cast<PKCS12Certificate>(key); if (!key) { return NULL; @@ -64,6 +64,7 @@ CFArrayRef getClientCertificateChainAsCFArrayRef(CertificateWithKey::ref key) { CFArrayRef items = NULL; CFDataRef pkcs12Data = bridge_cast<CFDataRef>([NSData dataWithBytes: static_cast<const void *>(pkcs12->getData().data()) length:pkcs12->getData().size()]); securityError = SecPKCS12Import(pkcs12Data, options, &items); + CFRelease(options); NSArray* nsItems = bridge_cast<NSArray*>(items); switch(securityError) { @@ -76,7 +77,6 @@ CFArrayRef getClientCertificateChainAsCFArrayRef(CertificateWithKey::ref key) { default: CFRelease(certChain); CFRelease(items); - CFRelease(options); certChain = NULL; } @@ -150,7 +150,7 @@ void SecureTransportContext::setState(State newState) { void SecureTransportContext::connect() { SWIFT_LOG_ASSERT(state_ == None, error) << "current state '" << stateToString(state_) << " invalid." << std::endl; if (clientCertificate_) { - CFArrayRef certs = getClientCertificateChainAsCFArrayRef(clientCertificate_); + CFArrayRef certs = CreateClientCertificateChainAsCFArrayRef(clientCertificate_); if (certs) { boost::shared_ptr<CFArray> certRefs(certs, CFRelease); OSStatus result = SSLSetCertificate(sslContext_.get(), certRefs.get()); @@ -274,7 +274,7 @@ void SecureTransportContext::verifyServerCertificate() { #pragma clang diagnostic pop bool SecureTransportContext::setClientCertificate(CertificateWithKey::ref cert) { - CFArrayRef nativeClientChain = getClientCertificateChainAsCFArrayRef(cert); + CFArrayRef nativeClientChain = CreateClientCertificateChainAsCFArrayRef(cert); if (nativeClientChain) { clientCertificate_ = cert; CFRelease(nativeClientChain); -- cgit v0.10.2-6-g49f6