From de867287924d75b7984f51b2c92cf1f75d56ef2a Mon Sep 17 00:00:00 2001 From: helge Date: Sat, 2 Oct 2004 15:39:10 +0000 Subject: [PATCH] added quoted printable envelope decoding git-svn-id: http://svn.opengroupware.org/SOPE/trunk@216 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- sope-mime/ChangeLog | 6 ++ sope-mime/NGImap4/ChangeLog | 4 + sope-mime/NGImap4/NGImap4EnvelopeAddress.h | 4 +- sope-mime/NGImap4/NGImap4ResponseParser.m | 73 +++++++++++++++---- sope-mime/NGMail/NGMimeMessageGenerator.m | 4 +- sope-mime/NGMail/NGMimeMessageParser.m | 7 +- sope-mime/NGMime/ChangeLog | 2 + .../NGMimeAddressHeaderFieldGenerator.m | 6 +- ...meContentDispositionHeaderFieldGenerator.m | 4 +- .../NGMimeContentTypeHeaderFieldGenerator.m | 4 +- sope-mime/NGMime/NGMimeUtilities.h | 5 +- sope-mime/Version | 2 +- 12 files changed, 87 insertions(+), 34 deletions(-) diff --git a/sope-mime/ChangeLog b/sope-mime/ChangeLog index 737d468c..eb66ddc0 100644 --- a/sope-mime/ChangeLog +++ b/sope-mime/ChangeLog @@ -1,5 +1,11 @@ 2004-10-02 Helge Hess + * v4.3.187 + + * NGMime, NGMail: minor cleanups + + * NGImap4: decode quoted printable subjects and addresses + * NGImap4: fixed long subject envelope processing (v4.3.186) * NGImap4: improved processing of envelope responses (v4.3.185) diff --git a/sope-mime/NGImap4/ChangeLog b/sope-mime/NGImap4/ChangeLog index b3bf7ba5..8b10394d 100644 --- a/sope-mime/NGImap4/ChangeLog +++ b/sope-mime/NGImap4/ChangeLog @@ -1,5 +1,9 @@ 2004-10-02 Helge Hess + * NGImap4ResponseParser.m: decode quoted printable in personal names + of envelope addresses and in the subject, fixed a memory leak in the + envelope parser (v4.3.187) + * NGImap4ResponseParser.m: support data-style subjects in envelopes (v4.3.186) diff --git a/sope-mime/NGImap4/NGImap4EnvelopeAddress.h b/sope-mime/NGImap4/NGImap4EnvelopeAddress.h index 923faf9a..6d4b5418 100644 --- a/sope-mime/NGImap4/NGImap4EnvelopeAddress.h +++ b/sope-mime/NGImap4/NGImap4EnvelopeAddress.h @@ -54,8 +54,8 @@ /* derived accessors */ -- (NSString *)baseEMail; -- (NSString *)email; +- (NSString *)baseEMail; /* returns just: mailbox@host */ +- (NSString *)email; /* returns: personalName */ @end diff --git a/sope-mime/NGImap4/NGImap4ResponseParser.m b/sope-mime/NGImap4/NGImap4ResponseParser.m index 6914756e..f40d8cd1 100644 --- a/sope-mime/NGImap4/NGImap4ResponseParser.m +++ b/sope-mime/NGImap4/NGImap4ResponseParser.m @@ -127,8 +127,9 @@ static unsigned Imap4MMDataBoundary = 0; static BOOL debugOn = NO; static BOOL debugDataOn = NO; static NSStringEncoding encoding; -static Class StrClass = Nil; -static Class NumClass = Nil; +static Class StrClass = Nil; +static Class NumClass = Nil; +static Class DataClass = Nil; static NSStringEncoding defCStringEncoding; static NSNumber *YesNum = nil; static NSNumber *NoNum = nil; @@ -154,10 +155,11 @@ static NSNull *null = nil; /* Note: this should be larger than a usual header size! */ Imap4MMDataBoundary = 2 * LaSize; - StrClass = [NSString class]; - NumClass = [NSNumber class]; - YesNum = [[NumClass numberWithBool:YES] retain]; - NoNum = [[NumClass numberWithBool:NO] retain]; + StrClass = [NSString class]; + NumClass = [NSNumber class]; + DataClass = [NSData class]; + YesNum = [[NumClass numberWithBool:YES] retain]; + NoNum = [[NumClass numberWithBool:NO] retain]; } + (id)parserWithStream:(id)_stream { @@ -389,7 +391,7 @@ static void _parseSieveRespone(NGImap4ResponseParser *self, [stream close]; [stream release]; stream = nil; - result = [NSData dataWithContentsOfMappedFile:path]; + result = [DataClass dataWithContentsOfMappedFile:path]; [[NSFileManager defaultManager] removeFileAtPath:path handler:nil]; return result; @@ -430,7 +432,7 @@ static void _parseSieveRespone(NGImap4ResponseParser *self, cnt++; } - result = [NSData dataWithBytesNoCopy:tmpBuf length:tmpBufCnt]; + result = [DataClass dataWithBytesNoCopy:tmpBuf length:tmpBufCnt]; if (buf != NULL) free(buf); buf = NULL; return result; @@ -972,6 +974,38 @@ static BOOL _parseThreadResponse(NGImap4ResponseParser *self, return nil; } +- (id)_decodeQP:(id)_string headerField:(NSString *)_field { + if (![_string isNotNull]) + return _string; + + if ([_string isKindOfClass:DataClass]) + return [_string decodeQuotedPrintableValueOfMIMEHeaderField:_field]; + + if ([_string isKindOfClass:StrClass]) { + if ([_string length] <= 6 /* minimum size */) + return _string; + if ([_string characterAtIndex:0] == '=' && + [_string characterAtIndex:1] == '?') { + NSData *data; + + if (debugOn) + [self debugWithFormat:@"WARNING: string with quoted printable info!"]; + + // TODO: this is really expensive ... + data = [_string dataUsingEncoding:NSUTF8StringEncoding]; + if (data != nil) { + NSData *qpData; + + qpData = [data decodeQuotedPrintableValueOfMIMEHeaderField:_field]; + if (qpData != data) return qpData; + } + } + return _string; + } + + return _string; +} + - (NGImap4EnvelopeAddress *)_parseEnvelopeAddressStructure { /* Note: returns retained object! @@ -995,11 +1029,18 @@ static BOOL _parseThreadResponse(NGImap4ResponseParser *self, return nil; } _consume(self, 1); // '(' + + /* parse personal name, can be with quoted printable encoding! */ + + pname = [self _parseQuotedStringOrNIL]; + if ([pname isNotNull]) + pname = [self _decodeQP:pname headerField:@"subject"]; + [self _consumeOptionalSpace]; - pname = [[self _parseQuotedStringOrNIL] copy]; [self _consumeOptionalSpace]; - route = [[self _parseQuotedStringOrNIL] copy]; [self _consumeOptionalSpace]; - mailbox = [[self _parseQuotedStringOrNIL] copy];[self _consumeOptionalSpace]; - host = [[self _parseQuotedStringOrNIL] copy]; [self _consumeOptionalSpace]; + // TODO: I think those forbid QP encoding? + route = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; + mailbox = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; + host = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; if (_la(self, 0) != ')') { [self logWithFormat:@"WARNING: IMAP4 envelope " @@ -1092,11 +1133,13 @@ static BOOL _parseThreadResponse(NGImap4ResponseParser *self, /* parse subject */ - if ((tmp = [self _parseQuotedStringOrDataOrNIL])) { + if ((tmp = [self _parseQuotedStringOrDataOrNIL]) != nil) { // TODO: that one is an issue, the client does know the requested charset // but doesn't pass it down to the parser? Requiring the client to // deal with NSData's is a bit overkill? - env->subject = [tmp isNotNull] ? [tmp copy] : nil; + env->subject = [tmp isNotNull] + ? [[self _decodeQP:tmp headerField:@"subject"] copy] + : nil; [self _consumeOptionalSpace]; } else { @@ -1412,7 +1455,7 @@ static NSString *_parseBodyDecodeString(NGImap4ResponseParser *self, static NSString *_parseBodyString(NGImap4ResponseParser *self, BOOL _convertString) { - return _parseBodyDecodeString(self, _convertString, NO); + return _parseBodyDecodeString(self, _convertString, NO /* no decode */); } static NSDictionary *_parseBodyParameterList(NGImap4ResponseParser *self) diff --git a/sope-mime/NGMail/NGMimeMessageGenerator.m b/sope-mime/NGMail/NGMimeMessageGenerator.m index 4f4928aa..6e61755f 100644 --- a/sope-mime/NGMail/NGMimeMessageGenerator.m +++ b/sope-mime/NGMail/NGMimeMessageGenerator.m @@ -18,7 +18,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ +// $Id: NGMimeMessageGenerator.m 11 2004-08-20 19:20:03Z helge $ #include "NGMimeMessageGenerator.h" #include "NGMimeMessage.h" @@ -142,7 +142,7 @@ _base64Encoding(NGMimeBodyGenerator *self, } cnt++; } - if (doEnc == YES) { + if (doEnc) { char iso[] = "=?iso-8859-15?q?"; unsigned isoLen = 16; char isoEnd[] = "?="; diff --git a/sope-mime/NGMail/NGMimeMessageParser.m b/sope-mime/NGMail/NGMimeMessageParser.m index f3c68b95..ace9611e 100644 --- a/sope-mime/NGMail/NGMimeMessageParser.m +++ b/sope-mime/NGMail/NGMimeMessageParser.m @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2000-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "NGMimeMessageParser.h" #include "NGMimeMessage.h" @@ -166,7 +165,7 @@ static Class NSStringClass = Nil; int cnt, tmp; unsigned char encoding; - buffer = calloc(sizeof(unichar), length + 13); + buffer = calloc(length + 13, sizeof(unichar)); maxBufLen = length + 3; buffer[maxBufLen - 1] = '\0'; diff --git a/sope-mime/NGMime/ChangeLog b/sope-mime/NGMime/ChangeLog index 3d47c3a2..eaf949a3 100644 --- a/sope-mime/NGMime/ChangeLog +++ b/sope-mime/NGMime/ChangeLog @@ -1,5 +1,7 @@ 2004-09-30 Helge Hess + * NGMime: minor cleanups (v4.3.187) + * NGMimePartParser.m: fixed an issue with unlimited length parsing, fixes OGo bug #936 (v4.3.182) diff --git a/sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m index e1aea78e..25082e47 100644 --- a/sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m +++ b/sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m @@ -18,7 +18,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ +// $Id: NGMimeAddressHeaderFieldGenerator.m 1 2004-08-20 10:08:27Z znek $ #include "NGMimeHeaderFieldGenerator.h" #include "NGMimeHeaderFields.h" @@ -107,7 +107,7 @@ static int UseLFSeperatedAddressEntries = -1; unsigned desLen; unsigned char *des; - free(buffer); + if (buffer) free(buffer); { NSData *data; @@ -118,7 +118,7 @@ static int UseLFSeperatedAddressEntries = -1; #endif bufLen = [data length]; - buffer = malloc(bufLen+1); + buffer = malloc(bufLen + 10); [data getBytes:buffer]; buffer[bufLen] = '\0'; } diff --git a/sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m index c7421fb2..e8e7597f 100644 --- a/sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m +++ b/sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m @@ -18,7 +18,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ +// $Id: NGMimeContentDispositionHeaderFieldGenerator.m 1 2004-08-20 10:08:27Z znek $ #include "NGMimeHeaderFieldGenerator.h" #include "NGMimeHeaderFields.h" @@ -82,7 +82,7 @@ unsigned desLen; char *des; - free(ctmp); + if (ctmp) free(ctmp); { NSData *data; diff --git a/sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m index 6a2545db..e7e9a49a 100644 --- a/sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m +++ b/sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m @@ -18,7 +18,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ +// $Id: NGMimeContentTypeHeaderFieldGenerator.m 1 2004-08-20 10:08:27Z znek $ #include "NGMimeHeaderFieldGenerator.h" #include "NGMimeHeaderFields.h" @@ -139,7 +139,7 @@ #endif len = [data length]; - ctmp = malloc(len+1); + ctmp = malloc(len + 10); [data getBytes:ctmp]; ctmp[len] = '\0'; } diff --git a/sope-mime/NGMime/NGMimeUtilities.h b/sope-mime/NGMime/NGMimeUtilities.h index 78c50890..29e10c11 100644 --- a/sope-mime/NGMime/NGMimeUtilities.h +++ b/sope-mime/NGMime/NGMimeUtilities.h @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2000-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #ifndef __NGMime_NGMimeUtilities_H__ #define __NGMime_NGMimeUtilities_H__ diff --git a/sope-mime/Version b/sope-mime/Version index 9033d0e8..b223b20b 100644 --- a/sope-mime/Version +++ b/sope-mime/Version @@ -2,6 +2,6 @@ MAJOR_VERSION:=4 MINOR_VERSION:=3 -SUBMINOR_VERSION:=186 +SUBMINOR_VERSION:=187 # v4.2.149 requires libNGStreams v4.2.34 -- 2.39.5