(fix) properly encode MIME parts with embedded images in HTML parts (fixes #4150)
This commit is contained in:
parent
399397bd79
commit
c29c6dc621
|
@ -295,7 +295,7 @@
|
||||||
NSData *data;
|
NSData *data;
|
||||||
id body;
|
id body;
|
||||||
|
|
||||||
int i, j, k;
|
int i, j, k, len;
|
||||||
|
|
||||||
i = [value indexOf: ';'];
|
i = [value indexOf: ';'];
|
||||||
j = [value indexOf: ';' fromIndex: i+1];
|
j = [value indexOf: ';' fromIndex: i+1];
|
||||||
|
@ -326,17 +326,39 @@
|
||||||
encoding = @"base64";
|
encoding = @"base64";
|
||||||
|
|
||||||
data = [[value substringFromIndex: k+1] dataUsingEncoding: NSASCIIStringEncoding];
|
data = [[value substringFromIndex: k+1] dataUsingEncoding: NSASCIIStringEncoding];
|
||||||
|
len = [data length];
|
||||||
|
if ([encoding isEqualToString: @"base64"] && len > 72)
|
||||||
|
{
|
||||||
|
NSMutableData *folded_data;
|
||||||
|
unsigned char *bytes, c;
|
||||||
|
|
||||||
|
folded_data = [NSMutableData data];
|
||||||
|
bytes = (unsigned char *)[data bytes];
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if (i > 0 && i % 72 == 0)
|
||||||
|
{
|
||||||
|
c = '\n';
|
||||||
|
[folded_data appendBytes: &c length: 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
c = *bytes; bytes++;
|
||||||
|
[folded_data appendBytes: &c length: 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
data = folded_data;
|
||||||
|
}
|
||||||
|
|
||||||
uniqueId = [SOGoObject globallyUniqueObjectId];
|
uniqueId = [SOGoObject globallyUniqueObjectId];
|
||||||
|
|
||||||
map = [[[NGMutableHashMap alloc] initWithCapacity:5] autorelease];
|
map = [[[NGMutableHashMap alloc] initWithCapacity: 5] autorelease];
|
||||||
[map setObject: encoding forKey: @"content-transfer-encoding"];
|
[map setObject: encoding forKey: @"content-transfer-encoding"];
|
||||||
[map setObject:[NSNumber numberWithInt:[data length]] forKey: @"content-length"];
|
[map setObject:[NSNumber numberWithInt: [data length]] forKey: @"content-length"];
|
||||||
[map setObject: [NSString stringWithFormat: @"inline; filename=\"%@\"", uniqueId] forKey: @"content-disposition"];
|
[map setObject: [NSString stringWithFormat: @"inline; filename=\"%@\"", uniqueId] forKey: @"content-disposition"];
|
||||||
[map setObject: [NSString stringWithFormat: @"%@; name=\"%@\"", mimeType, uniqueId] forKey: @"content-type"];
|
[map setObject: [NSString stringWithFormat: @"%@; name=\"%@\"", mimeType, uniqueId] forKey: @"content-type"];
|
||||||
[map setObject: [NSString stringWithFormat: @"<%@>", uniqueId] forKey: @"content-id"];
|
[map setObject: [NSString stringWithFormat: @"<%@>", uniqueId] forKey: @"content-id"];
|
||||||
|
|
||||||
|
|
||||||
body = [[NGMimeFileData alloc] initWithBytes: [data bytes] length: [data length]];
|
body = [[NGMimeFileData alloc] initWithBytes: [data bytes] length: [data length]];
|
||||||
|
|
||||||
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
|
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
|
||||||
|
|
|
@ -1307,7 +1307,7 @@ static NSString *userAgent = nil;
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
- (NGMimeBodyPart *) mimeMultipartAlternative
|
- (NGMimeBodyPart *) mimeMultipartAlternative: (NSArray *) extractedBodyParts
|
||||||
{
|
{
|
||||||
NGMimeMultipartBody *textParts;
|
NGMimeMultipartBody *textParts;
|
||||||
NGMutableHashMap *header;
|
NGMutableHashMap *header;
|
||||||
|
@ -1323,8 +1323,35 @@ static NSString *userAgent = nil;
|
||||||
// Get the text part from it and add it
|
// Get the text part from it and add it
|
||||||
[textParts addBodyPart: [self plainTextBodyPartForText]];
|
[textParts addBodyPart: [self plainTextBodyPartForText]];
|
||||||
|
|
||||||
// Add the HTML part
|
if ([extractedBodyParts count])
|
||||||
[textParts addBodyPart: [self bodyPartForText]];
|
{
|
||||||
|
// Create a multipart/related part and add this.
|
||||||
|
// We have inline image to avoid Thunderbird bug #61815 (https://bugzilla.mozilla.org/show_bug.cgi?id=61815)
|
||||||
|
NGMutableHashMap *relatedHeader;
|
||||||
|
NGMimeBodyPart *relatedPart;
|
||||||
|
NGMimeMultipartBody *relatedParts;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
relatedHeader = [NGMutableHashMap hashMap];
|
||||||
|
[relatedHeader addObject: MultiRelatedType forKey: @"content-type"];
|
||||||
|
relatedPart = [NGMimeBodyPart bodyPartWithHeader: relatedHeader];
|
||||||
|
relatedParts = [[NGMimeMultipartBody alloc] initWithPart: relatedPart];
|
||||||
|
|
||||||
|
[relatedParts addBodyPart: [self bodyPartForText]];
|
||||||
|
|
||||||
|
for (i = 0; i < [extractedBodyParts count]; i++)
|
||||||
|
{
|
||||||
|
[relatedParts addBodyPart: [extractedBodyParts objectAtIndex: i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
[relatedPart setBody: relatedParts];
|
||||||
|
[textParts addBodyPart: relatedPart];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add the HTML part
|
||||||
|
[textParts addBodyPart: [self bodyPartForText]];
|
||||||
|
}
|
||||||
|
|
||||||
[part setBody: textParts];
|
[part setBody: textParts];
|
||||||
RELEASE(textParts);
|
RELEASE(textParts);
|
||||||
|
@ -1336,7 +1363,8 @@ static NSString *userAgent = nil;
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
- (NGMimeMessage *) mimeMultiPartMessageWithHeaderMap: (NGMutableHashMap *) map
|
- (NGMimeMessage *) mimeMultiPartMessageWithHeaderMap: (NGMutableHashMap *) map
|
||||||
andBodyParts: (NSArray *) _bodyParts
|
extractedBodyParts: (NSArray *) extractedBodyParts
|
||||||
|
andBodyParts: (NSArray *) _bodyParts
|
||||||
{
|
{
|
||||||
NGMimeMessage *message;
|
NGMimeMessage *message;
|
||||||
NGMimeMultipartBody *mBody;
|
NGMimeMultipartBody *mBody;
|
||||||
|
@ -1352,7 +1380,7 @@ static NSString *userAgent = nil;
|
||||||
if (!isHTML)
|
if (!isHTML)
|
||||||
part = [self bodyPartForText];
|
part = [self bodyPartForText];
|
||||||
else
|
else
|
||||||
part = [self mimeMultipartAlternative];
|
part = [self mimeMultipartAlternative: extractedBodyParts];
|
||||||
|
|
||||||
[mBody addBodyPart: part];
|
[mBody addBodyPart: part];
|
||||||
|
|
||||||
|
@ -1551,26 +1579,20 @@ static NSString *userAgent = nil;
|
||||||
excluding: (NSArray *) _exclude
|
excluding: (NSArray *) _exclude
|
||||||
extractingImages: (BOOL) _extractImages
|
extractingImages: (BOOL) _extractImages
|
||||||
{
|
{
|
||||||
NSMutableArray *bodyParts;
|
NSMutableArray *extractedBodyParts;
|
||||||
NGMimeMessage *message;
|
NGMimeMessage *message;
|
||||||
NSArray *allBodyParts;
|
NSArray *allBodyParts;
|
||||||
NGMutableHashMap *map;
|
NGMutableHashMap *map;
|
||||||
NSString *newText;
|
NSString *newText;
|
||||||
|
|
||||||
BOOL has_inline_images;
|
|
||||||
|
|
||||||
message = nil;
|
message = nil;
|
||||||
has_inline_images = NO;
|
extractedBodyParts = [NSMutableArray array];
|
||||||
bodyParts = [NSMutableArray array];
|
|
||||||
|
|
||||||
if (_extractImages)
|
if (_extractImages)
|
||||||
{
|
{
|
||||||
newText = [text htmlByExtractingImages: bodyParts];
|
newText = [text htmlByExtractingImages: extractedBodyParts];
|
||||||
if ([bodyParts count])
|
if ([extractedBodyParts count])
|
||||||
{
|
[self setText: newText];
|
||||||
[self setText: newText];
|
|
||||||
has_inline_images = YES;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map = [self mimeHeaderMapWithHeaders: _headers
|
map = [self mimeHeaderMapWithHeaders: _headers
|
||||||
|
@ -1583,25 +1605,16 @@ static NSString *userAgent = nil;
|
||||||
if (!allBodyParts)
|
if (!allBodyParts)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
[bodyParts addObjectsFromArray: allBodyParts];
|
|
||||||
|
|
||||||
//[self debugWithFormat: @"attachments: %@", bodyParts];
|
//[self debugWithFormat: @"attachments: %@", bodyParts];
|
||||||
|
|
||||||
if ([bodyParts count] == 0)
|
if ([extractedBodyParts count] == 0 && [allBodyParts count] == 0)
|
||||||
/* no attachments */
|
/* no attachments */
|
||||||
message = [self mimeMessageForContentWithHeaderMap: map];
|
message = [self mimeMessageForContentWithHeaderMap: map];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// attachments, create multipart/mixed or multipart/related if
|
|
||||||
// we have inline image to avoid Thunderbird bug #61815 (https://bugzilla.mozilla.org/show_bug.cgi?id=61815)
|
|
||||||
if (has_inline_images)
|
|
||||||
{
|
|
||||||
[map removeAllObjectsForKey: @"content-type"];
|
|
||||||
[map addObject: MultiRelatedType forKey: @"content-type"];
|
|
||||||
}
|
|
||||||
|
|
||||||
message = [self mimeMultiPartMessageWithHeaderMap: map
|
message = [self mimeMultiPartMessageWithHeaderMap: map
|
||||||
andBodyParts: bodyParts];
|
extractedBodyParts: extractedBodyParts
|
||||||
|
andBodyParts: allBodyParts];
|
||||||
|
|
||||||
//[self debugWithFormat: @"message: %@", message];
|
//[self debugWithFormat: @"message: %@", message];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue