Skip to content

Commit 26c821c

Browse files
committed
Fix an issue where Sequel Pro added a NUL byte to the end of every query (fixes #2184)
We tried to convert the query string into a c string that could contain NUL bytes - which by definition a c string cannot (making it a byte buffer with a terminating NUL byte) and then tried to pass that to mysql_real_query() which expects a byte buffer anyway.
1 parent c5525ba commit 26c821c

File tree

2 files changed

+12
-9
lines changed

2 files changed

+12
-9
lines changed

Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Conversion.m

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ @implementation SPMySQLConnection (Conversion)
4040
* the current encoding, a representation will be returned rather than null.
4141
* The returned cString will correctly preserve any nul characters within the string,
4242
* which prevents the use of faster functions like [NSString cStringUsingEncoding:].
43-
* Pass in the third parameter to receive the length of the converted string, or pass
44-
* in NULL if you do not want this information.
43+
* Pass in the third parameter to receive the length of the converted string (INCLUDING
44+
* the terminating \0 character), or pass in NULL if you do not want this information.
4545
*/
46+
#warning This method doesn't make sense. It's only addition over [str dataUsingEncoding:allowLossyConversion:] is the terminating NUL byte. \
47+
But the "string" can already contain NUL bytes, so it's not a valid c string anyway.
4648
+ (const char *)_cStringForString:(NSString *)aString usingEncoding:(NSStringEncoding)anEncoding returningLengthAs:(NSUInteger *)cStringLengthPointer
4749
{
4850
@@ -56,7 +58,7 @@ + (const char *)_cStringForString:(NSString *)aString usingEncoding:(NSStringEnc
5658
// Take the converted data - not null-terminated - and copy it to a null-terminated buffer
5759
char *cStringBytes = malloc(convertedDataLength + 1);
5860
memcpy(cStringBytes, [convertedData bytes], convertedDataLength);
59-
cStringBytes[convertedDataLength] = 0L;
61+
cStringBytes[convertedDataLength] = '\0';
6062

6163
if (cStringLengthPointer) *cStringLengthPointer = convertedDataLength+1;
6264

Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,16 +264,17 @@ - (id)queryString:(NSString *)theQueryString usingEncoding:(NSStringEncoding)the
264264
[delegate willQueryString:theQueryString connection:self];
265265
}
266266

267-
// Retrieve a C-style query string from the supplied NSString
268-
NSUInteger cQueryStringLength;
269-
const char *cQueryString = _cStringForStringWithEncoding(theQueryString, theEncoding, &cQueryStringLength);
267+
// Retrieve a byte buffer from the supplied NSString
268+
NSData *queryData = [theQueryString dataUsingEncoding:theEncoding allowLossyConversion:YES];
269+
NSUInteger queryBytesLength = [queryData length];
270+
const char *queryBytes = [queryData bytes];
270271

271272
// Check the query length against the current maximum query length. If it is
272273
// larger, the query would error (and probably cause a disconnect), so if
273274
// the maximum size is editable, increase it and reconnect.
274-
if (cQueryStringLength > maxQuerySize) {
275+
if (queryBytesLength > maxQuerySize) {
275276
queryActionShouldRestoreMaxQuerySize = maxQuerySize;
276-
if (![self _attemptMaxQuerySizeIncreaseTo:(cQueryStringLength + 1024)]) {
277+
if (![self _attemptMaxQuerySizeIncreaseTo:(queryBytesLength + 1024)]) {
277278
queryActionShouldRestoreMaxQuerySize = NSNotFound;
278279
return nil;
279280
}
@@ -292,7 +293,7 @@ - (id)queryString:(NSString *)theQueryString usingEncoding:(NSStringEncoding)the
292293
// While recording the overall execution time (including network lag!), run
293294
// the raw query
294295
uint64_t queryStartTime = mach_absolute_time();
295-
queryStatus = mysql_real_query(mySQLConnection, cQueryString, cQueryStringLength);
296+
queryStatus = mysql_real_query(mySQLConnection, queryBytes, queryBytesLength);
296297
queryExecutionTime = _elapsedSecondsSinceAbsoluteTime(queryStartTime);
297298
lastConnectionUsedTime = mach_absolute_time();
298299

0 commit comments

Comments
 (0)