Try to cope with microsoft IE bugs in quoted strings.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@15124 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2002-11-26 14:26:00 +00:00
parent e0a81bfba5
commit 4ea9d6ba56
3 changed files with 72 additions and 41 deletions

View file

@ -6,6 +6,8 @@
* Source/Additions/GSMime.m: Provide a method to generate and return * Source/Additions/GSMime.m: Provide a method to generate and return
a string suitable for use as a boundary. Make tolerant of multipart a string suitable for use as a boundary. Make tolerant of multipart
messages with 'application' as the message type. messages with 'application' as the message type.
Added ([-setBuggyQuotes:]) method for parsing stuff produced by
microsoft ;-(
2002-11-25 Richard Frith-Macdonald <rfm@gnu.org> 2002-11-25 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -147,10 +147,13 @@
unsigned input; unsigned input;
unsigned expect; unsigned expect;
unsigned rawBodyLength; unsigned rawBodyLength;
BOOL inBody; struct {
BOOL isHttp; unsigned int inBody:1;
BOOL complete; unsigned int isHttp:1;
BOOL hadErrors; unsigned int complete:1;
unsigned int hadErrors:1;
unsigned int buggyQuotes:1;
} flags;
NSData *boundary; NSData *boundary;
GSMimeDocument *document; GSMimeDocument *document;
GSMimeParser *child; GSMimeParser *child;
@ -179,6 +182,7 @@
- (BOOL) scanPastSpace: (NSScanner*)scanner; - (BOOL) scanPastSpace: (NSScanner*)scanner;
- (NSString*) scanSpecial: (NSScanner*)scanner; - (NSString*) scanSpecial: (NSScanner*)scanner;
- (NSString*) scanToken: (NSScanner*)scanner; - (NSString*) scanToken: (NSScanner*)scanner;
- (void) setBuggyQuotes: (BOOL)flag;
- (void) setIsHttp; - (void) setIsHttp;
@end @end

View file

@ -951,18 +951,18 @@ wordData(NSString *word)
data = ctxt->data; data = ctxt->data;
bytes = (unsigned char*)[data mutableBytes]; bytes = (unsigned char*)[data mutableBytes];
dataEnd = [data length]; dataEnd = [data length];
inBody = NO; flags.inBody = 0;
/* /*
* Duplicate the normal header parsing process for our footers. * Duplicate the normal header parsing process for our footers.
*/ */
while (inBody == NO) while (flags.inBody == 0)
{ {
if ([self _unfoldHeader] == NO) if ([self _unfoldHeader] == NO)
{ {
break; break;
} }
if (inBody == NO) if (flags.inBody == 0)
{ {
NSString *header; NSString *header;
@ -973,7 +973,7 @@ wordData(NSString *word)
} }
if ([self parseHeader: header] == NO) if ([self parseHeader: header] == NO)
{ {
hadErrors = YES; flags.hadErrors = 1;
break; break;
} }
} }
@ -986,7 +986,7 @@ wordData(NSString *word)
data = old; data = old;
bytes = (unsigned char*)[data mutableBytes]; bytes = (unsigned char*)[data mutableBytes];
dataEnd = [data length]; dataEnd = [data length];
inBody = YES; flags.inBody = 1;
} }
} }
/* /*
@ -1042,9 +1042,9 @@ wordData(NSString *word)
*/ */
- (void) expectNoHeaders - (void) expectNoHeaders
{ {
if (complete == NO) if (flags.complete == 0)
{ {
inBody = YES; flags.inBody = 1;
} }
} }
@ -1055,11 +1055,11 @@ wordData(NSString *word)
*/ */
- (BOOL) isComplete - (BOOL) isComplete
{ {
if (hadErrors == YES) if (flags.hadErrors == 1)
{ {
return NO; return NO;
} }
return complete; return (flags.complete == 1) ? YES : NO;
} }
/** /**
@ -1068,7 +1068,7 @@ wordData(NSString *word)
*/ */
- (BOOL) isHttp - (BOOL) isHttp
{ {
return isHttp; return (flags.isHttp == 1) ? YES : NO;
} }
/** /**
@ -1077,7 +1077,7 @@ wordData(NSString *word)
*/ */
- (BOOL) isInBody - (BOOL) isInBody
{ {
return inBody; return (flags.inBody == 1) ? YES : NO;
} }
/** /**
@ -1086,9 +1086,9 @@ wordData(NSString *word)
*/ */
- (BOOL) isInHeaders - (BOOL) isInHeaders
{ {
if (inBody == YES) if (flags.inBody == 1)
return NO; return NO;
if (complete == YES) if (flags.complete == 1)
return NO; return NO;
return YES; return YES;
} }
@ -1149,26 +1149,26 @@ wordData(NSString *word)
{ {
unsigned l = [d length]; unsigned l = [d length];
if (complete == YES) if (flags.complete == 1)
{ {
return NO; /* Already completely parsed! */ return NO; /* Already completely parsed! */
} }
if (l > 0) if (l > 0)
{ {
NSDebugMLLog(@"GSMime", @"Parse %u bytes - '%*.*s'", l, l, l, [d bytes]); NSDebugMLLog(@"GSMime", @"Parse %u bytes - '%*.*s'", l, l, l, [d bytes]);
if (inBody == NO) if (flags.inBody == 0)
{ {
[data appendBytes: [d bytes] length: [d length]]; [data appendBytes: [d bytes] length: [d length]];
bytes = (unsigned char*)[data mutableBytes]; bytes = (unsigned char*)[data mutableBytes];
dataEnd = [data length]; dataEnd = [data length];
while (inBody == NO) while (flags.inBody == 0)
{ {
if ([self _unfoldHeader] == NO) if ([self _unfoldHeader] == NO)
{ {
return YES; /* Needs more data to fill line. */ return YES; /* Needs more data to fill line. */
} }
if (inBody == NO) if (flags.inBody == 0)
{ {
NSString *header; NSString *header;
@ -1179,7 +1179,7 @@ wordData(NSString *word)
} }
if ([self parseHeader: header] == NO) if ([self parseHeader: header] == NO)
{ {
hadErrors = YES; flags.hadErrors = 1;
return NO; /* Header not parsed properly. */ return NO; /* Header not parsed properly. */
} }
} }
@ -1201,7 +1201,7 @@ wordData(NSString *word)
* continuation header(s), in which case, we must start parsing * continuation header(s), in which case, we must start parsing
* headers again. * headers again.
*/ */
if (inBody == YES) if (flags.inBody == 1)
{ {
NSDictionary *info; NSDictionary *info;
@ -1222,7 +1222,7 @@ wordData(NSString *word)
* to restart the parsing operation! * to restart the parsing operation!
*/ */
NSDebugMLLog(@"GSMime", @"Parsed http continuation"); NSDebugMLLog(@"GSMime", @"Parsed http continuation");
inBody = NO; flags.inBody = 0;
} }
} }
} }
@ -1231,7 +1231,7 @@ wordData(NSString *word)
if ([d length] > 0) if ([d length] > 0)
{ {
if (inBody == YES) if (flags.inBody == 1)
{ {
/* /*
* We can't just re-call -parse: ... * We can't just re-call -parse: ...
@ -1251,7 +1251,7 @@ wordData(NSString *word)
{ {
BOOL result; BOOL result;
if (inBody == YES) if (flags.inBody == 1)
{ {
result = [self _decodeBody: d]; result = [self _decodeBody: d];
} }
@ -1263,8 +1263,8 @@ wordData(NSString *word)
*/ */
result = [self parse: [NSData dataWithBytes: @"\r\n\r\n" length: 4]]; result = [self parse: [NSData dataWithBytes: @"\r\n\r\n" length: 4]];
} }
inBody = NO; flags.inBody = 0;
complete = YES; /* Finished parsing */ flags.complete = 1; /* Finished parsing */
return result; return result;
} }
} }
@ -1739,7 +1739,7 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
[self scanPastSpace: scanner]; [self scanPastSpace: scanner];
if (isHttp == YES) if (flags.isHttp == 1)
{ {
specials = rfc822Specials; specials = rfc822Specials;
} }
@ -1843,6 +1843,10 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
{ {
src++; src++;
} }
if (flags.buggyQuotes == 1 && *src != '\\' && *src != '"')
{
*dst++ = '\\'; // Buggy use of escape in quotes.
}
*dst++ = *src++; *dst++ = *src++;
} }
return [NSString stringWithCharacters: buf length: dst - buf]; return [NSString stringWithCharacters: buf length: dst - buf];
@ -1853,7 +1857,7 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
NSCharacterSet *specials; NSCharacterSet *specials;
NSString *value; NSString *value;
if (isHttp == YES) if (flags.isHttp == 1)
{ {
specials = rfc822Specials; specials = rfc822Specials;
} }
@ -1879,6 +1883,26 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
} }
} }
/**
* Method to inform the parser that the data it is parsing is likely to
* contain fields with buggy use of backslash quotes ... and it should
* try to be tolerant of them and treat them as is they were escaped
* backslashes. This is for use with things like microsoft internet
* explorer, which puts the backslashes used as file path separators
* in parameters without quoting them.
*/
- (void) setBuggyQuotes: (BOOL)flag
{
if (flag == YES)
{
flags.buggyQuotes = 1;
}
else
{
flags.buggyQuotes = 0;
}
}
/** /**
* Method to inform the parser that the data it is parsing is an HTTP * Method to inform the parser that the data it is parsing is an HTTP
* document rather than true MIME. This method is called internally * document rather than true MIME. This method is called internally
@ -1887,7 +1911,7 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
*/ */
- (void) setIsHttp - (void) setIsHttp
{ {
isHttp = YES; flags.isHttp = 1;
} }
@end @end
@ -2090,8 +2114,8 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
if ([context atEnd] == YES) if ([context atEnd] == YES)
{ {
inBody = NO; flags.inBody = 0;
complete = YES; flags.complete = 1;
if ([d length] > 0) if ([d length] > 0)
{ {
NSLog(@"Additional data (%*.*s) ignored after parse complete", NSLog(@"Additional data (%*.*s) ignored after parse complete",
@ -2109,8 +2133,8 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
if ([type isEqualToString: @"multipart"] == YES) if ([type isEqualToString: @"multipart"] == YES)
{ {
NSLog(@"multipart decode attempt without boundary"); NSLog(@"multipart decode attempt without boundary");
inBody = NO; flags.inBody = 0;
complete = YES; flags.complete = 1;
result = NO; result = NO;
} }
else else
@ -2123,8 +2147,8 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
if ([context atEnd] == YES if ([context atEnd] == YES
|| (expect > 0 && rawBodyLength >= expect)) || (expect > 0 && rawBodyLength >= expect))
{ {
inBody = NO; flags.inBody = 0;
complete = YES; flags.complete = 1;
NSDebugMLLog(@"GSMime", @"Parse body complete"); NSDebugMLLog(@"GSMime", @"Parse body complete");
/* /*
@ -2321,8 +2345,8 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
*/ */
if (endedFinalPart == YES || (expect > 0 && rawBodyLength >= expect)) if (endedFinalPart == YES || (expect > 0 && rawBodyLength >= expect))
{ {
complete = YES; flags.complete = 1;
inBody = NO; flags.inBody = 0;
result = NO; result = NO;
} }
else else
@ -2429,12 +2453,13 @@ NSDebugMLLog(@"GSMime", @"Header parsed - %@", info);
lineStart = 0; lineStart = 0;
lineEnd = 0; lineEnd = 0;
input = 0; input = 0;
inBody = YES; flags.inBody = 1;
} }
} }
} }
NSDebugMLLog(@"GSMimeH", @"exit: inBody:%d unwrappingComplete: %d " NSDebugMLLog(@"GSMimeH", @"exit: inBody:%d unwrappingComplete: %d "
@"input:%u dataEnd:%u lineStart:%u '%*.*s'", inBody, unwrappingComplete, @"input:%u dataEnd:%u lineStart:%u '%*.*s'", flags.inBody,
unwrappingComplete,
input, dataEnd, lineStart, lineEnd - lineStart, lineEnd - lineStart, input, dataEnd, lineStart, lineEnd - lineStart, lineEnd - lineStart,
&bytes[lineStart]); &bytes[lineStart]);
return unwrappingComplete; return unwrappingComplete;