From 2f2aafb4f5675282a37d16dce96027706096df40 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 31 Oct 2015 02:54:59 +0100 Subject: * Basic math is hard sometimes (fixes an issue introduced by me in b2d798ba9282d3acf1a2d65de30849e529d4d255) * Fix an exception that could occur when trying to view a damaged table * Fix a theoretical use-after-free issue by a wrongly structured retain/release in a setter --- .../Source/SPMySQLConnection Categories/Server Info.m | 2 +- Source/SPDatabaseData.m | 3 +++ Source/SPDatabaseDocument.m | 6 +++--- Source/SPTableContent.m | 14 ++++++++------ Source/SPTableData.m | 14 ++++++++++++-- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Server Info.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Server Info.m index 01410eb5..5925d138 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Server Info.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Server Info.m @@ -87,7 +87,7 @@ { unsigned long myver = aMajorVersion * 10000 + aMinorVersion * 100 + aReleaseVersion; - return (myver >= serverVersionNumber); + return (serverVersionNumber >= myver); } #pragma mark - diff --git a/Source/SPDatabaseData.m b/Source/SPDatabaseData.m index 0cbb756a..965dfcb5 100644 --- a/Source/SPDatabaseData.m +++ b/Source/SPDatabaseData.m @@ -471,6 +471,9 @@ copy_return: [result setReturnDataAsStrings:YES]; + if([connection queryErrored]) + SPLog(@"server variable lookup failed for '%@': %@ (%lu)",variable,[connection lastErrorMessage],[connection lastErrorID]); + if ([result numberOfRows] != 1) return nil; diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m index 2f7a5235..76dda407 100644 --- a/Source/SPDatabaseDocument.m +++ b/Source/SPDatabaseDocument.m @@ -1729,20 +1729,20 @@ static int64_t SPDatabaseDocumentInstanceCounter = 0; { _supportsEncoding = YES; - NSString *mysqlEncoding = [databaseDataInstance getDatabaseDefaultCharacterSet]; + NSString *mysqlEncoding = [[databaseDataInstance getDatabaseDefaultCharacterSet] retain]; SPClear(selectedDatabaseEncoding); // Fallback or older version? -> set encoding to mysql default encoding latin1 if ( !mysqlEncoding ) { - NSLog(@"Error: no character encoding found, mysql version is %@", [self mySQLVersion]); + NSLog(@"Error: no character encoding found for db, mysql version is %@", [self mySQLVersion]); selectedDatabaseEncoding = [[NSString alloc] initWithString:@"latin1"]; _supportsEncoding = NO; } else { - selectedDatabaseEncoding = [mysqlEncoding retain]; + selectedDatabaseEncoding = mysqlEncoding; } } diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index 14bae14a..095f89ee 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -434,7 +434,8 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper [tableContentView scrollColumnToVisible:0]; // Set the maximum table rows to an estimated count pre-load - maxNumRows = [[tableDataInstance statusValueForKey:@"Rows"] integerValue]; + NSString *rows = [tableDataInstance statusValueForKey:@"Rows"]; + maxNumRows = (rows && ![rows isNSNull])? [rows integerValue] : 0; maxNumRowsIsEstimate = YES; } @@ -3991,14 +3992,15 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper [tableDataInstance updateAccurateNumberOfRowsForCurrentTableForcingUpdate:NO]; // If the state is now accurate, use it + NSString *rows = [tableDataInstance statusValueForKey:@"Rows"]; if ([[tableDataInstance statusValueForKey:@"RowsCountAccurate"] boolValue]) { - maxNumRows = [[tableDataInstance statusValueForKey:@"Rows"] integerValue]; + maxNumRows = [rows integerValue]; maxNumRowsIsEstimate = NO; checkStatusCount = YES; - - // Otherwise, use the estimate count - } else { - maxNumRows = [[tableDataInstance statusValueForKey:@"Rows"] integerValue]; + } + // Otherwise, use the estimate count + else { + maxNumRows = (rows && ![rows isNSNull])? [rows integerValue] : 0; maxNumRowsIsEstimate = YES; checkStatusCount = YES; } diff --git a/Source/SPTableData.m b/Source/SPTableData.m index a40225d0..51c6a274 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -1004,7 +1004,7 @@ SPOnewayAlertSheet( NSLocalizedString(@"Error", @"error"), [NSApp mainWindow], - [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving status data.\nMySQL said: %@", @"message of panel when retrieving view information failed"), [mySQLConnection lastErrorMessage]] + [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving status data.\n\nMySQL said: %@", @"message of panel when retrieving view information failed"), [mySQLConnection lastErrorMessage]] ); if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } @@ -1041,9 +1041,19 @@ // this happens e.g. for db "information_schema" if([[status objectForKey:@"Rows"] isNSNull]) { tableStatusResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [escapedTableName backtickQuotedString] ]]; - if (![mySQLConnection queryErrored]) + // this query can fail e.g. if a table is damaged + if (tableStatusResult && ![mySQLConnection queryErrored]) { [status setObject:[[tableStatusResult getRowAsArray] objectAtIndex:0] forKey:@"Rows"]; [status setObject:@"y" forKey:@"RowsCountAccurate"]; + } + else { + //FIXME that error should really show only when trying to view the table content, but we don't even try to load that if Rows==NULL + SPOnewayAlertSheet( + NSLocalizedString(@"Querying row count failed", @"table status : row count query failed : error title"), + [NSApp mainWindow], + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to determine the number of rows for “%@”.\nMySQL said: %@ (%lu)", @"table status : row count query failed : error message"),[tableListInstance tableName],[mySQLConnection lastErrorMessage],[mySQLConnection lastErrorID]] + ); + } } } -- cgit v1.2.3