From 6eab6532b713803cadf7398ea6c9621b377acadb Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Tue, 2 Sep 2008 20:57:23 +0000 Subject: [PATCH] Monotone-Parent: bf785cb3c555f8f6753cf915bc53455b1fb08004 Monotone-Revision: 99cc1bb593f4002d820b712345f3e8c1c9ba44ba Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2008-09-02T20:57:23 Monotone-Branch: ca.inverse.sogo --- SOPE/sope-patchset-r1626.diff | 847 +++++++++++++++++++++++++++++++++- 1 file changed, 846 insertions(+), 1 deletion(-) diff --git a/SOPE/sope-patchset-r1626.diff b/SOPE/sope-patchset-r1626.diff index cf84f7457..faa243b64 100644 --- a/SOPE/sope-patchset-r1626.diff +++ b/SOPE/sope-patchset-r1626.diff @@ -499,6 +499,42 @@ Index: sope-mime/NGImap4/NGImap4Client.m - (NSException *)_processCommandParserException:(NSException *)_exception { [self logWithFormat:@"ERROR(%s): catched IMAP4 parser exception %@: %@", __PRETTY_FUNCTION__, [_exception name], [_exception reason]]; +Index: sope-mime/NGImap4/NGSieveClient.m +=================================================================== +--- sope-mime/NGImap4/NGSieveClient.m (révision 1626) ++++ sope-mime/NGImap4/NGSieveClient.m (copie de travail) +@@ -294,8 +294,8 @@ + return con; + } + +- logLen = [self->login cStringLength]; +- bufLen = (logLen * 2) + [self->password cStringLength] +2; ++ logLen = [self->login lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; ++ bufLen = (logLen * 2) + [self->password lengthOfBytesUsingEncoding: NSUTF8StringEncoding] +2; + + buf = calloc(bufLen + 2, sizeof(char)); + +@@ -306,8 +306,9 @@ + password + */ + sprintf(buf, "%s %s %s", +- [self->login cString], [self->login cString], +- [self->password cString]); ++ [self->login cStringUsingEncoding:NSUTF8StringEncoding], ++ [self->login cStringUsingEncoding:NSUTF8StringEncoding], ++ [self->password cStringUsingEncoding:NSUTF8StringEncoding]); + + buf[logLen] = '\0'; + buf[logLen * 2 + 1] = '\0'; +@@ -656,7 +657,7 @@ + fputc('\n', stderr); + } + else +- fprintf(stderr, "C: %s\n", [_txt cString]); ++ fprintf(stderr, "C: %s\n", [_txt cStringUsingEncoding:NSUTF8StringEncoding]); + } + + /* write */ Index: sope-mime/NGImap4/NGImap4Connection.m =================================================================== --- sope-mime/NGImap4/NGImap4Connection.m (révision 1626) @@ -821,6 +857,18 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m - (NSException *)exceptionForFailedMatch:(unsigned char)_match got:(unsigned char)_avail { +@@ -2225,9 +2297,9 @@ + [s release]; + + if (c == '\n') { +- if ([self->serverResponseDebug cStringLength] > 2) { ++ if ([self->serverResponseDebug lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding] > 2) { + fprintf(stderr, "S[%p]: %s", self, +- [self->serverResponseDebug cString]); ++ [self->serverResponseDebug cStringUsingEncoding:NSISOLatin1StringEncoding]); + } + [self->serverResponseDebug release]; + self->serverResponseDebug = Index: sope-mime/NGImap4/ChangeLog =================================================================== --- sope-mime/NGImap4/ChangeLog (révision 1626) @@ -965,6 +1013,528 @@ Index: sope-mime/NGImap4/NGImap4ConnectionManager.m } /* client object */ +Index: sope-mime/NGImap4/NSString+Imap4.m +=================================================================== +--- sope-mime/NGImap4/NSString+Imap4.m (révision 1626) ++++ sope-mime/NGImap4/NSString+Imap4.m (copie de travail) +@@ -20,11 +20,56 @@ + 02111-1307, USA. + */ + ++#import ++ + #include + #include "imCommon.h" + + /* TODO: NOT UNICODE SAFE (uses cString) */ + ++#ifndef __APPLE__ ++ ++@interface NSMutableData (PantomimeExtensions) ++ ++- (void) appendCFormat: (NSString *) theFormat, ...; ++- (void) appendCString: (const char *) theCString; ++ ++@end ++ ++@implementation NSMutableData (PantomimeExtensions) ++ ++- (void) appendCFormat: (NSString *) theFormat, ... ++{ ++ NSString *aString; ++ va_list args; ++ ++ va_start(args, theFormat); ++ aString = [[NSString alloc] initWithFormat: theFormat arguments: args]; ++ va_end(args); ++ ++ // We allow lossy conversion to not lose any information / raise an exception ++ [self appendData: [aString dataUsingEncoding: NSASCIIStringEncoding allowLossyConversion: YES]]; ++ ++ RELEASE(aString); ++} ++ ++ ++// ++// ++// ++- (void) appendCString: (const char *) theCString ++{ ++ [self appendBytes: theCString length: strlen(theCString)]; ++} ++ ++@end ++ ++#endif ++ ++@implementation NSString(Imap4) ++ ++#if __APPLE__ ++ + static void _encodeToModifiedUTF7(unsigned char *_buf, int encLen, + unsigned char **result_, + unsigned int *cntRes_); +@@ -33,8 +78,6 @@ + unsigned char **buffer_, + int *bufLen_, int maxBuf); + +-@implementation NSString(Imap4) +- + - (NSString *)stringByEncodingImap4FolderName { + // TBD: this is restricted to Latin1, should be fixed to UTF-8 + /* dude.d& --> dude.d&- */ +@@ -46,12 +89,15 @@ + NSString *result = nil; + NSData *data; + +- len = [self cStringLength]; +- buf = calloc(len + 3, sizeof(char)); +- res = calloc((len * 6) + 3, sizeof(char)); +- buf[len] = '\0'; +- res[len * 6] = '\0'; +- [self getCString:(char *)buf]; ++ len = [self lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding] + 1; ++ buf = calloc(len + 3, sizeof(char)); ++ res = calloc((len * 6) + 3, sizeof(char)); ++ [self getCString:(char *)buf maxLength: len ++ encoding: NSISOLatin1StringEncoding]; ++ buf[len-1] = 0; ++ buf[len] = 0; ++ buf[len+1] = 0; ++ buf[len+2] = 0; + + while (cnt < len) { + int c = buf[cnt]; +@@ -185,70 +231,6 @@ + return [result autorelease]; + } + +-- (NSString *)stringByEscapingImap4Password { +- // TODO: perf +- unichar *buffer; +- unichar *chars; +- unsigned len, i, j; +- NSString *s; +- +- len = [self length]; +- chars = calloc(len + 2, sizeof(unichar)); +- [self getCharacters:chars]; +- +- buffer = calloc(len * 2 + 2, sizeof(unichar)); +- buffer[len * 2] = '\0'; +- +- for (i = 0, j = 0; i < len; i++, j++) { +- BOOL conv = NO; +- +- if (chars[i] <= 0x1F || chars[i] > 0x7F) { +- conv = YES; +- } +- else switch (chars[i]) { +- case '(': +- case ')': +- case '{': +- case ' ': +- case '%': +- case '*': +- case '"': +- case '\\': +- conv = YES; +- break; +- } +- +- if (conv) { +- buffer[j] = '\\'; +- j++; +- } +- buffer[j] = chars[i]; +- } +- if (chars != NULL) free(chars); chars = NULL; +- +- s = [NSString stringWithCharacters:buffer length:j]; +- if (buffer != NULL) free(buffer); buffer = NULL; +- return s; +-} +- +-@end /* NSString(Imap4) */ +- +-static void writeChunk(int _c1, int _c2, int _c3, int _pads, +- unsigned char **result_, +- unsigned int *cntRes_); +- +-static int getChar(int _cnt, int *cnt_, unsigned char *_buf) { +- int result; +- +- if ((_cnt % 2)) { +- result = _buf[*cnt_]; +- (*cnt_)++; +- } +- else { +- result = 0; +- } +- return result; +-} + static void _encodeToModifiedUTF7(unsigned char *_buf, int encLen, + unsigned char **result_, unsigned int *cntRes_) + { +@@ -276,58 +258,6 @@ + } + } + +-/* check metamail output for correctness */ +- +-static unsigned char basis_64[] = +- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +- +-static void writeChunk(int c1, int c2, int c3, int pads, unsigned char **result_, +- unsigned int *cntRes_) { +- unsigned char c; +- +- c = basis_64[c1>>2]; +- (*result_)[*cntRes_] = c; +- (*cntRes_)++; +- +- c = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)]; +- +- (*result_)[*cntRes_] = c; +- (*cntRes_)++; +- +- +- if (pads == 2) { +- ; +- } +- else if (pads) { +- c = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; +- (*result_)[*cntRes_] = c; +- (*cntRes_)++; +- } +- else { +- c = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; +- +- (*result_)[*cntRes_] = c; +- (*cntRes_)++; +- +- c = basis_64[c3 & 0x3F]; +- (*result_)[*cntRes_] = c; +- (*cntRes_)++; +- } +-} +- +-static char index_64[128] = { +- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, +- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, +- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, +- 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, +- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, +- 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, +- -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, +- 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +-}; +- +-#define char64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) +- + static int _decodeOfModifiedUTF7(unsigned char *_target, unsigned _targetLen, + unsigned *usedBytes_ , unsigned char **buffer_, + int *bufLen_, int maxBuf) +@@ -430,3 +360,299 @@ + } + return 0; + } ++ ++static void writeChunk(int _c1, int _c2, int _c3, int _pads, ++ unsigned char **result_, ++ unsigned int *cntRes_); ++ ++static int getChar(int _cnt, int *cnt_, unsigned char *_buf) { ++ int result; ++ ++ if ((_cnt % 2)) { ++ result = _buf[*cnt_]; ++ (*cnt_)++; ++ } ++ else { ++ result = 0; ++ } ++ return result; ++} ++ ++/* check metamail output for correctness */ ++ ++static unsigned char basis_64[] = ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; ++ ++static void writeChunk(int c1, int c2, int c3, int pads, unsigned char **result_, ++ unsigned int *cntRes_) { ++ unsigned char c; ++ ++ c = basis_64[c1>>2]; ++ (*result_)[*cntRes_] = c; ++ (*cntRes_)++; ++ ++ c = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)]; ++ ++ (*result_)[*cntRes_] = c; ++ (*cntRes_)++; ++ ++ ++ if (pads == 2) { ++ ; ++ } ++ else if (pads) { ++ c = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; ++ (*result_)[*cntRes_] = c; ++ (*cntRes_)++; ++ } ++ else { ++ c = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; ++ ++ (*result_)[*cntRes_] = c; ++ (*cntRes_)++; ++ ++ c = basis_64[c3 & 0x3F]; ++ (*result_)[*cntRes_] = c; ++ (*cntRes_)++; ++ } ++} ++ ++static char index_64[128] = { ++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, ++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, ++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, ++ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, ++ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, ++ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, ++ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, ++ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 ++}; ++ ++#define char64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) ++ ++#else // __APPLE__ ++ ++#define IS_PRINTABLE(c) (isascii(c) && isprint(c)) ++ ++- (NSString *)stringByEncodingImap4FolderName { ++ NSMutableData *aMutableData, *modifiedData; ++ NSString *aString; ++ ++ const char *b; ++ BOOL escaped; ++ unichar ch; ++ int i, len; ++ ++ // ++ // We UTF-7 encode _only_ the non-ASCII parts. ++ // ++ aMutableData = [[NSMutableData alloc] init]; ++ AUTORELEASE(aMutableData); ++ len = [self length]; ++ ++ for (i = 0; i < len; i++) ++ { ++ ch = [self characterAtIndex: i]; ++ ++ if (IS_PRINTABLE(ch)) ++ { ++ [aMutableData appendCFormat: @"%c", ch]; ++ } ++ else ++ { ++ int j; ++ ++ j = i+1; ++ // We got a non-ASCII character, let's get the substring and encode it using UTF-7. ++ while (j < len && !IS_PRINTABLE([self characterAtIndex: j])) ++ { ++ j++; ++ } ++ ++ // Get the substring. ++ [aMutableData appendData: [[self substringWithRange: NSMakeRange(i,j-i)] dataUsingEncoding: NSUTF7StringEncoding]]; ++ i = j-1; ++ } ++ } ++ ++ b = [aMutableData bytes]; ++ len = [aMutableData length]; ++ escaped = NO; ++ ++ // ++ // We replace: ++ // ++ // & -> &- ++ // + -> & ++ // +- -> + ++ // / -> , ++ // ++ // in order to produce our modified UTF-7 string. ++ // ++ modifiedData = [[NSMutableData alloc] init]; ++ AUTORELEASE(modifiedData); ++ ++ for (i = 0; i < len; i++, b++) ++ { ++ if (!escaped && *b == '&') ++ { ++ [modifiedData appendCString: "&-"]; ++ } ++ else if (!escaped && *b == '+') ++ { ++ if (*(b+1) == '-') ++ { ++ [modifiedData appendCString: "+"]; ++ } ++ else ++ { ++ [modifiedData appendCString: "&"]; ++ ++ // We enter the escaped mode. ++ escaped = YES; ++ } ++ } ++ else if (escaped && *b == '/') ++ { ++ [modifiedData appendCString: ","]; ++ } ++ else if (escaped && *b == '-') ++ { ++ [modifiedData appendCString: "-"]; ++ ++ // We leave the escaped mode. ++ escaped = NO; ++ } ++ else ++ { ++ [modifiedData appendCFormat: @"%c", *b]; ++ } ++ } ++ ++ // If we're still in the escaped mode we haven't added our trailing -, ++ // let's add it right now. ++ if (escaped) ++ { ++ [modifiedData appendCString: "-"]; ++ } ++ ++ aString = AUTORELEASE([[NSString alloc] initWithData: modifiedData encoding: NSASCIIStringEncoding]); ++ ++ return (aString != nil ? aString : self); ++} ++ ++// ++// ++// ++- (NSString *)stringByDecodingImap4FolderName { ++ NSMutableData *aMutableData; ++ ++ BOOL escaped; ++ unichar ch; ++ int i, len; ++ ++ aMutableData = [[NSMutableData alloc] init]; ++ AUTORELEASE(aMutableData); ++ ++ len = [self length]; ++ escaped = NO; ++ ++ // ++ // We replace: ++ // ++ // & -> + ++ // &- -> & ++ // , -> / ++ // ++ // If we are in escaped mode. That is, between a &....- ++ // ++ for (i = 0; i < len; i++) ++ { ++ ch = [self characterAtIndex: i]; ++ ++ if (!escaped && ch == '&') ++ { ++ if ( (i+1) < len && [self characterAtIndex: (i+1)] != '-' ) ++ { ++ [aMutableData appendCString: "+"]; ++ ++ // We enter the escaped mode. ++ escaped = YES; ++ } ++ else ++ { ++ // We replace &- by & ++ [aMutableData appendCString: "&"]; ++ i++; ++ } ++ } ++ else if (escaped && ch == ',') ++ { ++ [aMutableData appendCString: "/"]; ++ } ++ else if (escaped && ch == '-') ++ { ++ [aMutableData appendCString: "-"]; ++ ++ // We leave the escaped mode. ++ escaped = NO; ++ } ++ else ++ { ++ [aMutableData appendCFormat: @"%c", ch]; ++ } ++ } ++ ++ return AUTORELEASE([[NSString alloc] initWithData: aMutableData encoding: NSUTF7StringEncoding]); ++} ++ ++ ++#endif // __APPLE__ ++ ++- (NSString *)stringByEscapingImap4Password { ++ // TODO: perf ++ unichar *buffer; ++ unichar *chars; ++ unsigned len, i, j; ++ NSString *s; ++ ++ len = [self length]; ++ chars = calloc(len + 2, sizeof(unichar)); ++ [self getCharacters:chars]; ++ ++ buffer = calloc(len * 2 + 2, sizeof(unichar)); ++ buffer[len * 2] = '\0'; ++ ++ for (i = 0, j = 0; i < len; i++, j++) { ++ BOOL conv = NO; ++ ++ if (chars[i] <= 0x1F || chars[i] > 0x7F) { ++ conv = YES; ++ } ++ else switch (chars[i]) { ++ case '(': ++ case ')': ++ case '{': ++ case ' ': ++ case '%': ++ case '*': ++ case '"': ++ case '\\': ++ conv = YES; ++ break; ++ } ++ ++ if (conv) { ++ buffer[j] = '\\'; ++ j++; ++ } ++ buffer[j] = chars[i]; ++ } ++ if (chars != NULL) free(chars); chars = NULL; ++ ++ s = [NSString stringWithCharacters:buffer length:j]; ++ if (buffer != NULL) free(buffer); buffer = NULL; ++ return s; ++} ++ ++@end /* NSString(Imap4) */ Index: sope-mime/NGMail/NGSmtpClient.m =================================================================== --- sope-mime/NGMail/NGSmtpClient.m (révision 1626) @@ -1765,6 +2335,31 @@ Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m if (date == nil) goto failed; #if 0 +Index: sope-mime/NGMime/NGMimeMultipartBodyParser.m +=================================================================== +--- sope-mime/NGMime/NGMimeMultipartBodyParser.m (révision 1626) ++++ sope-mime/NGMime/NGMimeMultipartBodyParser.m (copie de travail) +@@ -428,6 +428,7 @@ + NSString *boundary = nil; + NSArray *rawBodyParts = nil; + BOOL foundError = NO; ++ NSData *boundaryBytes; + + contentType = [_part contentType]; + boundary = [contentType valueOfParameter:@"boundary"]; +@@ -437,9 +438,10 @@ + + *(&foundError) = NO; + ++ boundaryBytes = [boundary dataUsingEncoding:NSISOLatin1StringEncoding]; + *(&rawBodyParts) = [self _parseBody:_body part:_part data:_data +- boundary:[boundary cString] +- length:[boundary cStringLength] ++ boundary:[boundaryBytes bytes] ++ length:[boundary length] + delegate:_d]; + + if (rawBodyParts) { Index: sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m =================================================================== --- sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m (révision 1626) @@ -1781,7 +2376,42 @@ Index: sope-mime/NGMime/NGMimeType.m =================================================================== --- sope-mime/NGMime/NGMimeType.m (révision 1626) +++ sope-mime/NGMime/NGMimeType.m (copie de travail) -@@ -152,7 +152,7 @@ +@@ -120,28 +120,23 @@ + + /* some unsupported, but known encoding */ + else if ([charset isEqualToString:@"ks_c_5601-1987"]) { +- encoding = [NSString defaultCStringEncoding]; ++ encoding = NSISOLatin1StringEncoding; + foundUnsupported = YES; + } + else if ([charset isEqualToString:@"euc-kr"]) { +- encoding = [NSString defaultCStringEncoding]; +- foundUnsupported = YES; ++ encoding = NSKoreanEUCStringEncoding; + } + else if ([charset isEqualToString:@"big5"]) { +- encoding = [NSString defaultCStringEncoding]; +- foundUnsupported = YES; ++ encoding = NSBIG5StringEncoding; + } + else if ([charset isEqualToString:@"iso-2022-jp"]) { +- encoding = [NSString defaultCStringEncoding]; +- foundUnsupported = YES; ++ encoding = NSISO2022JPStringEncoding; + } + else if ([charset isEqualToString:@"gb2312"]) { +- encoding = [NSString defaultCStringEncoding]; +- foundUnsupported = YES; ++ encoding = NSGB2312StringEncoding; + } + else if ([charset isEqualToString:@"koi8-r"]) { +- encoding = [NSString defaultCStringEncoding]; +- foundUnsupported = YES; ++ encoding = NSKOI8RStringEncoding; + } + + else if ([charset isEqualToString:@"windows-1252"]) { +@@ -152,7 +147,7 @@ } else if ([charset isEqualToString:@"x-unknown"] || [charset isEqualToString:@"unknown"]) { @@ -1790,6 +2420,56 @@ Index: sope-mime/NGMime/NGMimeType.m } /* ISO Latin 9 */ #if !(NeXT_Foundation_LIBRARY || APPLE_Foundation_LIBRARY) +@@ -166,7 +161,7 @@ + else { + [self logWithFormat:@"%s: unknown charset '%@'", + __PRETTY_FUNCTION__, _s]; +- encoding = [NSString defaultCStringEncoding]; ++ encoding = NSISOLatin1StringEncoding; + } + return encoding; + } +@@ -385,23 +380,26 @@ + } + + - (BOOL)valueNeedsQuotes:(NSString *)_parameterValue { +- unsigned len = [_parameterValue cStringLength]; +- char buf[len + 15]; +- char *cstr; ++ NSData *stringData; ++ const char *cstr; ++ unsigned int count, max; ++ BOOL needsQuote; + +- cstr = &(buf[0]); ++ needsQuote = NO; + +- [_parameterValue getCString:cstr]; cstr[len] = '\0'; +- while (*cstr) { +- if (isMime_SpecialByte(*cstr)) +- return YES; +- +- if (*cstr == 32) +- return YES; +- +- cstr++; ++ stringData = [_parameterValue dataUsingEncoding:NSUTF8StringEncoding]; ++ cstr = [stringData bytes]; ++ max = [stringData length]; ++ count = 0; ++ while (!needsQuote && count < max) { ++ if (isMime_SpecialByte(*(cstr + count)) ++ || *(cstr + count) == 32) ++ needsQuote = YES; ++ else ++ count++; + } +- return NO; ++ ++ return needsQuote; + } + + - (NSString *)stringValue { Index: sope-mime/NGMime/NGMimeBodyPart.m =================================================================== --- sope-mime/NGMime/NGMimeBodyPart.m (révision 1626) @@ -1868,6 +2548,171 @@ Index: sope-mime/NGMime/ChangeLog 2008-01-29 Albrecht Dress * fixes for OGo bug #789 (reply-to QP encoding) +Index: sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m +=================================================================== +--- sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m (révision 1626) ++++ sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m (copie de travail) +@@ -36,8 +36,7 @@ + NGMimeType *type = nil; // only one content-type field + NSString *tmp = nil; + NSMutableData *data = nil; +- unsigned char *ctmp = NULL; +- unsigned len = 0; ++ NSData *valueData; + + type = _value; + +@@ -59,21 +58,15 @@ + + tmp = [type type]; + NSAssert(tmp, @"type should not be nil"); +- len = [tmp length]; +- ctmp = malloc(len + 4); +- [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; +- [data appendBytes:ctmp length:len]; +- free(ctmp); ++ valueData = [tmp dataUsingEncoding: NSISOLatin1StringEncoding]; ++ [data appendData: valueData]; ++ ++ [data appendBytes:"/" length:1]; + +- [data appendBytes:"//" length:1]; +- + tmp = [type subType]; + if (tmp != nil) { +- len = [tmp length]; +- ctmp = malloc(len + 4); +- [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; +- [data appendBytes:ctmp length:len]; +- free(ctmp); ++ valueData = [tmp dataUsingEncoding: NSISOLatin1StringEncoding]; ++ [data appendData:valueData]; + } + else + [data appendBytes:"*" length:1]; +@@ -91,12 +84,9 @@ + continue; + } + [data appendBytes:"; " length:2]; +- +- len = [name cStringLength]; +- ctmp = malloc(len + 1); +- [name getCString:(char *)ctmp]; ctmp[len] = '\0'; +- [data appendBytes:ctmp length:len]; +- free(ctmp); ++ ++ valueData = [name dataUsingEncoding: NSUTF8StringEncoding]; ++ [data appendData: valueData]; + + /* + this confuses GroupWise: "= \"" (a space) +@@ -105,66 +95,30 @@ + + /* check for encoding */ + { +- unsigned cnt; ++ unsigned cnt, max; ++ const char *dataBytes; + BOOL doEnc; + +- len = [value cStringLength]; +- ctmp = malloc(len + 4); +- [value getCString:(char *)ctmp]; ctmp[len] = '\0'; +- cnt = 0; ++ valueData = [value dataUsingEncoding:NSUTF8StringEncoding]; ++ dataBytes = [valueData bytes]; ++ max = [valueData length]; ++ + doEnc = NO; +- while (cnt < len) { +- if ((unsigned char)ctmp[cnt] > 127) { ++ cnt = 0; ++ while (!doEnc && cnt < max) { ++ if ((unsigned char)dataBytes[cnt] > 127) + doEnc = YES; +- break; +- } +- cnt++; ++ else ++ cnt++; + } + if (doEnc) { +- unsigned char iso[] = "=?iso-8859-15?q?"; +- unsigned isoLen = 16; +- unsigned char isoEnd[] = "?="; +- unsigned isoEndLen = 2; +- unsigned desLen; +- unsigned char *des; +- +- if (ctmp) free(ctmp); +- { +- NSData *data; +- +-#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY +- data = [value dataUsingEncoding:NSISOLatin1StringEncoding]; +-#else +- data = [value dataUsingEncoding:NSISOLatin9StringEncoding]; +-#endif +- +- len = [data length]; +- ctmp = malloc(len + 10); +- [data getBytes:ctmp]; ctmp[len] = '\0'; +- } +- +- desLen = len * 3 + 20; +- des = calloc(desLen + 10, sizeof(char)); +- +- memcpy(des, ctmp, cnt); +- memcpy(des + cnt, iso, isoLen); +- desLen = +- NGEncodeQuotedPrintableMime(ctmp + cnt, len - cnt, +- des + cnt + isoLen, +- desLen - cnt - isoLen); +- if ((int)desLen != -1) { +- memcpy(des + cnt + isoLen + desLen, isoEnd, isoEndLen); +- [data appendBytes:des length:(cnt + isoLen + desLen + isoEndLen)]; +- } +- else { +- NSLog(@"WARNING: An error occour during quoted-printable decoding"); +- } +- if (des) free(des); ++ [data appendBytes:"=?utf-8?q?" length:10]; ++ [data appendData: [valueData dataByEncodingQuotedPrintable]]; ++ [data appendBytes:"?=" length:2]; + } + else { +- [data appendBytes:ctmp length:len]; ++ [data appendData: valueData]; + } +- free(ctmp); + } + [data appendBytes:"\"" length:1]; + } +Index: sope-mime/NGMime/NGMimePartGenerator.m +=================================================================== +--- sope-mime/NGMime/NGMimePartGenerator.m (révision 1626) ++++ sope-mime/NGMime/NGMimePartGenerator.m (copie de travail) +@@ -155,8 +155,9 @@ + BOOL isMultiValue, isFirst; + + /* get field name and strip leading spaces */ +- fcname = (const unsigned char *)[_field cString]; +- for (len = [_field cStringLength]; len > 0; fcname++, len--) { ++ fcname = (const unsigned char *)[_field cStringUsingEncoding:NSISOLatin1StringEncoding]; ++ for (len = [_field lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding]; ++ len > 0; fcname++, len--) { + if (*fcname != ' ') + break; + } +@@ -328,7 +329,7 @@ + if ([body isKindOfClass:[NSData class]]) + data = body; + else if ([body isKindOfClass:[NSString class]]) +- data = [body dataUsingEncoding:[NSString defaultCStringEncoding]]; ++ data = [body dataUsingEncoding: NSISOLatin1StringEncoding]; + else + data = nil; + Index: sope-mime/NGMime/NGMimeBodyParser.m =================================================================== --- sope-mime/NGMime/NGMimeBodyParser.m (révision 1626)