From d6016080249ae92a6942ba3ec0d19147c8737340 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Tue, 10 May 2016 08:51:59 -0400 Subject: [PATCH] (fix) fixed bogus headers generation when stripping folded bcc headers (fixes #3664) --- SoObjects/Mailer/SOGoDraftObject.m | 58 ++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index f14fe7b0c8..3334039876 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -103,6 +103,7 @@ - (NSString *) imap4FolderNameForURL: (NSURL *) url; // @interface NSMutableData (DataCleanupExtension) +- (unichar) characterAtIndex: (int) theIndex; - (NSRange) rangeOfCString: (const char *) theCString; - (NSRange) rangeOfCString: (const char *) theCString options: (unsigned int) theOptions @@ -111,6 +112,32 @@ - (NSRange) rangeOfCString: (const char *) theCString @implementation NSMutableData (DataCleanupExtension) +- (unichar) characterAtIndex: (int) theIndex +{ + const char *bytes; + int i, len; + + len = [self length]; + + if (len == 0 || theIndex >= len) + { + [[NSException exceptionWithName: NSRangeException + reason: @"Index out of range." + userInfo: nil] raise]; + + return (unichar)0; + } + + bytes = [self bytes]; + + for (i = 0; i < theIndex; i++) + { + bytes++; + } + + return (unichar)*bytes; +} + - (NSRange) rangeOfCString: (const char *) theCString { return [self rangeOfCString: theCString @@ -1874,9 +1901,9 @@ - (NSException *) sendMailAndCopyToSent: (BOOL) copyToSent NSURL *sourceIMAP4URL; NSException *error; NSData *message; - NSRange r1, r2; - - /* send mail */ + NSRange r1; + + unsigned int limit; // We strip the BCC fields prior sending any mails NGMimeMessageGenerator *generator; @@ -1890,21 +1917,32 @@ - (NSException *) sendMailAndCopyToSent: (BOOL) copyToSent // #warning FIXME - we should fix the case issue when we switch to Pantomime cleaned_message = [NSMutableData dataWithData: message]; + + // We search only in the headers so we start at 0 until + // we find \r\n\r\n, which is the headers delimiter r1 = [cleaned_message rangeOfCString: "\r\n\r\n"]; + limit = r1.location-1; r1 = [cleaned_message rangeOfCString: "\r\nbcc: " options: 0 - range: NSMakeRange(0,r1.location-1)]; + range: NSMakeRange(0,limit)]; if (r1.location != NSNotFound) { // We search for the first \r\n AFTER the Bcc: header and // replace the whole thing with \r\n. - r2 = [cleaned_message rangeOfCString: "\r\n" - options: 0 - range: NSMakeRange(NSMaxRange(r1)+1,[cleaned_message length]-NSMaxRange(r1)-1)]; - [cleaned_message replaceBytesInRange: NSMakeRange(r1.location, NSMaxRange(r2)-r1.location) - withBytes: "\r\n" - length: 2]; + unsigned int i; + + for (i = r1.location+7; i < limit; i++) + { + if ([cleaned_message characterAtIndex: i] == '\r' && + (i+1 < limit && [cleaned_message characterAtIndex: i+1] == '\n') && + (i+2 < limit && !isspace([cleaned_message characterAtIndex: i+2]))) + break; + } + + [cleaned_message replaceBytesInRange: NSMakeRange(r1.location, i-r1.location) + withBytes: NULL + length: 0]; } dd = [[context activeUser] domainDefaults];