(fix) properly encode MIME parts with embedded images in HTML parts (fixes #4150)
parent
399397bd79
commit
c29c6dc621
|
@ -295,7 +295,7 @@
|
|||
NSData *data;
|
||||
id body;
|
||||
|
||||
int i, j, k;
|
||||
int i, j, k, len;
|
||||
|
||||
i = [value indexOf: ';'];
|
||||
j = [value indexOf: ';' fromIndex: i+1];
|
||||
|
@ -326,17 +326,39 @@
|
|||
encoding = @"base64";
|
||||
|
||||
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];
|
||||
|
||||
map = [[[NGMutableHashMap alloc] initWithCapacity:5] autorelease];
|
||||
map = [[[NGMutableHashMap alloc] initWithCapacity: 5] autorelease];
|
||||
[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: @"%@; name=\"%@\"", mimeType, uniqueId] forKey: @"content-type"];
|
||||
[map setObject: [NSString stringWithFormat: @"<%@>", uniqueId] forKey: @"content-id"];
|
||||
|
||||
|
||||
body = [[NGMimeFileData alloc] initWithBytes: [data bytes] length: [data length]];
|
||||
|
||||
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
|
||||
|
|
|
@ -1307,7 +1307,7 @@ static NSString *userAgent = nil;
|
|||
//
|
||||
//
|
||||
//
|
||||
- (NGMimeBodyPart *) mimeMultipartAlternative
|
||||
- (NGMimeBodyPart *) mimeMultipartAlternative: (NSArray *) extractedBodyParts
|
||||
{
|
||||
NGMimeMultipartBody *textParts;
|
||||
NGMutableHashMap *header;
|
||||
|
@ -1323,8 +1323,35 @@ static NSString *userAgent = nil;
|
|||
// Get the text part from it and add it
|
||||
[textParts addBodyPart: [self plainTextBodyPartForText]];
|
||||
|
||||
// Add the HTML part
|
||||
[textParts addBodyPart: [self bodyPartForText]];
|
||||
if ([extractedBodyParts count])
|
||||
{
|
||||
// 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];
|
||||
RELEASE(textParts);
|
||||
|
@ -1336,7 +1363,8 @@ static NSString *userAgent = nil;
|
|||
//
|
||||
//
|
||||
- (NGMimeMessage *) mimeMultiPartMessageWithHeaderMap: (NGMutableHashMap *) map
|
||||
andBodyParts: (NSArray *) _bodyParts
|
||||
extractedBodyParts: (NSArray *) extractedBodyParts
|
||||
andBodyParts: (NSArray *) _bodyParts
|
||||
{
|
||||
NGMimeMessage *message;
|
||||
NGMimeMultipartBody *mBody;
|
||||
|
@ -1352,7 +1380,7 @@ static NSString *userAgent = nil;
|
|||
if (!isHTML)
|
||||
part = [self bodyPartForText];
|
||||
else
|
||||
part = [self mimeMultipartAlternative];
|
||||
part = [self mimeMultipartAlternative: extractedBodyParts];
|
||||
|
||||
[mBody addBodyPart: part];
|
||||
|
||||
|
@ -1551,26 +1579,20 @@ static NSString *userAgent = nil;
|
|||
excluding: (NSArray *) _exclude
|
||||
extractingImages: (BOOL) _extractImages
|
||||
{
|
||||
NSMutableArray *bodyParts;
|
||||
NSMutableArray *extractedBodyParts;
|
||||
NGMimeMessage *message;
|
||||
NSArray *allBodyParts;
|
||||
NGMutableHashMap *map;
|
||||
NSString *newText;
|
||||
|
||||
BOOL has_inline_images;
|
||||
|
||||
message = nil;
|
||||
has_inline_images = NO;
|
||||
bodyParts = [NSMutableArray array];
|
||||
extractedBodyParts = [NSMutableArray array];
|
||||
|
||||
if (_extractImages)
|
||||
{
|
||||
newText = [text htmlByExtractingImages: bodyParts];
|
||||
if ([bodyParts count])
|
||||
{
|
||||
[self setText: newText];
|
||||
has_inline_images = YES;
|
||||
}
|
||||
newText = [text htmlByExtractingImages: extractedBodyParts];
|
||||
if ([extractedBodyParts count])
|
||||
[self setText: newText];
|
||||
}
|
||||
|
||||
map = [self mimeHeaderMapWithHeaders: _headers
|
||||
|
@ -1583,25 +1605,16 @@ static NSString *userAgent = nil;
|
|||
if (!allBodyParts)
|
||||
return nil;
|
||||
|
||||
[bodyParts addObjectsFromArray: allBodyParts];
|
||||
|
||||
//[self debugWithFormat: @"attachments: %@", bodyParts];
|
||||
|
||||
if ([bodyParts count] == 0)
|
||||
if ([extractedBodyParts count] == 0 && [allBodyParts count] == 0)
|
||||
/* no attachments */
|
||||
message = [self mimeMessageForContentWithHeaderMap: map];
|
||||
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
|
||||
andBodyParts: bodyParts];
|
||||
extractedBodyParts: extractedBodyParts
|
||||
andBodyParts: allBodyParts];
|
||||
|
||||
//[self debugWithFormat: @"message: %@", message];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue