diff options
Diffstat (limited to 'src/mongo/db/matcher/expression_parser.cpp')
-rw-r--r-- | src/mongo/db/matcher/expression_parser.cpp | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp index 823543ac29d..bfc363ceda1 100644 --- a/src/mongo/db/matcher/expression_parser.cpp +++ b/src/mongo/db/matcher/expression_parser.cpp @@ -245,10 +245,17 @@ namespace mongo { mongoutils::str::stream() << "not handled: " << e.fieldName() ); } - StatusWithMatchExpression MatchExpressionParser::_parse( const BSONObj& obj, bool topLevel ) { + StatusWithMatchExpression MatchExpressionParser::_parse( const BSONObj& obj, int level ) { + if (level > kMaximumTreeDepth) { + return StatusWithMatchExpression( ErrorCodes::BadValue, + "exceeded maximum query tree depth" ); + } std::auto_ptr<AndMatchExpression> root( new AndMatchExpression() ); + bool topLevel = (level == 0); + level++; + BSONObjIterator i( obj ); while ( i.more() ){ @@ -262,7 +269,7 @@ namespace mongo { return StatusWithMatchExpression( ErrorCodes::BadValue, "$or needs an array" ); std::auto_ptr<OrMatchExpression> temp( new OrMatchExpression() ); - Status s = _parseTreeList( e.Obj(), temp.get() ); + Status s = _parseTreeList( e.Obj(), temp.get(), level ); if ( !s.isOK() ) return StatusWithMatchExpression( s ); root->add( temp.release() ); @@ -272,7 +279,7 @@ namespace mongo { return StatusWithMatchExpression( ErrorCodes::BadValue, "and needs an array" ); std::auto_ptr<AndMatchExpression> temp( new AndMatchExpression() ); - Status s = _parseTreeList( e.Obj(), temp.get() ); + Status s = _parseTreeList( e.Obj(), temp.get(), level ); if ( !s.isOK() ) return StatusWithMatchExpression( s ); root->add( temp.release() ); @@ -282,7 +289,7 @@ namespace mongo { return StatusWithMatchExpression( ErrorCodes::BadValue, "and needs an array" ); std::auto_ptr<NorMatchExpression> temp( new NorMatchExpression() ); - Status s = _parseTreeList( e.Obj(), temp.get() ); + Status s = _parseTreeList( e.Obj(), temp.get(), level ); if ( !s.isOK() ) return StatusWithMatchExpression( s ); root->add( temp.release() ); |