Skip to content

Commit

Permalink
Move max-depth error handling from stream parser to chunk-parser
Browse files Browse the repository at this point in the history
  • Loading branch information
stig committed Nov 14, 2013
1 parent 4ef698e commit e8a1444
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 42 deletions.
27 changes: 16 additions & 11 deletions src/main/objc/SBJsonChunkParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ @implementation SBJsonChunkParser {
SBJsonChunkType currentType;
BOOL supportManyDocuments;
BOOL supportPartialDocuments;
NSUInteger _maxDepth;
}

#pragma mark Housekeeping
Expand Down Expand Up @@ -90,7 +91,6 @@ - (id)initWithBlock:(SBEnumeratorBlock)block
if (self) {
_parser = [[SBJsonStreamParser alloc] init];
_parser.delegate = self;
_parser.maxDepth = maxDepth;

supportManyDocuments = manyDocs;
supportPartialDocuments = arrayItems;
Expand All @@ -103,6 +103,7 @@ - (id)initWithBlock:(SBEnumeratorBlock)block
processBlock = initialProcessBlock;
errorHandler = eh ? eh : ^(NSError*err) { NSLog(@"%@", err); };
currentType = SBJsonChunkNone;
_maxDepth = maxDepth;
}
return self;
}
Expand Down Expand Up @@ -171,7 +172,11 @@ - (void)parser:(SBJsonStreamParser *)parser found:(id)obj isValue:(BOOL)isValue

- (void)parserFoundObjectStart:(SBJsonStreamParser *)parser {
++depth;
if(path) [self addToPath];
if (depth > _maxDepth)
[self maxDepthError];

if (path)
[self addToPath];
dict = [NSMutableDictionary new];
[stack addObject:dict];
currentType = SBJsonChunkObject;
Expand All @@ -190,6 +195,9 @@ - (void)parserFoundObjectEnd:(SBJsonStreamParser *)parser {

- (void)parserFoundArrayStart:(SBJsonStreamParser *)parser {
depth++;
if (depth > _maxDepth)
[self maxDepthError];

if (depth > 1 || !supportPartialDocuments) {
if(path)
[self addToPath];
Expand All @@ -208,6 +216,12 @@ - (void)parserFoundArrayEnd:(SBJsonStreamParser *)parser {
}
}

- (void)maxDepthError {
id ui = @{ NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Input depth exceeds max depth of %lu", (unsigned long)_maxDepth]};
errorHandler([NSError errorWithDomain:@"org.sbjson.parser" code:3 userInfo:ui]);
[_parser stop];
}

- (void)parser:(SBJsonStreamParser *)parser foundBoolean:(BOOL)x {
[self parser:parser found:[NSNumber numberWithBool:x] isValue:YES];
}
Expand Down Expand Up @@ -256,13 +270,4 @@ - (SBJsonParserStatus)parse:(NSData *)data {
return [_parser parse:data];
}

- (void)setMaxDepth:(NSUInteger)maxDepth {
_parser.maxDepth = maxDepth;
}

- (NSUInteger)maxDepth {
return _parser.maxDepth;
}


@end
4 changes: 1 addition & 3 deletions src/main/objc/SBJsonParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,11 @@ - (id)objectWithData:(NSData *)data processValuesWithBlock:(SBProcessBlock)proce
case SBJsonParserComplete:
return value;

case SBJsonParserStopped:
@throw @"Impossible condition";

case SBJsonParserWaitingForData:
self.error = @"Unexpected end of input";
break;

case SBJsonParserStopped: // max-depth error
case SBJsonParserError:
break;
}
Expand Down
10 changes: 0 additions & 10 deletions src/main/objc/SBJsonStreamParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,6 @@ typedef enum {
*/
@property (nonatomic, weak) id<SBJsonStreamParserDelegate> delegate;

/**
The max parse depth
If the input is nested deeper than this the parser will halt parsing and return an error.
Defaults to 32.
*/
@property(nonatomic) NSUInteger maxDepth;

/**
Parse some JSON
Expand All @@ -133,7 +124,6 @@ typedef enum {
*/
- (SBJsonParserStatus)parse:(NSData*)data;


/*
Call this to cause parsing to stop.
*/
Expand Down
19 changes: 1 addition & 18 deletions src/main/objc/SBJsonStreamParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ @implementation SBJsonStreamParser {
- (id)init {
self = [super init];
if (self) {
_maxDepth = 32u;
_stateStack = [[NSMutableArray alloc] initWithCapacity:_maxDepth];
_stateStack = [[NSMutableArray alloc] initWithCapacity:32];
_state = [SBJsonStreamParserStateStart sharedInstance];
tokeniser = [[SBJsonStreamTokeniser alloc] init];
}
Expand Down Expand Up @@ -113,18 +112,7 @@ - (NSString*)tokenName:(sbjson_token_t)token {
return @"<aaiiie!>";
}

- (void)_maxDepthError {
_state = [SBJsonStreamParserStateError sharedInstance];
id ui = @{ NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Input depth exceeds max depth of %lu", (unsigned long)_maxDepth]};
[_delegate parser:self foundError:[NSError errorWithDomain:@"org.sbjson.parser" code:3 userInfo:ui]];
}

- (void)handleObjectStart {
if (_stateStack.count >= _maxDepth) {
[self _maxDepthError];
return;
}

[_delegate parserFoundObjectStart:self];
[_stateStack addObject:_state];
_state = [SBJsonStreamParserStateObjectStart sharedInstance];
Expand All @@ -138,11 +126,6 @@ - (void)handleObjectEnd: (sbjson_token_t) tok {
}

- (void)handleArrayStart {
if (_stateStack.count >= _maxDepth) {
[self _maxDepthError];
return;
}

[_delegate parserFoundArrayStart:self];
[_stateStack addObject:_state];
_state = [SBJsonStreamParserStateArrayStart sharedInstance];
Expand Down

0 comments on commit e8a1444

Please sign in to comment.