From bd3f359e4c9dfab4aa108f60f0149979c6fb4b6c Mon Sep 17 00:00:00 2001 From: znek Date: Thu, 14 Oct 2004 17:18:50 +0000 Subject: [PATCH] improvements/fixes git-svn-id: http://svn.opengroupware.org/SOGo/trunk@397 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/SOGo.xcode/project.pbxproj | 6 +- SOGoLogic/ChangeLog | 3 + SOGoLogic/NSString+iCal.m | 211 ++++++++++++++++++++------------ SOGoLogic/Version | 2 +- 4 files changed, 142 insertions(+), 80 deletions(-) diff --git a/SOGo/SOGo.xcode/project.pbxproj b/SOGo/SOGo.xcode/project.pbxproj index 568e9755..c8f05b9b 100644 --- a/SOGo/SOGo.xcode/project.pbxproj +++ b/SOGo/SOGo.xcode/project.pbxproj @@ -1438,7 +1438,8 @@ sourceTree = ""; }; ADA6333607140E0D0058C21C = { - fileEncoding = 4; + fileEncoding = 5; + indentWidth = 2; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+iCal.h"; @@ -1446,7 +1447,8 @@ sourceTree = ""; }; ADA6333707140E0D0058C21C = { - fileEncoding = 4; + fileEncoding = 5; + indentWidth = 2; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+iCal.m"; diff --git a/SOGoLogic/ChangeLog b/SOGoLogic/ChangeLog index 5774bcb6..815fa5be 100644 --- a/SOGoLogic/ChangeLog +++ b/SOGoLogic/ChangeLog @@ -1,5 +1,8 @@ 2004-10-14 Marcus Mueller + * NSString+iCal.[hm]: new (private) method to strip off any unsafe + characters from strings and bugfix for escaping (v0.9.17) + * SOGoAppointment.m: fix comparison of role attribute to be compatible with new versitSaxDriver. Note: this is a bug in the old iCalSaxDriver, but the fix is backwards compatible and shouldn't diff --git a/SOGoLogic/NSString+iCal.m b/SOGoLogic/NSString+iCal.m index 8b21ed27..42fe41a7 100644 --- a/SOGoLogic/NSString+iCal.m +++ b/SOGoLogic/NSString+iCal.m @@ -24,99 +24,156 @@ #import "NSString+iCal.h" +@interface NSString (SOGoiCal_Private) +- (NSString *)iCalCleanString; +@end + @implementation NSString (SOGoiCal) #if 0 - (NSString *)iCalFoldedString { - /* RFC2445, 4.1 Content Lines - - The iCalendar object is organized into individual lines of text, - called content lines. Content lines are delimited by a line break, - which is a CRLF sequence (US-ASCII decimal 13, followed by US-ASCII - decimal 10). - Lines of text SHOULD NOT be longer than 75 octets, excluding the line - break. Long content lines SHOULD be split into a multiple line - representations using a line "folding" technique. That is, a long - line can be split between any two characters by inserting a CRLF - immediately followed by a single linear white space character (i.e., - SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). - Any sequence of CRLF followed immediately by a single linear white space - character is ignored (i.e., removed) when processing the content type. - */ + /* RFC2445, 4.1 Content Lines + + The iCalendar object is organized into individual lines of text, + called content lines. Content lines are delimited by a line break, + which is a CRLF sequence (US-ASCII decimal 13, followed by US-ASCII + decimal 10). + Lines of text SHOULD NOT be longer than 75 octets, excluding the line + break. Long content lines SHOULD be split into a multiple line + representations using a line "folding" technique. That is, a long + line can be split between any two characters by inserting a CRLF + immediately followed by a single linear white space character (i.e., + SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). + Any sequence of CRLF followed immediately by a single linear white space + character is ignored (i.e., removed) when processing the content type. + */ } #endif -- (NSString *)iCalDQUOTESafeString { - static NSCharacterSet *escapeSet = nil; - - if(escapeSet == nil) { - escapeSet = [NSCharacterSet characterSetWithCharactersInString:@"\""]; - [escapeSet retain]; +/* strip off any characters from string which are not allowed in iCal */ +- (NSString *)iCalCleanString { + static NSCharacterSet *replaceSet = nil; + NSRange r, er; + NSMutableString *safeString; + BOOL needsReplacing; + unsigned length; + + if(replaceSet == nil) { + replaceSet = [NSCharacterSet characterSetWithCharactersInString:@"\r"]; + [replaceSet retain]; + } + + length = [self length]; + r = NSMakeRange(0, length); + er = [self rangeOfCharacterFromSet:replaceSet options:0 range:r]; + needsReplacing = er.length > 0 ? YES : NO; + if(!needsReplacing) { + return self; /* cheap */ + } + + safeString = [NSMutableString stringWithCapacity:length]; + if(needsReplacing) { + NSRange todoRange; + /* + r == previous range, upto er.location + er == escape range + todoRange == what we still need to scan + */ + length = r.length; + do { + r.length = er.location - r.location; + if(r.length > 0) + [safeString appendString:[self substringWithRange:r]]; + r.location = NSMaxRange(er); + todoRange.location = r.location; + todoRange.length = length - r.location; + er = [self rangeOfCharacterFromSet:replaceSet + options:0 + range:todoRange]; + } + while(er.length > 0); + if(todoRange.length > 0) { + [safeString appendString:[self substringWithRange:todoRange]]; } - return [self iCalEscapedStringWithEscapeSet:escapeSet]; + } + return safeString; } -- (NSString *)iCalSafeString { - static NSCharacterSet *escapeSet = nil; +- (NSString *)iCalDQUOTESafeString { + static NSCharacterSet *escapeSet = nil; + + if(escapeSet == nil) { + escapeSet = [NSCharacterSet characterSetWithCharactersInString:@"\""]; + [escapeSet retain]; + } + return [self iCalEscapedStringWithEscapeSet:escapeSet]; +} - if(escapeSet == nil) { - escapeSet = [NSCharacterSet characterSetWithCharactersInString:@"\n,;\""]; - [escapeSet retain]; - } - return [self iCalEscapedStringWithEscapeSet:escapeSet]; +- (NSString *)iCalSafeString { + static NSCharacterSet *escapeSet = nil; + + if(escapeSet == nil) { + escapeSet = [NSCharacterSet characterSetWithCharactersInString:@"\n,;\""]; + [escapeSet retain]; + } + return [self iCalEscapedStringWithEscapeSet:escapeSet]; } +/* Escape unsafe characters */ - (NSString *)iCalEscapedStringWithEscapeSet:(NSCharacterSet *)_es { - /* Escape unsafe characters */ - NSMutableString *safeString; - NSRange r, er; - BOOL needsEscaping; - unsigned length; - - length = [self length]; - r = NSMakeRange(0, length); - er = [self rangeOfCharacterFromSet:_es options:0 range:r]; - needsEscaping = er.length > 0 ? YES : NO; - if(!needsEscaping) { - return self; /* cheap */ + NSString *cleanString; + NSMutableString *safeString; + NSRange r, er; + BOOL needsEscaping; + unsigned length; + + cleanString = [self iCalCleanString]; + length = [cleanString length]; + r = NSMakeRange(0, length); + er = [cleanString rangeOfCharacterFromSet:_es options:0 range:r]; + needsEscaping = er.length > 0 ? YES : NO; + if(!needsEscaping) { + return cleanString; /* cheap */ + } + /* wild guess */ + safeString = [NSMutableString stringWithCapacity:length + 10]; + if(needsEscaping) { + NSRange todoRange; + /* + r == previous range, upto er.location + er == escape range + todoRange == what we still need to scan + */ + length = r.length; + do { + NSString *s; + + r.length = er.location - r.location; + if(r.length > 0) { + s = [cleanString substringWithRange:r]; + [safeString appendString:s]; + } + [safeString appendString:@"\\"]; + if([cleanString characterAtIndex:er.location] == '\n') { + s = @"n"; + } + else { + s = [cleanString substringWithRange:er]; + } + [safeString appendString:s]; + r.location = NSMaxRange(er); + todoRange.location = r.location; + todoRange.length = length - r.location; + er = [cleanString rangeOfCharacterFromSet:_es + options:0 + range:todoRange]; } - /* wild guess */ - safeString = [NSMutableString stringWithCapacity:length + 10]; - if(needsEscaping) { - NSRange todoRange; - /* - r == previous range, upto er.location - er == escape range - todoRange == what we still need to scan - */ - length = r.length; - do { - NSString *s; - - r.length = (er.location - 1) - r.location; - s = [self substringWithRange:r]; - [safeString appendString:s]; - [safeString appendString:@"\\"]; - if([self characterAtIndex:er.location] == '\n') { - s = @"n"; - } - else { - s = [self substringWithRange:er]; - } - [safeString appendString:s]; - r.location = NSMaxRange(er); - todoRange.location = r.location; - todoRange.length = length - r.location; - er = [self rangeOfCharacterFromSet:_es - options:0 - range:todoRange]; - } - while(er.length > 0); - if(todoRange.length > 0) { - [safeString appendString:[self substringWithRange:todoRange]]; - } + while(er.length > 0); + if(todoRange.length > 0) { + [safeString appendString:[cleanString substringWithRange:todoRange]]; } - return safeString; + } + return safeString; } @end diff --git a/SOGoLogic/Version b/SOGoLogic/Version index a7274e9e..f120816a 100644 --- a/SOGoLogic/Version +++ b/SOGoLogic/Version @@ -1,5 +1,5 @@ # $Id$ -SUBMINOR_VERSION:=16 +SUBMINOR_VERSION:=17 # v0.9.13 requires libFoundation v1.0.62 -- 2.39.5