From 13805614e6ed2131827bfa6c668b50a1b30da1e5 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Wed, 10 Feb 2010 01:32:05 +0000 Subject: Fix a number of memory leaks, and over-releases, as both a result of manual inspection of leaks and Clang static analysis. --- Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h | 2 +- Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m | 40 ++++++++++++---------- Frameworks/MCPKit/MCPFoundationKit/MCPResult.m | 6 ++-- Source/CMTextView.m | 4 +-- Source/SPContentFilterManager.m | 2 ++ Source/SPFavoriteTextFieldCell.m | 12 +++---- Source/SPKeychain.m | 2 +- Source/SPQueryController.m | 2 +- Source/SPTableData.m | 4 ++- Source/SPTooltip.m | 2 +- Source/TableDocument.m | 2 +- Source/TableDump.m | 10 ++++-- Source/TablesList.m | 9 ++--- 13 files changed, 55 insertions(+), 42 deletions(-) diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h index 68875bb7..84b18a26 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h @@ -230,7 +230,7 @@ void performThreadedKeepAlive(void *ptr); - (MCPResult *)listFieldsFromTable:(NSString *)tableName like:(NSString *)fieldsName; - (void)queryDbStructure; - (NSDictionary *)getDbStructure; -- (NSInteger)getUniqueDbIndentifierFor:(NSString*)term; +- (NSInteger)getUniqueDbIdentifierFor:(NSString*)term; // Server information - (NSString *)clientInfo; diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m index 1911e1e1..8cb80048 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m @@ -111,6 +111,7 @@ static BOOL sTruncateLongFieldInLogs = YES; keepAliveInterval = 60; theDbStructure = nil; + uniqueDbIdentifier = nil; isQueryingDbStructure = NO; connectionThreadId = 0; @@ -281,7 +282,7 @@ static BOOL sTruncateLongFieldInLogs = YES; { const char *theLogin = [self cStringFromString:connectionLogin]; const char *theHost; - const char *thePass; + const char *thePass = NULL; const char *theSocket; void *theRet; @@ -380,6 +381,7 @@ static BOOL sTruncateLongFieldInLogs = YES; if (serverVersionString) [serverVersionString release], serverVersionString = nil; if (theDbStructure) [theDbStructure release], theDbStructure = nil; + if (uniqueDbIdentifier) [uniqueDbIdentifier release], uniqueDbIdentifier = nil; [self stopKeepAliveTimer]; } @@ -1375,6 +1377,7 @@ void performThreadedKeepAlive(void *ptr) // If this query has failed once already, check the connection if (isQueryRetry) { if (![self checkConnection]) { + if (queryErrorMessage) [queryErrorMessage release], queryErrorMessage = nil; // Notify that the query has been performed [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:delegate]; @@ -1536,7 +1539,7 @@ void performThreadedKeepAlive(void *ptr) if (killerConnection) { const char *theLogin = [self cStringFromString:connectionLogin]; const char *theHost; - const char *thePass; + const char *thePass = NULL; const char *theSocket; void *connectionSetupStatus; @@ -1658,7 +1661,7 @@ void performThreadedKeepAlive(void *ptr) { if (!mConnected) return NO; - MCPResult *theResult = [MCPResult alloc]; + MCPResult *theResult = nil; MYSQL_RES *theResPtr; [self stopKeepAliveTimer]; @@ -1670,20 +1673,20 @@ void performThreadedKeepAlive(void *ptr) [queryLock lock]; if ((dbsName == nil) || ([dbsName isEqualToString:@""])) { if (theResPtr = mysql_list_dbs(mConnection, NULL)) { - [theResult initWithResPtr: theResPtr encoding: mEncoding timeZone:mTimeZone]; + theResult = [[MCPResult alloc] initWithResPtr: theResPtr encoding: mEncoding timeZone:mTimeZone]; } else { - [theResult init]; + theResult = [[MCPResult alloc] init]; } } else { const char *theCDBsName = (const char *)[self cStringFromString:dbsName]; if (theResPtr = mysql_list_dbs(mConnection, theCDBsName)) { - [theResult initWithResPtr:theResPtr encoding:mEncoding timeZone:mTimeZone]; + theResult = [[MCPResult alloc] initWithResPtr:theResPtr encoding:mEncoding timeZone:mTimeZone]; } else { - [theResult init]; + theResult = [[MCPResult alloc] init]; } } [queryLock unlock]; @@ -1715,7 +1718,7 @@ void performThreadedKeepAlive(void *ptr) { if (!mConnected) return NO; - MCPResult *theResult = [MCPResult alloc]; + MCPResult *theResult = nil; MYSQL_RES *theResPtr; [self stopKeepAliveTimer]; @@ -1727,19 +1730,19 @@ void performThreadedKeepAlive(void *ptr) [queryLock lock]; if ((tablesName == nil) || ([tablesName isEqualToString:@""])) { if (theResPtr = mysql_list_tables(mConnection, NULL)) { - [theResult initWithResPtr: theResPtr encoding: mEncoding timeZone:mTimeZone]; + theResult = [[MCPResult alloc] initWithResPtr: theResPtr encoding: mEncoding timeZone:mTimeZone]; } else { - [theResult init]; + theResult = [[MCPResult alloc] init]; } } else { const char *theCTablesName = (const char *)[self cStringFromString:tablesName]; if (theResPtr = mysql_list_tables(mConnection, theCTablesName)) { - [theResult initWithResPtr: theResPtr encoding: mEncoding timeZone:mTimeZone]; + theResult = [[MCPResult alloc] initWithResPtr: theResPtr encoding: mEncoding timeZone:mTimeZone]; } else { - [theResult init]; + theResult = [[MCPResult alloc] init]; } } @@ -1818,7 +1821,7 @@ void performThreadedKeepAlive(void *ptr) if (structConnection) { const char *theLogin = [self cStringFromString:connectionLogin]; const char *theHost; - const char *thePass; + const char *thePass = NULL; const char *theSocket; void *connectionSetupStatus; @@ -1957,9 +1960,9 @@ void performThreadedKeepAlive(void *ptr) * Otherwise it return 0. Mainly used for completion to know whether a `foo`. can only be * a db name or a table name. */ -- (NSInteger)getUniqueDbIndentifierFor:(NSString*)term +- (NSInteger)getUniqueDbIdentifierFor:(NSString*)term { - if([uniqueDbIdentifier objectForKey:term]) + if(uniqueDbIdentifier && [uniqueDbIdentifier objectForKey:term]) return [[uniqueDbIdentifier objectForKey:term] integerValue]; else return 0; @@ -2017,15 +2020,15 @@ void performThreadedKeepAlive(void *ptr) */ - (MCPResult *)listProcesses { - MCPResult *theResult = [MCPResult alloc]; + MCPResult *theResult = nil; MYSQL_RES *theResPtr; [queryLock lock]; if (theResPtr = mysql_list_processes(mConnection)) { - [theResult initWithResPtr:theResPtr encoding:mEncoding timeZone:mTimeZone]; + theResult = [[MCPResult alloc] initWithResPtr:theResPtr encoding:mEncoding timeZone:mTimeZone]; } else { - [theResult init]; + theResult = [[MCPResult alloc] init]; } [queryLock unlock]; @@ -2395,6 +2398,7 @@ void performThreadedKeepAlive(void *ptr) if (connectionPassword) [connectionPassword release]; if (serverVersionString) [serverVersionString release], serverVersionString = nil; if (theDbStructure) [theDbStructure release], theDbStructure = nil; + if (uniqueDbIdentifier) [uniqueDbIdentifier release], uniqueDbIdentifier = nil; [super dealloc]; } diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m index 98f26b6c..4e3fef3a 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m @@ -866,7 +866,7 @@ const OUR_CHARSET our_charsets60[] = - (NSUInteger)fetchFlagsForKey:(NSString *)key { NSUInteger theRet; - NSUInteger theNumFields, index; + NSUInteger index; MYSQL_FIELD *theField; if (mResult == NULL) { @@ -878,7 +878,6 @@ const OUR_CHARSET our_charsets60[] = [self fetchFieldNames]; } - theNumFields = [self numOfFields]; theField = mysql_fetch_fields(mResult); if ([mNames indexOfObject:key] == NSNotFound) { @@ -952,7 +951,7 @@ const OUR_CHARSET our_charsets60[] = - (BOOL)isBlobForKey:(NSString *)key { BOOL theRet; - NSUInteger theNumFields, index; + NSUInteger index; MYSQL_FIELD *theField; if (mResult == NULL) { @@ -964,7 +963,6 @@ const OUR_CHARSET our_charsets60[] = [self fetchFieldNames]; } - theNumFields = [self numOfFields]; theField = mysql_fetch_fields(mResult); if ([mNames indexOfObject:key] == NSNotFound) { diff --git a/Source/CMTextView.m b/Source/CMTextView.m index c95d7d1f..474b0af9 100644 --- a/Source/CMTextView.m +++ b/Source/CMTextView.m @@ -314,7 +314,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) // Add structural db/table/field data to completions list or fallback to gathering TablesList data NSDictionary *dbs = [NSDictionary dictionaryWithDictionary:[mySQLConnection getDbStructure]]; if(dbs != nil && [dbs count]) { - NSMutableArray *allDbs = [[NSMutableArray array] autorelease]; + NSMutableArray *allDbs = [NSMutableArray array]; [allDbs addObjectsFromArray:[dbs allKeys]]; // Add database names having no tables since they don't appear in the information_schema @@ -356,7 +356,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) if(!aDbName) { // Try to suggest only items which are uniquely valid for the parsed string - NSInteger uniqueSchemaKind = [mySQLConnection getUniqueDbIndentifierFor:[aTableName lowercaseString]]; + NSInteger uniqueSchemaKind = [mySQLConnection getUniqueDbIdentifierFor:[aTableName lowercaseString]]; // If no db name but table name check if table name is a valid name in the current selected db if(aTableName && [aTableName length] && [dbs objectForKey:currentDb] && [[dbs objectForKey:currentDb] objectForKey:aTableName] && uniqueSchemaKind == 2) { diff --git a/Source/SPContentFilterManager.m b/Source/SPContentFilterManager.m index 34a3b214..8e3fa5fe 100644 --- a/Source/SPContentFilterManager.m +++ b/Source/SPContentFilterManager.m @@ -792,6 +792,7 @@ // } [contentFilterArrayController rearrangeObjects]; [contentFilterTableView reloadData]; + [spf release]; } else { NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Error while reading data file", @"error while reading data file")] defaultButton:NSLocalizedString(@"OK", @"OK button") @@ -801,6 +802,7 @@ [alert setAlertStyle:NSInformationalAlertStyle]; [alert runModal]; + [spf release]; return; } } diff --git a/Source/SPFavoriteTextFieldCell.m b/Source/SPFavoriteTextFieldCell.m index ea460af0..355ee459 100644 --- a/Source/SPFavoriteTextFieldCell.m +++ b/Source/SPFavoriteTextFieldCell.m @@ -121,8 +121,8 @@ (([self isHighlighted]) && (![[self highlightColorWithFrame:cellFrame inView:controlView] isEqualTo:[NSColor secondarySelectedControlColor]])) ? [self invertFontColors] : [self restoreFontColors]; // Construct and get the sub text attributed string - NSAttributedString *mainString = [[self attributedStringForFavoriteName] autorelease]; - NSAttributedString *subString = [[self constructSubStringAttributedString] autorelease]; + NSAttributedString *mainString = [self attributedStringForFavoriteName]; + NSAttributedString *subString = [self constructSubStringAttributedString]; NSRect subFrame = NSMakeRect(0.0, 0.0, [subString size].width, [subString size].height); @@ -169,8 +169,8 @@ - (NSSize)cellSize { NSSize cellSize = [super cellSize]; - NSAttributedString *mainString = [[self attributedStringForFavoriteName] autorelease]; - NSAttributedString *subString = [[self constructSubStringAttributedString] autorelease]; + NSAttributedString *mainString = [self attributedStringForFavoriteName]; + NSAttributedString *subString = [self constructSubStringAttributedString]; // 15 := indention 10 from image to string plus 5 px padding CGFloat theWidth = MAX([mainString size].width, [subString size].width) + (([self image] != nil) ? [[self image] size].width : 0) + 15; @@ -225,7 +225,7 @@ // ------------------------------------------------------------------------------- - (NSAttributedString *)constructSubStringAttributedString { - return [[NSAttributedString alloc] initWithString:favoriteHost attributes:[self subStringAttributedStringAttributes]]; + return [[[NSAttributedString alloc] initWithString:favoriteHost attributes:[self subStringAttributedStringAttributes]] autorelease]; } // ------------------------------------------------------------------------------- @@ -235,7 +235,7 @@ // ------------------------------------------------------------------------------- - (NSAttributedString *)attributedStringForFavoriteName { - return [[NSAttributedString alloc] initWithString:favoriteName attributes:[self mainStringAttributedStringAttributes]]; + return [[[NSAttributedString alloc] initWithString:favoriteName attributes:[self mainStringAttributedStringAttributes]] autorelease]; } // ------------------------------------------------------------------------------- diff --git a/Source/SPKeychain.m b/Source/SPKeychain.m index 622c3a86..a6550ec6 100644 --- a/Source/SPKeychain.m +++ b/Source/SPKeychain.m @@ -45,7 +45,7 @@ { OSStatus status; SecTrustedApplicationRef sequelProRef, sequelProHelperRef; - SecAccessRef passwordAccessRef; + SecAccessRef passwordAccessRef = NULL; SecKeychainAttribute attributes[4]; SecKeychainAttributeList attList; diff --git a/Source/SPQueryController.m b/Source/SPQueryController.m index 0ff0fac7..2eddf018 100644 --- a/Source/SPQueryController.m +++ b/Source/SPQueryController.m @@ -653,7 +653,7 @@ static SPQueryController *sharedQueryController = nil; - (NSArray *)historyMenuItemsForFileURL:(NSURL *)fileURL { if([historyContainer objectForKey:[fileURL absoluteString]]) { - NSMutableArray *returnArray = [[NSMutableArray arrayWithCapacity:[[historyContainer objectForKey:[fileURL absoluteString]] count]] autorelease]; + NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:[[historyContainer objectForKey:[fileURL absoluteString]] count]]; NSMenuItem *historyMenuItem; for(id history in [historyContainer objectForKey:[fileURL absoluteString]]) { historyMenuItem = [[[NSMenuItem alloc] initWithTitle:([history length] > 64) ? [NSString stringWithFormat:@"%@…", [history substringToIndex:63]] : history diff --git a/Source/SPTableData.m b/Source/SPTableData.m index 82b7a9da..fe13e4f3 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -583,7 +583,9 @@ [NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving the information for table '%@'. Please try again.\n\nMySQL said: %@", @"error retrieving table information informative message"), tableName, [mySQLConnection getLastErrorMessage]]); } - + [tableColumns release]; + [encodingString release]; + return nil; } diff --git a/Source/SPTooltip.m b/Source/SPTooltip.m index 90f4b202..07162db8 100644 --- a/Source/SPTooltip.m +++ b/Source/SPTooltip.m @@ -122,7 +122,7 @@ static CGFloat slow_in_out (CGFloat t) spTooltipCounter++; - SPTooltip* tip = [SPTooltip new]; + SPTooltip* tip = [SPTooltip new]; // Automatically released on close [tip initMeWithOptions:displayOptions]; [tip setFrameTopLeftPoint:point]; diff --git a/Source/TableDocument.m b/Source/TableDocument.m index 28a5bae8..f8c0fe69 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -848,7 +848,7 @@ [connection setValue:versionForPrint forKey:@"version"]; NSArray *columns, *rows; - columns = rows = nil; + rows = nil; columns = [self columnNames]; if ( [tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 0 ){ diff --git a/Source/TableDump.m b/Source/TableDump.m index 04942462..2e055f94 100644 --- a/Source/TableDump.m +++ b/Source/TableDump.m @@ -1746,7 +1746,10 @@ NSString *procedureName = [NSString stringWithFormat:@"%@", [proceduresList objectForKey:@"Name"]]; // Only proceed if the item was selected for export - if (![selectedItems containsObject:procedureName]) continue; + if (![selectedItems containsObject:procedureName]) { + [proceduresList release]; + continue; + } // Add the "drop" command if specified in the export dialog if ([addDropTableSwitch state] == NSOnState) { @@ -1756,7 +1759,10 @@ } // Only continue if the "create syntax" is specified in the export dialog - if ([addCreateTableSwitch state] == NSOffState) continue; + if ([addCreateTableSwitch state] == NSOffState) { + [proceduresList release]; + continue; + } //Definer is user@host but we need to escape it to `user`@`host` NSArray *procedureDefiner = [[proceduresList objectForKey:@"Definer"] componentsSeparatedByString:@"@"]; diff --git a/Source/TablesList.m b/Source/TablesList.m index dd675c43..b66af9fb 100644 --- a/Source/TablesList.m +++ b/Source/TablesList.m @@ -2005,19 +2005,21 @@ } else { //insert new table name in create syntax and create new table - NSScanner *scanner = [NSScanner alloc]; + NSScanner *scanner; NSString *scanString; if(tblType == SP_TABLETYPE_VIEW){ - [scanner initWithString:[[queryResult fetchRowAsDictionary] objectForKey:@"Create View"]]; + scanner = [[NSScanner alloc] initWithString:[[queryResult fetchRowAsDictionary] objectForKey:@"Create View"]]; [scanner scanUpToString:@"AS" intoString:nil]; [scanner scanUpToString:@"" intoString:&scanString]; + [scanner release]; [mySQLConnection queryString:[NSString stringWithFormat:@"CREATE VIEW %@ %@", [[copyTableNameField stringValue] backtickQuotedString], scanString]]; } else if(tblType == SP_TABLETYPE_TABLE){ - [scanner initWithString:[[queryResult fetchRowAsDictionary] objectForKey:@"Create Table"]]; + scanner = [[NSScanner alloc] initWithString:[[queryResult fetchRowAsDictionary] objectForKey:@"Create Table"]]; [scanner scanUpToString:@"(" intoString:nil]; [scanner scanUpToString:@"" intoString:&scanString]; + [scanner release]; // If there are any InnoDB referencial constraints we need to strip out the names as they must be unique. // MySQL will generate the new names based on the new table name. @@ -2062,7 +2064,6 @@ } } - [scanner release]; if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) { //error while creating new table -- cgit v1.2.3