mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-01 09:02:01 +00:00
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:
parent
e0a81bfba5
commit
4ea9d6ba56
3 changed files with 72 additions and 41 deletions
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue