diff options
3 files changed, 98 insertions, 5 deletions
diff --git a/Frameworks/SPMySQLFramework/SPMySQL Unit Tests/SPMySQLStringAdditions_Tests.m b/Frameworks/SPMySQLFramework/SPMySQL Unit Tests/SPMySQLStringAdditions_Tests.m new file mode 100644 index 00000000..cc1f44dd --- /dev/null +++ b/Frameworks/SPMySQLFramework/SPMySQL Unit Tests/SPMySQLStringAdditions_Tests.m @@ -0,0 +1,89 @@ +// +// SPMySQLStringAdditions_Tests.m +// SPMySQLFramework +// +// Created by Max Lohrmann on 04.10.15. +// +// + +#import <Cocoa/Cocoa.h> +#import <XCTest/XCTest.h> +#import <SPMySQL/SPMySQL.h> + +@interface SPMySQLStringAdditions_Tests : XCTestCase + +- (void)test_mySQLBacktickQuotedString; +- (void)test_mySQLTickQuotedString; +- (void)test_stringForDataBytesLengthEncoding; + +@end + +@implementation SPMySQLStringAdditions_Tests + +- (void)test_mySQLBacktickQuotedString +{ + XCTAssertEqualObjects([@"" mySQLBacktickQuotedString], @"``",@"empty string"); + + XCTAssertEqualObjects([@"tbl1" mySQLBacktickQuotedString], @"`tbl1`", @"regular string"); + + XCTAssertEqualObjects([@"tbl`1" mySQLBacktickQuotedString], @"`tbl``1`",@"string with control character"); + + XCTAssertEqualObjects([@"tbl``" mySQLBacktickQuotedString], @"`tbl`````",@"string with escaped control character at end"); +} + +- (void)test_mySQLTickQuotedString +{ + XCTAssertEqualObjects([@"" mySQLTickQuotedString], @"''",@"empty string"); + + XCTAssertEqualObjects([@"tbl1" mySQLTickQuotedString], @"'tbl1'", @"regular string"); + + XCTAssertEqualObjects([@"tbl'1" mySQLTickQuotedString], @"'tbl''1'",@"string with control character"); + + XCTAssertEqualObjects([@"tbl''" mySQLTickQuotedString], @"'tbl'''''",@"string with escaped control character at end"); +} + +- (void)test_stringForDataBytesLengthEncoding +{ + { + const char chr = '\0'; + NSString *conv = [NSString stringForDataBytes:&chr length:0 encoding:NSISOLatin1StringEncoding]; + XCTAssertEqualObjects(conv, @"",@"empty string test"); + } + { + const char *cstr = "an ASCII C string"; + NSString *conv = [NSString stringForDataBytes:cstr length:strlen(cstr) encoding:NSASCIIStringEncoding]; + XCTAssertEqualObjects(conv, @"an ASCII C string", @"simple ASCII string test"); + } + { + // the euro sign is the tricky part + // ISO-8859-1 (aka Latin1): not supported, codepoint 0x80 is not in use + // ISO-8859-1 + ISO/IEC 6429: not supported, codepoint 0x80 is PAD control character + // ISO-8859-15 (aka Latin9): € is at 0xA4, codepoint 0x80 is PAD control character + // Windows cp1252 (aka latin1 in mysql): € is at 0x80, codepoint 0xA4 is "¤" + const char cstr[] = {'\xE4','-','\xDF','-','\x80','\0'}; + NSString *conv = [NSString stringForDataBytes:cstr length:strlen(cstr) encoding:NSWindowsCP1252StringEncoding]; + XCTAssertEqualObjects(conv, @"ä-ß-€",@"handling of cp1252 special characters"); + + unsigned char latin9 = 0xA4; + NSString *conv2 = [NSString stringForDataBytes:&latin9 length:1 encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatin9)]; + XCTAssertEqualObjects(conv2, @"€",@"handling of iso-8859-15 special characters"); + } + { + const char *cstr = "エスキューエル"; + NSString *conv = [NSString stringForDataBytes:cstr length:strlen(cstr) encoding:NSUTF8StringEncoding]; + XCTAssertEqualObjects(conv, @"エスキューエル",@"handling of valid utf-8 string"); + } + { + // this is a test for a certain mysql issue: + // mysql limits field names to 255 characters and will even cut multibyte chars in the middle, + // if neccesary. This will create invalid characters which cause NSString + // to fail and return nil on the whole string. Since we know that, we can + // at least try to return something. + char cstr[] = {'\xE3','\x82','\xA8','\xE3','\x82','\xB9','\xE3','\x82','\xAD','\xE3','\x83','\xA5','\xE3','\x83','\xBC','\xE3','\x82','\xA8','\xE3','\x83','\xAB','\0'}; // エスキューエル + cstr[strlen(cstr)-2] = '\0'; //simulate cutting off the string + NSString *conv = [NSString stringForDataBytes:cstr length:strlen(cstr) encoding:NSUTF8StringEncoding]; + XCTAssertNotNil(conv, @"handling of invalid utf8 sequences"); + } +} + +@end diff --git a/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj b/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj index b3b58052..32dca24c 100644 --- a/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj +++ b/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 17E3A57C1885A286009CF372 /* SPMySQLDataTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E3A57A1885A286009CF372 /* SPMySQLDataTypes.m */; }; 507FF1E51BC0D82300104523 /* DataConversion_Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 507FF1811BC0C64100104523 /* DataConversion_Tests.m */; }; 507FF23B1BC0E8CA00104523 /* SPMySQL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* SPMySQL.framework */; }; + 507FF23D1BC157B500104523 /* SPMySQLStringAdditions_Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 507FF23C1BC157B500104523 /* SPMySQLStringAdditions_Tests.m */; }; 580A331E14D75CF7000D6933 /* SPMySQLGeometryData.h in Headers */ = {isa = PBXBuildFile; fileRef = 580A331C14D75CF7000D6933 /* SPMySQLGeometryData.h */; settings = {ATTRIBUTES = (Public, ); }; }; 580A331F14D75CF7000D6933 /* SPMySQLGeometryData.m in Sources */ = {isa = PBXBuildFile; fileRef = 580A331D14D75CF7000D6933 /* SPMySQLGeometryData.m */; }; 583C734A17A489CC0056B284 /* SPMySQLStreamingResultStoreDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 583C734917A489CC0056B284 /* SPMySQLStreamingResultStoreDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -98,6 +99,7 @@ 507FF1811BC0C64100104523 /* DataConversion_Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DataConversion_Tests.m; sourceTree = "<group>"; }; 507FF1D51BC0D7D300104523 /* SPMySQL Unit Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SPMySQL Unit Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 507FF1D81BC0D7D300104523 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + 507FF23C1BC157B500104523 /* SPMySQLStringAdditions_Tests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPMySQLStringAdditions_Tests.m; sourceTree = "<group>"; }; 580A331C14D75CF7000D6933 /* SPMySQLGeometryData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SPMySQLGeometryData.h; path = Source/SPMySQLGeometryData.h; sourceTree = "<group>"; }; 580A331D14D75CF7000D6933 /* SPMySQLGeometryData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SPMySQLGeometryData.m; path = Source/SPMySQLGeometryData.m; sourceTree = "<group>"; }; 583C734917A489CC0056B284 /* SPMySQLStreamingResultStoreDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SPMySQLStreamingResultStoreDelegate.h; path = Source/SPMySQLStreamingResultStoreDelegate.h; sourceTree = "<group>"; }; @@ -282,6 +284,7 @@ children = ( 507FF1D81BC0D7D300104523 /* Info.plist */, 507FF1811BC0C64100104523 /* DataConversion_Tests.m */, + 507FF23C1BC157B500104523 /* SPMySQLStringAdditions_Tests.m */, ); name = "Unit Tests"; path = "SPMySQL Unit Tests"; @@ -548,6 +551,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 507FF23D1BC157B500104523 /* SPMySQLStringAdditions_Tests.m in Sources */, 507FF1E51BC0D82300104523 /* DataConversion_Tests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -731,7 +735,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; @@ -765,7 +769,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; @@ -795,7 +799,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; @@ -889,7 +893,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLResult.m b/Frameworks/SPMySQLFramework/Source/SPMySQLResult.m index 5f54960c..2e1cb2ba 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLResult.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLResult.m @@ -318,7 +318,7 @@ static id NSNullPointer; { return [[[NSString alloc] initWithBytes:bytes length:length encoding:stringEncoding] autorelease]; } - +#warning duplicate code with Data Conversion.m stringForDataBytes:length:encoding: (↑, ↓) - (NSString *)_lossyStringWithBytes:(const void *)bytes length:(NSUInteger)length wasLossy:(BOOL *)outLossy { if(!bytes || !length) return @""; //to match -[NSString initWithBytes:length:encoding:] |