From 312227a2fddf70b16cadb8d46eb6b68a24aec6c7 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 2 Oct 2015 16:31:39 +0200 Subject: Fix conversion of BIT fields (fixes #2254) --- .../SPMySQLResult Categories/Data Conversion.m | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'Frameworks/SPMySQLFramework/Source') diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Data Conversion.m b/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Data Conversion.m index 639ff0b9..8c5b9181 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Data Conversion.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Data Conversion.m @@ -209,27 +209,26 @@ static inline NSString * _bitStringWithBytes(const char *bytes, NSUInteger lengt return nil; } - // Ensure padLength is never lower than the length - if (padLength < bitLength) { - padLength = bitLength; - } - + // use whatever is smaller. padLength comes from BIT(x), bitLength from the actual bytes transmitted. + // if bitLength < padLength it means the value is smaller than what the field can accomodate. + // if bitLength > padLength it means BIT(x) is not a full n bytes long and was extended by mysqls storage. + // In that case the additional bits should still be 0 as mysql does not allow to set bits over the size of x. + bitLength = MIN(bitLength,padLength); // Generate a nul-terminated C string representation of the binary data char *cStringBuffer = malloc(padLength + 1); - cStringBuffer[padLength] = '\0'; + memset(cStringBuffer, '0', padLength); while (i < bitLength) { + // start with the least significant bit (the rightmost bit in the last byte) and move left + unsigned char bitInByteMask = i % 8; // 0-7, the cycle is 0,1,...,7,0,... + unsigned long bytesOffset = (length - 1) - (i >> 3); // i>>3 == floor(i/8) ++i; - - cStringBuffer[padLength - i] = ((bytes[length - 1 - (i >> 3)] >> (i & 0x7)) & 1 ) ? '1' : '0'; + cStringBuffer[padLength - i] = ((bytes[bytesOffset] & (1 << bitInByteMask)) != 0) ? '1' : '0'; } - - while (i++ < padLength) - { - cStringBuffer[padLength - i] = '0'; - } - + + cStringBuffer[padLength] = '\0'; + // Convert to a string NSString *returnString = [NSString stringWithUTF8String:cStringBuffer]; -- cgit v1.2.3