diff --git a/ActiveSync/NGVCard+ActiveSync.m b/ActiveSync/NGVCard+ActiveSync.m index 4f38f1d3e..5f4b90ec9 100644 --- a/ActiveSync/NGVCard+ActiveSync.m +++ b/ActiveSync/NGVCard+ActiveSync.m @@ -54,16 +54,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. n = [self n]; if ((o = [n flattenedValueAtIndex: 0 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [n flattenedValueAtIndex: 1 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [self workCompany])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [self title])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [self preferredEMail])) [s appendFormat: @"%@", o]; @@ -84,19 +84,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Telephone numbers if ((o = [self workPhone]) && [o length]) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [self homePhone]) && [o length]) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [self fax]) && [o length]) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [self mobile]) && [o length]) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [self pager]) && [o length]) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; // Home Address addresses = [self childrenWithTag: @"adr" @@ -108,19 +108,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. homeAdr = [addresses objectAtIndex: 0]; if ((o = [homeAdr flattenedValueAtIndex: 2 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [homeAdr flattenedValueAtIndex: 3 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [homeAdr flattenedValueAtIndex: 4 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [homeAdr flattenedValueAtIndex: 5 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [homeAdr flattenedValueAtIndex: 6 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; } // Work Address @@ -133,19 +133,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. workAdr = [addresses objectAtIndex: 0]; if ((o = [workAdr flattenedValueAtIndex: 2 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [workAdr flattenedValueAtIndex: 3 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [workAdr flattenedValueAtIndex: 4 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [workAdr flattenedValueAtIndex: 5 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; if ((o = [workAdr flattenedValueAtIndex: 6 forKey: @""])) - [s appendFormat: @"%@", [o stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [o activeSyncRepresentation]]; } // Other, less important fields @@ -154,7 +154,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if ((o = [self note])) { - o = [o stringByEscapingHTMLString]; + o = [o activeSyncRepresentation]; [s appendString: @""]; [s appendFormat: @"%d", 1]; [s appendFormat: @"%d", [o length]]; diff --git a/ActiveSync/NSData+ActiveSync.m b/ActiveSync/NSData+ActiveSync.m index 54c9e1e8a..55c8d3714 100644 --- a/ActiveSync/NSData+ActiveSync.m +++ b/ActiveSync/NSData+ActiveSync.m @@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#define WBXMLDEBUG 0 +#define WBXMLDEBUG 1 @implementation NSData (ActiveSync) diff --git a/ActiveSync/NSString+ActiveSync.h b/ActiveSync/NSString+ActiveSync.h index c1d32c0f7..735c6ffbc 100644 --- a/ActiveSync/NSString+ActiveSync.h +++ b/ActiveSync/NSString+ActiveSync.h @@ -39,6 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @interface NSString (ActiveSync) +- (NSString *) activeSyncRepresentation; - (int) activeSyncFolderType; - (NSString *) realCollectionIdWithFolderType: (SOGoMicrosoftActiveSyncFolderType *) folderType; - (NSCalendarDate *) calendarDate; diff --git a/ActiveSync/NSString+ActiveSync.m b/ActiveSync/NSString+ActiveSync.m index 53637cec6..27580b797 100644 --- a/ActiveSync/NSString+ActiveSync.m +++ b/ActiveSync/NSString+ActiveSync.m @@ -34,10 +34,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include + #include @implementation NSString (ActiveSync) +- (NSString *) activeSyncRepresentation +{ + NSString *s; + + s = [self stringByEscapingHTMLString]; + + return [[s componentsSeparatedByCharactersInSet: [self safeCharacterSet]] + componentsJoinedByString: @""]; +} + - (int) activeSyncFolderType { if ([self isEqualToString: @"inbox"]) diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index bb14a17fc..5601e3f66 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -508,26 +508,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [serverId stringByEscapingURL], [parentId stringByEscapingURL], type, - [name stringByEscapingHTMLString]]; + [name activeSyncRepresentation]]; } // We add the personal calendar - events // FIXME: add all calendars currentFolder = [[context activeUser] personalCalendarFolderInContext: context]; name = [NSString stringWithFormat: @"vevent/%@", [currentFolder nameInContainer]]; - [s appendFormat: @"%@%@%d%@", name, @"0", 8, [[currentFolder displayName] stringByEscapingHTMLString]]; + [s appendFormat: @"%@%@%d%@", name, @"0", 8, [[currentFolder displayName] activeSyncRepresentation]]; // We add the personal calendar - tasks // FIXME: add all calendars currentFolder = [[context activeUser] personalCalendarFolderInContext: context]; name = [NSString stringWithFormat: @"vtodo/%@", [currentFolder nameInContainer]]; - [s appendFormat: @"%@%@%d%@", name, @"0", 7, [[currentFolder displayName] stringByEscapingHTMLString]]; + [s appendFormat: @"%@%@%d%@", name, @"0", 7, [[currentFolder displayName] activeSyncRepresentation]]; // We add the personal address book // FIXME: add all address books currentFolder = [[context activeUser] personalContactsFolderInContext: context]; name = [NSString stringWithFormat: @"vcard/%@", [currentFolder nameInContainer]]; - [s appendFormat: @"%@%@%d%@", name, @"0", 9, [[currentFolder displayName] stringByEscapingHTMLString]]; + [s appendFormat: @"%@%@%d%@", name, @"0", 9, [[currentFolder displayName] activeSyncRepresentation]]; } [s appendString: @""]; diff --git a/ActiveSync/SOGoMailObject+ActiveSync.m b/ActiveSync/SOGoMailObject+ActiveSync.m index cb0f001c3..5992482fb 100644 --- a/ActiveSync/SOGoMailObject+ActiveSync.m +++ b/ActiveSync/SOGoMailObject+ActiveSync.m @@ -344,13 +344,13 @@ struct GlobalObjectId { // From value = [self _emailAddressesFrom: [[self envelope] from]]; if (value) - [s appendFormat: @"%@", [value stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [value activeSyncRepresentation]]; // To - "The value of this element contains one or more e-mail addresses. // If there are multiple e-mail addresses, they are separated by commas." value = [self _emailAddressesFrom: [[self envelope] to]]; if (value) - [s appendFormat: @"%@", [value stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [value activeSyncRepresentation]]; // DisplayTo [s appendFormat: @"\"%@\"", [[context activeUser] login]]; @@ -358,14 +358,14 @@ struct GlobalObjectId { // Cc - same syntax as the To field value = [self _emailAddressesFrom: [[self envelope] cc]]; if (value) - [s appendFormat: @"%@", [value stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [value activeSyncRepresentation]]; // Subject value = [self decodedSubject]; if (value) { - [s appendFormat: @"%@", [value stringByEscapingHTMLString]]; - [s appendFormat: @"%@", [value stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [value activeSyncRepresentation]]; + [s appendFormat: @"%@", [value activeSyncRepresentation]]; } // DateReceived @@ -459,7 +459,7 @@ struct GlobalObjectId { content = [[NSString alloc] initWithData: d encoding: NSUTF8StringEncoding]; AUTORELEASE(content); - content = [content stringByEscapingHTMLString]; + content = [content activeSyncRepresentation]; len = [content length]; [s appendString: @""]; @@ -483,7 +483,7 @@ struct GlobalObjectId { value = [attachmentKeys objectAtIndex: i]; [s appendString: @""]; - [s appendFormat: @"%@", [[value objectForKey: @"filename"] stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [[value objectForKey: @"filename"] activeSyncRepresentation]]; // FileReference must be a unique identifier across the whole store. We use the following structure: // mail// diff --git a/ActiveSync/iCalEvent+ActiveSync.m b/ActiveSync/iCalEvent+ActiveSync.m index 82767e915..f9fc367b2 100644 --- a/ActiveSync/iCalEvent+ActiveSync.m +++ b/ActiveSync/iCalEvent+ActiveSync.m @@ -138,11 +138,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Subject -- http://msdn.microsoft.com/en-us/library/ee157192(v=exchg.80).aspx if ([[self summary] length]) - [s appendFormat: @"%@", [[self summary] stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [[self summary] activeSyncRepresentation]]; // Location if ([[self location] length]) - [s appendFormat: @"%@", [[self location] stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [[self location] activeSyncRepresentation]]; // Importance - NOT SUPPORTED - DO NOT ENABLE //o = [self priority]; @@ -184,7 +184,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. o = [self comment]; if ([o length]) { - o = [o stringByEscapingHTMLString]; + o = [o activeSyncRepresentation]; [s appendString: @""]; [s appendFormat: @"%d", 1]; [s appendFormat: @"%d", [o length]]; diff --git a/ActiveSync/iCalToDo+ActiveSync.m b/ActiveSync/iCalToDo+ActiveSync.m index 8e52f3bfb..b4e511746 100644 --- a/ActiveSync/iCalToDo+ActiveSync.m +++ b/ActiveSync/iCalToDo+ActiveSync.m @@ -97,11 +97,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Subject o = [self summary]; if ([o length]) - [s appendFormat: @"%@", [[self summary] stringByEscapingHTMLString]]; + [s appendFormat: @"%@", [[self summary] activeSyncRepresentation]]; if ((o = [self comment])) { - o = [o stringByEscapingHTMLString]; + o = [o activeSyncRepresentation]; [s appendString: @""]; [s appendFormat: @"%d", 1]; [s appendFormat: @"%d", [o length]]; diff --git a/SoObjects/SOGo/NSString+Utilities.h b/SoObjects/SOGo/NSString+Utilities.h index 245df3a3e..034d9818b 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-2013 Inverse inc. + * Copyright (C) 2006-2014 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 @@ -23,6 +23,7 @@ #import +@class NSCharacterSet; @class NSDictionary; @class NSObject; @@ -49,6 +50,7 @@ - (NSString *) asSafeSQLString; /* JSON */ +- (NSCharacterSet *) safeCharacterSet; - (NSString *) jsonRepresentation; - (BOOL) isJSONString; - (id) objectFromJSONString; diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index cb9889eb8..ba297cac7 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-2013 Inverse inc. + * Copyright (C) 2006-2014 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 @@ -46,6 +46,10 @@ static NSString **cssEscapingStrings = NULL; static unichar *cssEscapingCharacters = NULL; static int cssEscapingCount; +static unichar thisCharCode[29]; +static NSString *controlCharString = nil; +static NSCharacterSet *controlCharSet = nil; + @implementation NSString (SOGoURLExtension) - (NSString *) composeURLWithAction: (NSString *) action @@ -274,16 +278,12 @@ static int cssEscapingCount; return [NSString stringWithFormat: @"\"%@\"", representation]; } -- (NSString *) jsonRepresentation +- (NSCharacterSet *) safeCharacterSet { - static unichar thisCharCode[29]; - static NSString *controlCharString = nil; - static NSCharacterSet *controlCharSet = nil; - NSString *cleanedString; - int i, j; - if (!controlCharSet) { + int i, j; + // Create an array of chars for all control characters between 0x00 and 0x1F, // apart from \t, \n, \f and \r (0x08, 0x09, 0x0A, 0x0C and 0x0D) for (i = 0, j = 0x00; j < 0x08; i++, j++) { @@ -293,7 +293,7 @@ static int cssEscapingCount; for (j = 0x0E; j <= 0x1F; i++, j++) { thisCharCode[i] = j; } - + // Also add some unicode separators thisCharCode[i++] = 0x2028; // line separator thisCharCode[i++] = 0x2029; // paragraph separator @@ -302,8 +302,15 @@ static int cssEscapingCount; [controlCharSet retain]; } + return controlCharSet; +} + +- (NSString *) jsonRepresentation +{ + NSString *cleanedString; + // Escape double quotes and remove control characters - cleanedString = [[[self doubleQuotedString] componentsSeparatedByCharactersInSet: controlCharSet] + cleanedString = [[[self doubleQuotedString] componentsSeparatedByCharactersInSet: [self safeCharacterSet]] componentsJoinedByString: @""]; return cleanedString; }