mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-05 06:01:17 +00:00
(e.g. multipart boundary) git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@39302 72102866-910b-0410-8b05-ffd578937521
256 lines
8.9 KiB
Objective-C
256 lines
8.9 KiB
Objective-C
#if defined(GNUSTEP_BASE_LIBRARY)
|
|
#import <Foundation/Foundation.h>
|
|
#import <GNUstepBase/GSMime.h>
|
|
#import "Testing.h"
|
|
|
|
static GSMimeDocument *
|
|
parse(GSMimeParser **parserPointer, NSData *data)
|
|
{
|
|
GSMimeParser *parser;
|
|
unsigned length = [data length];
|
|
unsigned index;
|
|
|
|
if (0 == parserPointer)
|
|
{
|
|
parser = [[GSMimeParser new] autorelease];
|
|
}
|
|
else
|
|
{
|
|
if (nil == *parserPointer)
|
|
{
|
|
*parserPointer = [[GSMimeParser new] autorelease];
|
|
}
|
|
parser = *parserPointer;
|
|
}
|
|
|
|
for (index = 0; index < length-1; index++)
|
|
{
|
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
|
NSData *d;
|
|
|
|
d = [data subdataWithRange: NSMakeRange(index, 1)];
|
|
if ([parser parse: d] == NO)
|
|
{
|
|
return [parser mimeDocument];
|
|
}
|
|
[arp release];
|
|
}
|
|
data = [data subdataWithRange: NSMakeRange(index, 1)];
|
|
if ([parser parse: data] == YES && NO == [parser isComplete])
|
|
{
|
|
[parser parse: nil];
|
|
}
|
|
return [parser mimeDocument];
|
|
}
|
|
|
|
static GSMimeDocument *
|
|
exact(GSMimeParser **parserPointer, NSData *data)
|
|
{
|
|
GSMimeParser *parser = nil;
|
|
GSMimeDocument *doc;
|
|
|
|
if (0 == parserPointer)
|
|
{
|
|
parserPointer = &parser;
|
|
}
|
|
doc = parse(parserPointer, data);
|
|
if (nil != [parser excess])
|
|
{
|
|
NSLog(@"Excess data in parser after parse completed");
|
|
doc = nil;
|
|
}
|
|
return doc;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
|
NSData *cr;
|
|
NSData *data;
|
|
NSData *orig;
|
|
NSString *str;
|
|
GSMimeParser *parser;
|
|
GSMimeDocument *doc;
|
|
GSMimeDocument *idoc;
|
|
BOOL oldStyleFolding;
|
|
|
|
oldStyleFolding = [[NSUserDefaults standardUserDefaults]
|
|
boolForKey: @"GSMimeOldStyleFolding"];
|
|
|
|
cr = [NSData dataWithBytes: "\r" length: 1];
|
|
|
|
data = [NSData dataWithBytes: "DQ==" length: 4];
|
|
PASS_EQUAL([GSMimeDocument decodeBase64: data], cr,
|
|
"decodeBase64 works for padded data");
|
|
|
|
data = [NSData dataWithBytes: "DQ" length: 2];
|
|
PASS_EQUAL([GSMimeDocument decodeBase64: data], cr,
|
|
"decodeBase64 works for unpadded data");
|
|
|
|
data = [NSData dataWithContentsOfFile: @"mime1.dat"];
|
|
idoc = exact(0, data);
|
|
PASS_EQUAL([[[idoc content] objectAtIndex:0] content], @"a",
|
|
"can parse one char base64 mime1.dat incrementally");
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS_EQUAL([[[doc content] objectAtIndex:0] content], @"a",
|
|
"can parse one char base64 mime1.dat in one go");
|
|
PASS_EQUAL(idoc, doc, "mime1.dat documents are the same");
|
|
|
|
parser = [GSMimeParser new];
|
|
data = [[data mutableCopy] autorelease];
|
|
[(NSMutableData*)data appendBytes: "\r\n\r\n" length: 4];
|
|
[parser parse: data];
|
|
doc = [parser mimeDocument];
|
|
PASS([[parser excess] length] == 5, "Can detect excess data in multipart");
|
|
[parser release];
|
|
|
|
data = [NSData dataWithContentsOfFile: @"mime2.dat"];
|
|
idoc = exact(0, data);
|
|
PASS_EQUAL([idoc content], @"aa",
|
|
"can parse two char base64 mime2.dat incrementally");
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS_EQUAL([doc content], @"aa",
|
|
"can parse two char base64 mime2.dat in one go");
|
|
PASS_EQUAL(idoc, doc, "mime2.dat documents are the same");
|
|
|
|
data = [NSData dataWithContentsOfFile: @"mime3.dat"];
|
|
idoc = exact(0, data);
|
|
PASS(([[idoc content] isEqual: @"aaa"]),
|
|
"can parse three char base64 mime3.dat incrementally");
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS(([[doc content] isEqual: @"aaa"]),
|
|
"can parse three char base64 mime3.dat in one go");
|
|
PASS([idoc isEqual: doc], "mime3.dat documents are the same");
|
|
|
|
data = [NSData dataWithContentsOfFile: @"mime4.dat"];
|
|
idoc = exact(0, data);
|
|
PASS(([[[[idoc content] objectAtIndex:0] content] isEqual: @"hello\n"]
|
|
&& [[[[idoc content] objectAtIndex:1] content] isEqual: @"there\n"]),
|
|
"can parse multi-part text mime4.dat incrementally");
|
|
PASS(([[[[idoc content] objectAtIndex:0] contentFile] isEqual: @"a.a"]),
|
|
"can extract content file name from mime4.dat (incrementally parsed)");
|
|
PASS(([[[[idoc content] objectAtIndex:0] contentType] isEqual: @"text"]),
|
|
"can extract content type from mime4.dat (incrementally parsed)");
|
|
PASS(([[[[idoc content] objectAtIndex:0] contentSubtype] isEqual: @"plain"]),
|
|
"can extract content sub type from mime4.dat (incrementally parsed)");
|
|
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS(([[[[doc content] objectAtIndex:0] content] isEqual: @"hello\n"]
|
|
&& [[[[doc content] objectAtIndex:1] content] isEqual: @"there\n"]),
|
|
"can parse multi-part text mime4.dat in one go");
|
|
PASS(([[[[doc content] objectAtIndex:0] contentFile] isEqual: @"a.a"]),
|
|
"can extract content file name from mime4.dat (parsed in one go)");
|
|
PASS(([[[[doc content] objectAtIndex:0] contentType] isEqual: @"text"]),
|
|
"can extract content type from mime4.dat (parsed in one go)");
|
|
PASS(([[[[doc content] objectAtIndex:0] contentSubtype] isEqual: @"plain"]),
|
|
"can extract content sub type from mime4.dat (parsed in one go)");
|
|
PASS([idoc isEqual: doc], "mime4.dat documents are the same");
|
|
|
|
data = [NSData dataWithContentsOfFile: @"mime5.dat"];
|
|
idoc = exact(0, data);
|
|
PASS(([[idoc contentSubtype] isEqual: @"xml"]),
|
|
"can parse http document mime5.dat incrementally");
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS(([[doc contentSubtype] isEqual: @"xml"]),
|
|
"can parse http document mime5.dat in one go");
|
|
PASS([idoc isEqual: doc], "mime5.dat documents are the same");
|
|
|
|
data = [NSData dataWithContentsOfFile: @"mime6.dat"];
|
|
idoc = exact(0, data);
|
|
PASS(([[idoc content] count] == 3),
|
|
"can parse multipart mixed mime6.dat incrementally");
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS(([[doc content] count] == 3),
|
|
"can parse multipart mixed mime6.dat in one go");
|
|
PASS([idoc isEqual: doc], "mime6.dat documents are the same");
|
|
|
|
data = [NSData dataWithContentsOfFile: @"mime7.dat"];
|
|
PASS(([[[[doc content] objectAtIndex:1] content] isEqual: data]),
|
|
"mime6.dat binary data part matches mime7.dat");
|
|
|
|
data = [NSData dataWithContentsOfFile: @"mime9.dat"];
|
|
idoc = exact(0, data);
|
|
|
|
if (YES == oldStyleFolding)
|
|
{
|
|
str = @"first second third";
|
|
}
|
|
else
|
|
{
|
|
str = @"first\tsecond\tthird";
|
|
}
|
|
PASS(([[[idoc headerNamed: @"Long"] value] isEqual: str]),
|
|
"mime9.dat folded header unfolds correctly incrementally");
|
|
doc = [GSMimeParser documentFromData: data];
|
|
//NSLog(@"'%@'", [[doc headerNamed: @"Long"] value]);
|
|
PASS(([[[doc headerNamed: @"Long"] value] isEqual: str]),
|
|
"mime9.dat folded header unfolds correctly in one go");
|
|
PASS([idoc isEqual: doc], "mime9.dat documents are the same");
|
|
|
|
/* Test a document containing nested multipart documents
|
|
*/
|
|
data = [NSData dataWithContentsOfFile: @"mime10.dat"];
|
|
idoc = exact(0, data);
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS_EQUAL(idoc, doc, "mime10.dat documents are the same");
|
|
data = [idoc rawMimeData];
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS_EQUAL(idoc, doc, "rawMimeData reproduces document");
|
|
|
|
/* Test parse of a document containing encoded words in header.
|
|
* Use JavaMail encoded words (different format from those GSMime
|
|
* produces).
|
|
*/
|
|
data = [NSData dataWithContentsOfFile: @"mime11.dat"];
|
|
idoc = exact(0, data);
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS_EQUAL(idoc, doc, "mime11.dat documents are the same");
|
|
|
|
NSData *oData = [doc rawMimeData: YES foldedAt: 78];
|
|
GSMimeDocument *oDoc = [GSMimeParser documentFromData: oData];
|
|
PASS_EQUAL(doc, oDoc, "mime11.dat (folded and quoted boundary header) equal after writing and re-parsing");
|
|
|
|
/* Test a document with adjacent encoded words in headers, as
|
|
* produced by GSMime
|
|
*/
|
|
orig = [NSData dataWithContentsOfFile: @"mime12.dat"];
|
|
idoc = exact(0, orig);
|
|
if (YES == oldStyleFolding)
|
|
{
|
|
str = @"Avant de partir, n'oubliez pas de préparer votre séjour à Paris";
|
|
}
|
|
else
|
|
{
|
|
str = @"Avant de partir, n'oubliez pas de préparer votre\tséjour à Paris";
|
|
}
|
|
doc = [GSMimeDocument documentWithContent: @"hello"
|
|
type: @"text/plain"
|
|
name: nil];
|
|
[doc setHeader: @"MIME-Version" value: @"1.0" parameters: nil];
|
|
[doc setHeader: @"Subject" value: str parameters: nil];
|
|
PASS_EQUAL(idoc, doc, "mime12.dat same as internally generated content");
|
|
doc = [GSMimeParser documentFromData: orig];
|
|
PASS_EQUAL(idoc, doc, "mime12.dat documents are the same");
|
|
data = [idoc rawMimeData];
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS_EQUAL(idoc, doc, "rawMimeData reproduces document with 'q' header");
|
|
NSLog(@"Made\n%@\nOrig\n%@", data, orig);
|
|
|
|
if (NO == oldStyleFolding)
|
|
{
|
|
[idoc setHeader: @"Subject" value: @"==répà==" parameters: nil];
|
|
data = [idoc rawMimeData];
|
|
NSLog(@"Made\n%@", data);
|
|
doc = [GSMimeParser documentFromData: data];
|
|
PASS_EQUAL(doc, idoc, "rawMimeData reproduces document with 'b' header");
|
|
}
|
|
|
|
[arp release]; arp = nil;
|
|
return 0;
|
|
}
|
|
#else
|
|
int main(int argc,char **argv)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|