Skip to content
Browse files

ASN1 Parser Fixes

- fixed a crash due to using BytesNoCopy on a different address than the malloc, in bit string decoding
- fixed a bug where encountering ASN1NULL would end parsing
- moved date formatter creation for parsing into init
- added an additional autorelease pool in the parse method, so that if there are some other memory problems this is localized to DTASN1Parser
  • Loading branch information...
1 parent a6ea226 commit c5cebdadb3ad4015233e6bf60187d3763dbff519 @odrobnik odrobnik committed Feb 22, 2013
Showing with 65 additions and 68 deletions.
  1. +65 −68 Core/Source/DTASN1Parser.m
View
133 Core/Source/DTASN1Parser.m
@@ -17,8 +17,10 @@ @implementation DTASN1Parser
NSError *_parserError;
BOOL _abortParsing;
+ NSDateFormatter *_UTCFormatter;
+
// lookup bitmask what delegate methods are implemented
- struct
+ struct
{
unsigned int delegateSupportsDocumentStart:1;
unsigned int delegateSupportsDocumentEnd:1;
@@ -47,6 +49,11 @@ - (id)initWithData:(NSData *)data
_data = data;
_dataLength = [data length];
+ // has to end with Z
+ _UTCFormatter = [[NSDateFormatter alloc] init];
+ _UTCFormatter.dateFormat = @"yyMMddHHmmss'Z'";
+ _UTCFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
+
if (!_dataLength)
{
return nil;
@@ -83,7 +90,7 @@ - (NSUInteger)_parseLengthAtLocation:(NSUInteger)location lengthOfLength:(NSUInt
{
retValue = (NSUInteger)buffer;
}
- else if (buffer>0x80)
+ else if (buffer>0x80)
{
// next n bytes describe the length length
NSUInteger lengthLength = buffer-0x80;
@@ -105,7 +112,7 @@ - (NSUInteger)_parseLengthAtLocation:(NSUInteger)location lengthOfLength:(NSUInt
free(lengthBytes);
}
- else
+ else
{
// length 0x80 means "indefinite"
[self _parseErrorEncountered:@"Indefinite Length form encounted, not implemented"];
@@ -121,12 +128,15 @@ - (NSUInteger)_parseLengthAtLocation:(NSUInteger)location lengthOfLength:(NSUInt
- (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange
{
- if (!dataRange.length)
- {
- return NO;
- }
-
- switch (tag)
+ if (!dataRange.length && tag != DTASN1TypeNull)
+ {
+ NSLog(@"Encountered zero length data for tag %ld", tag);
+
+ // only NULL can have zero length
+ return NO;
+ }
+
+ switch (tag)
{
case DTASN1TypeBoolean:
{
@@ -172,15 +182,15 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange
[_delegate parser:self foundNumber:number];
}
- else
+ else
{
// send number as data if supported, too long for 32 bit
sendAsData = YES;
}
-
- free(buffer);
+
+ free(buffer);
}
- else
+ else
{
// send number as data if supported, delegate does not want numbers
sendAsData = YES;
@@ -191,7 +201,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange
char *buffer = malloc(dataRange.length);
[_data getBytes:buffer range:dataRange];
NSData *data = [NSData dataWithBytesNoCopy:buffer length:dataRange.length freeWhenDone:YES];
-
+
[_delegate parser:self foundData:data];
}
@@ -202,21 +212,23 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange
{
if (_delegateFlags.delegateSupportsData)
{
- char *buffer = malloc(dataRange.length);
- [_data getBytes:buffer range:dataRange];
-
- // primitive encoding
- NSUInteger unusedBits = buffer[0];
-
- if (unusedBits>0)
- {
- [self _parseErrorEncountered:@"Encountered bit string with unused bits > 0, not implemented"];
- free(buffer);
- return NO;
- }
+ char *buffer = malloc(dataRange.length);
+ [_data getBytes:buffer range:dataRange];
+
+ // primitive encoding
+ NSUInteger unusedBits = buffer[0];
+
+ if (unusedBits>0)
+ {
+ [self _parseErrorEncountered:@"Encountered bit string with unused bits > 0, not implemented"];
+ free(buffer);
+ return NO;
+ }
- NSData *data = [NSData dataWithBytesNoCopy:buffer+1 length:dataRange.length-1 freeWhenDone:YES];
+ NSData *data = [NSData dataWithBytes:buffer+1 length:dataRange.length-1];
[_delegate parser:self foundData:data];
+
+ free(buffer);
}
break;
@@ -231,7 +243,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange
NSData *data = [NSData dataWithBytesNoCopy:buffer length:dataRange.length freeWhenDone:YES];
[_delegate parser:self foundData:data];
- }
+ }
break;
}
@@ -264,7 +276,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange
NSUInteger value=0;
BOOL more = NO;
- do
+ do
{
unsigned char b = buffer[i];
value = value * 128;
@@ -281,7 +293,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange
{
[self _parseErrorEncountered:@"Invalid object identifier with more bit set on last octed"];
free(buffer);
-
+
return NO;
}
} while (more);
@@ -324,12 +336,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange
NSString *string = [[NSString alloc] initWithBytesNoCopy:buffer length:dataRange.length encoding:NSASCIIStringEncoding freeWhenDone:YES];
- // has to end with Z
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
- formatter.dateFormat = @"yyMMddHHmmss'Z'";
- formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
-
- NSDate *parsedDate = [formatter dateFromString:string];
+ NSDate *parsedDate = [_UTCFormatter dateFromString:string];
if (parsedDate)
{
@@ -363,7 +370,7 @@ - (BOOL)_parseRange:(NSRange)range
NSUInteger location = range.location;
- do
+ do
{
if (_abortParsing)
{
@@ -375,9 +382,8 @@ - (BOOL)_parseRange:(NSRange)range
[_data getBytes:&tagByte range:NSMakeRange(location, 1)];
location++;
-
- BOOL isSeq = tagByte & 32;
- BOOL isContext = tagByte & 128;
+ // BOOL isSeq = tagByte & 32;
+ // BOOL isContext = tagByte & 128;
//NSUInteger tagClass = tagByte >> 6;
DTASN1Type tagType = tagByte & 31;
@@ -404,18 +410,6 @@ - (BOOL)_parseRange:(NSRange)range
// make range
NSRange subRange = NSMakeRange(location, length);
- if (isContext)
- {
- //NSLog(@"[%d]", tagType);
- }
- else
- {
- if (isSeq)
- {
- //NSLog(@"%d", tagType);
- }
- }
-
if (tagConstructed)
{
// constructed element
@@ -435,7 +429,7 @@ - (BOOL)_parseRange:(NSRange)range
[_delegate parser:self didEndContainerWithType:tagType];
}
}
- else
+ else
{
// primitive
if (![self _parseValueWithTag:tagType dataRange:subRange])
@@ -463,19 +457,22 @@ - (BOOL)_parseRange:(NSRange)range
- (BOOL)parse
{
- if (_delegateFlags.delegateSupportsDocumentStart)
+ @autoreleasepool
{
- [_delegate parserDidStartDocument:self];
- }
-
- BOOL result = [self _parseRange:NSMakeRange(0, _dataLength)];
-
- if (result && _delegateFlags.delegateSupportsDocumentEnd)
- {
- [_delegate parserDidEndDocument:self];
+ if (_delegateFlags.delegateSupportsDocumentStart)
+ {
+ [_delegate parserDidStartDocument:self];
+ }
+
+ BOOL result = [self _parseRange:NSMakeRange(0, _dataLength)];
+
+ if (result && _delegateFlags.delegateSupportsDocumentEnd)
+ {
+ [_delegate parserDidEndDocument:self];
+ }
+
+ return result;
}
-
- return result;
}
- (void)abortParsing
@@ -503,7 +500,7 @@ - (void)setDelegate:(__unsafe_unretained id<DTASN1ParserDelegate>)delegate;
{
_delegateFlags.delegateSupportsDocumentEnd = YES;
}
-
+
if ([_delegate respondsToSelector:@selector(parser:didStartContainerWithType:)])
{
_delegateFlags.delegateSupportsContainerStart = YES;
@@ -523,7 +520,7 @@ - (void)setDelegate:(__unsafe_unretained id<DTASN1ParserDelegate>)delegate;
{
_delegateFlags.delegateSupportsString = YES;
}
-
+
if ([_delegate respondsToSelector:@selector(parserFoundNull:)])
{
_delegateFlags.delegateSupportsNull = YES;
@@ -538,12 +535,12 @@ - (void)setDelegate:(__unsafe_unretained id<DTASN1ParserDelegate>)delegate;
{
_delegateFlags.delegateSupportsData = YES;
}
-
+
if ([_delegate respondsToSelector:@selector(parser:foundNumber:)])
{
_delegateFlags.delegateSupportsNumber = YES;
}
-
+
if ([_delegate respondsToSelector:@selector(parser:foundObjectIdentifier:)])
{
_delegateFlags.delegateSupportsObjectIdentifier = YES;

0 comments on commit c5cebda

Please sign in to comment.
Something went wrong with that request. Please try again.