From 43cafb58805e846a0e8da20518de7575cfb23166 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 3 Mar 2016 21:37:47 +0100 Subject: Fix #2150 & #2173 on 1.1.x branch Backport of 2b52f76ed2103bc6d458767906753814ee8ba9e1 & 2b52f76ed2103bc6d458767906753814ee8ba9e1 --- Frameworks/SPMySQLFramework/Source/SPMySQLResult.m | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'Frameworks/SPMySQLFramework/Source/SPMySQLResult.m') diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLResult.m b/Frameworks/SPMySQLFramework/Source/SPMySQLResult.m index 56b50d9a..6d2bdfd6 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLResult.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLResult.m @@ -318,6 +318,35 @@ static id NSNullPointer; return [[[NSString alloc] initWithBytes:bytes length:length encoding:stringEncoding] autorelease]; } +- (NSString *)_lossyStringWithBytes:(const void *)bytes length:(NSUInteger)length wasLossy:(BOOL *)outLossy +{ + //mysql protocol limits column names to 256 bytes. + //with inline columns and multibyte charsets this can result in a character + //being split in half at which the method above will fail. + //Let's first try removing stuff from the end to create something valid. + NSUInteger removed = 0; + do { + NSString *res = [self _stringWithBytes:bytes length:(length-removed)]; + if(res) { + if(outLossy) *outLossy = (removed != 0); + return (removed? [res stringByAppendingString:@"…"] : res); + } + removed++; + } while(removed <= 10 && removed < length); // 10 is arbitrary + + //if that fails, ascii should accept all values from 0-255 as input + NSString *ascii = [[NSString alloc] initWithBytes:bytes length:length encoding:NSASCIIStringEncoding]; + if(ascii){ + if(outLossy) *outLossy = YES; + return [ascii autorelease]; + } + + //if even that failed we lose. + NSDictionary *info = @{ @"data": [NSData dataWithBytes:bytes length:length] }; + NSString *reason = [NSString stringWithFormat:@"Failed to convert byte sequence %@ to string (encoding = %lu)",info[@"data"],stringEncoding]; + @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:info]; +} + /** * Allow setting the execution time for the original query (including connection lag) * so it can be requested later without relying on connection state. -- cgit v1.2.3