From 7c81e3acec53651056319f8bece582e057a7c475 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 31 Jan 2022 14:51:26 -0500 Subject: [PATCH] fix(core): only escape "%" with the SQL LIKE operator --- SoObjects/Appointments/SOGoAppointmentFolder.m | 12 ++++++------ SoObjects/Contacts/SOGoContactGCSFolder.m | 6 +++--- SoObjects/SOGo/NSString+Utilities.h | 3 ++- SoObjects/SOGo/NSString+Utilities.m | 12 ++++++++---- SoObjects/SOGo/SOGoGCSFolder.m | 9 ++++----- SoObjects/SOGo/SQLSource.m | 2 +- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 9749dbcb6..f74444301 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2007-2019 Inverse inc. + Copyright (C) 2007-2022 Inverse inc. Copyright (C) 2004-2005 SKYRIX Software AG This file is part of SOGo. @@ -794,7 +794,7 @@ static Class iCalEventK = nil; if ([title length]) [baseWhere addObject: [NSString stringWithFormat: @"c_title isCaseInsensitiveLike: '%%%@%%'", - [title asSafeSQLString]]]; + [title asSafeSQLLikeString]]]; if (component) { @@ -1577,14 +1577,14 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir if ([filters isEqualToString:@"title_Category_Location"] || [filters isEqualToString:@"entireContent"]) { [baseWhere addObject: [NSString stringWithFormat: @"(c_title isCaseInsensitiveLike: '%%%@%%' OR c_category isCaseInsensitiveLike: '%%%@%%' OR c_location isCaseInsensitiveLike: '%%%@%%')", - [title asSafeSQLString], - [title asSafeSQLString], - [title asSafeSQLString]]]; + [title asSafeSQLLikeString], + [title asSafeSQLLikeString], + [title asSafeSQLLikeString]]]; } } else [baseWhere addObject: [NSString stringWithFormat: @"c_title isCaseInsensitiveLike: '%%%@%%'", - [title asSafeSQLString]]]; + [title asSafeSQLLikeString]]]; } /* prepare mandatory fields */ diff --git a/SoObjects/Contacts/SOGoContactGCSFolder.m b/SoObjects/Contacts/SOGoContactGCSFolder.m index 945ddd7a8..8e4d86b79 100644 --- a/SoObjects/Contacts/SOGoContactGCSFolder.m +++ b/SoObjects/Contacts/SOGoContactGCSFolder.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2006-2019 Inverse inc. + Copyright (C) 2006-2022 Inverse inc. This file is part of SOGo. @@ -208,7 +208,7 @@ static NSArray *folderListingFields = nil; qualifier = nil; if ([filter length] > 0) { - filter = [filter asSafeSQLString]; + filter = [filter asSafeSQLLikeString]; filters = [NSMutableArray array]; filterFormat = [NSString stringWithFormat: @"(%%@ isCaseInsensitiveLike: '%%%%%@%%%%')", filter]; if (criteria) @@ -356,7 +356,7 @@ static NSArray *folderListingFields = nil; if (aName && [aName length] > 0) { aName = [aName asSafeSQLString]; - qs = [NSString stringWithFormat: @"(c_name='%@')", aName]; + qs = [NSString stringWithFormat: @"(c_name = '%@')", aName]; qualifier = [EOQualifier qualifierWithQualifierFormat: qs]; dbRecords = [[self ocsFolder] fetchFields: folderListingFields matchingQualifier: qualifier]; diff --git a/SoObjects/SOGo/NSString+Utilities.h b/SoObjects/SOGo/NSString+Utilities.h index 7f631ce9d..371666613 100644 --- a/SoObjects/SOGo/NSString+Utilities.h +++ b/SoObjects/SOGo/NSString+Utilities.h @@ -1,6 +1,6 @@ /* NSString+Utilities.h - this file is part of SOGo * - * Copyright (C) 2006-2019 Inverse inc. + * Copyright (C) 2006-2022 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,6 +51,7 @@ /* SQL safety */ - (NSString *) asSafeSQLString; +- (NSString *) asSafeSQLLikeString; /* Unicode safety */ - (NSString *) safeString; diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index 2422300b3..5c7cc7a4f 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -1,6 +1,6 @@ /* NSString+Utilities.m - this file is part of SOGo * - * Copyright (C) 2006-2019 Inverse inc. + * Copyright (C) 2006-2022 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -725,9 +725,13 @@ static int cssEscapingCount; - (NSString *) asSafeSQLString { - return [[[self stringByReplacingString: @"\\" withString: @"\\\\"] - stringByReplacingString: @"'" withString: @"\\'"] - stringByReplacingString: @"\%" withString: @"\\%"]; + return [[self stringByReplacingString: @"\\" withString: @"\\\\"] + stringByReplacingString: @"'" withString: @"\\'"]; +} + +- (NSString *) asSafeSQLLikeString +{ + return [[self asSafeSQLString] stringByReplacingString: @"\%" withString: @"\\%"]; } - (NSUInteger) countOccurrencesOfString: (NSString *) substring diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index 6fa45279d..4663e78c3 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -1,7 +1,7 @@ /* SOGoGCSFolder.m - this file is part of SOGo * * Copyright (C) 2004-2005 SKYRIX Software AG - * Copyright (C) 2006-2014 Inverse inc. + * Copyright (C) 2006-2022 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1969,8 +1969,8 @@ static NSArray *childRecordFields = nil; if (sqlFilter) { filterString = [NSMutableString stringWithCapacity: 8192]; - [filterString appendFormat: @"(c_name='%@')", - [cNames componentsJoinedByString: @"' OR c_name='"]]; + [filterString appendFormat: @"(c_name = '%@')", + [cNames componentsJoinedByString: @"' OR c_name = '"]]; if ([sqlFilter length] > 0) [filterString appendFormat: @" AND (%@)", sqlFilter]; qualifier = [EOQualifier qualifierWithQualifierFormat: filterString]; @@ -2012,8 +2012,7 @@ static NSArray *childRecordFields = nil; { currentName = [[cNames objectAtIndex: count] asSafeSQLString]; queryNameLength = idQueryOverhead + [currentName length]; - if ((currentSize + queryNameLength) - > maxQuerySize) + if ((currentSize + queryNameLength) > maxQuerySize) { records = [self _fetchComponentsWithNames: currentNames fields: fields]; [components addObjectsFromArray: records]; diff --git a/SoObjects/SOGo/SQLSource.m b/SoObjects/SOGo/SQLSource.m index a10e551c7..5f2e63538 100644 --- a/SoObjects/SOGo/SQLSource.m +++ b/SoObjects/SOGo/SQLSource.m @@ -861,7 +861,7 @@ if ([filter length]) { lowerFilter = [filter lowercaseString]; - lowerFilter = [lowerFilter asSafeSQLString]; + lowerFilter = [lowerFilter asSafeSQLLikeString]; filterFormat = [NSString stringWithFormat: @"LOWER(%%@) LIKE '%%%%%@%%%%'", lowerFilter]; if (criteria) criteriaList = [criteria objectEnumerator];