@@ -172,15 +172,15 @@ Status JParse::parseError(StringData msg) {
172
172
return Status (ErrorCodes::FailedToParse, ossmsg.str ());
173
173
}
174
174
175
- Status JParse::value (StringData fieldName, BSONObjBuilder& builder) {
175
+ Status JParse::value (StringData fieldName, BSONObjBuilder& builder, int depth ) {
176
176
MONGO_JSON_DEBUG (" fieldName: " << fieldName);
177
177
if (peekToken (LBRACE)) {
178
- Status ret = object (fieldName, builder);
178
+ Status ret = object (fieldName, builder, true , depth + 1 );
179
179
if (ret != Status::OK ()) {
180
180
return ret;
181
181
}
182
182
} else if (peekToken (LBRACKET)) {
183
- Status ret = array (fieldName, builder);
183
+ Status ret = array (fieldName, builder, true , depth + 1 );
184
184
if (ret != Status::OK ()) {
185
185
return ret;
186
186
}
@@ -220,7 +220,7 @@ Status JParse::value(StringData fieldName, BSONObjBuilder& builder) {
220
220
return ret;
221
221
}
222
222
} else if (readToken (" Dbref" ) || readToken (" DBRef" )) {
223
- Status ret = dbRef (fieldName, builder);
223
+ Status ret = dbRef (fieldName, builder, depth + 1 );
224
224
if (ret != Status::OK ()) {
225
225
return ret;
226
226
}
@@ -268,11 +268,14 @@ Status JParse::value(StringData fieldName, BSONObjBuilder& builder) {
268
268
}
269
269
270
270
Status JParse::parse (BSONObjBuilder& builder) {
271
- return isArray () ? array (" UNUSED" , builder, false ) : object (" UNUSED" , builder, false );
271
+ return isArray () ? array (" UNUSED" , builder, false , 0 ) : object (" UNUSED" , builder, false , 0 );
272
272
}
273
273
274
- Status JParse::object (StringData fieldName, BSONObjBuilder& builder, bool subObject) {
274
+ Status JParse::object (StringData fieldName, BSONObjBuilder& builder, bool subObject, int depth ) {
275
275
MONGO_JSON_DEBUG (" fieldName: " << fieldName);
276
+ if (depth > kMaxDepth ) {
277
+ return parseError (" Reached nested object limit" );
278
+ }
276
279
if (!readToken (LBRACE)) {
277
280
return parseError (" Expecting '{'" );
278
281
}
@@ -354,7 +357,7 @@ Status JParse::object(StringData fieldName, BSONObjBuilder& builder, bool subObj
354
357
if (!subObject) {
355
358
return parseError (" Reserved field name in base object: $ref" );
356
359
}
357
- Status ret = dbRefObject (fieldName, builder);
360
+ Status ret = dbRefObject (fieldName, builder, depth + 1 );
358
361
if (ret != Status::OK ()) {
359
362
return ret;
360
363
}
@@ -429,7 +432,7 @@ Status JParse::object(StringData fieldName, BSONObjBuilder& builder, bool subObj
429
432
if (!readToken (COLON)) {
430
433
return parseError (" Expecting ':'" );
431
434
}
432
- Status valueRet = value (firstField, *objBuilder);
435
+ Status valueRet = value (firstField, *objBuilder, depth );
433
436
if (valueRet != Status::OK ()) {
434
437
return valueRet;
435
438
}
@@ -443,7 +446,7 @@ Status JParse::object(StringData fieldName, BSONObjBuilder& builder, bool subObj
443
446
if (!readToken (COLON)) {
444
447
return parseError (" Expecting ':'" );
445
448
}
446
- Status nextFieldValueRet = value (nextFieldName, *objBuilder);
449
+ Status nextFieldValueRet = value (nextFieldName, *objBuilder, depth );
447
450
if (nextFieldValueRet != Status::OK ()) {
448
451
return nextFieldValueRet;
449
452
}
@@ -773,7 +776,10 @@ Status JParse::regexObjectCanonical(StringData fieldName, BSONObjBuilder& builde
773
776
return Status::OK ();
774
777
}
775
778
776
- Status JParse::dbRefObject (StringData fieldName, BSONObjBuilder& builder) {
779
+ Status JParse::dbRefObject (StringData fieldName, BSONObjBuilder& builder, int depth) {
780
+ if (depth > kMaxDepth ) {
781
+ return parseError (" Reached nested object limit" );
782
+ }
777
783
BSONObjBuilder subBuilder (builder.subobjStart (fieldName));
778
784
779
785
if (!readToken (COLON)) {
@@ -797,7 +803,7 @@ Status JParse::dbRefObject(StringData fieldName, BSONObjBuilder& builder) {
797
803
if (!readToken (COLON)) {
798
804
return parseError (" DBRef: Expecting ':'" );
799
805
}
800
- Status valueRet = value (" $id" , subBuilder);
806
+ Status valueRet = value (" $id" , subBuilder, depth );
801
807
if (valueRet != Status::OK ()) {
802
808
return valueRet;
803
809
}
@@ -945,8 +951,11 @@ Status JParse::maxKeyObject(StringData fieldName, BSONObjBuilder& builder) {
945
951
return Status::OK ();
946
952
}
947
953
948
- Status JParse::array (StringData fieldName, BSONObjBuilder& builder, bool subObject) {
954
+ Status JParse::array (StringData fieldName, BSONObjBuilder& builder, bool subObject, int depth ) {
949
955
MONGO_JSON_DEBUG (" fieldName: " << fieldName);
956
+ if (depth > kMaxDepth ) {
957
+ return parseError (" Reached nested object limit" );
958
+ }
950
959
if (!readToken (LBRACKET)) {
951
960
return parseError (" Expecting '['" );
952
961
}
@@ -961,7 +970,7 @@ Status JParse::array(StringData fieldName, BSONObjBuilder& builder, bool subObje
961
970
if (!peekToken (RBRACKET)) {
962
971
DecimalCounter<uint32_t > index;
963
972
do {
964
- Status ret = value (StringData{index}, *arrayBuilder);
973
+ Status ret = value (StringData{index}, *arrayBuilder, depth );
965
974
if (!ret.isOK ()) {
966
975
return ret;
967
976
}
@@ -1158,7 +1167,10 @@ Status JParse::numberInt(StringData fieldName, BSONObjBuilder& builder) {
1158
1167
return Status::OK ();
1159
1168
}
1160
1169
1161
- Status JParse::dbRef (StringData fieldName, BSONObjBuilder& builder) {
1170
+ Status JParse::dbRef (StringData fieldName, BSONObjBuilder& builder, int depth) {
1171
+ if (depth > kMaxDepth ) {
1172
+ return parseError (" Reached nested object limit" );
1173
+ }
1162
1174
BSONObjBuilder subBuilder (builder.subobjStart (fieldName));
1163
1175
1164
1176
if (!readToken (LPAREN)) {
@@ -1176,7 +1188,7 @@ Status JParse::dbRef(StringData fieldName, BSONObjBuilder& builder) {
1176
1188
return parseError (" Expecting ','" );
1177
1189
}
1178
1190
1179
- Status valueRet = value (" $id" , subBuilder);
1191
+ Status valueRet = value (" $id" , subBuilder, depth );
1180
1192
if (valueRet != Status::OK ()) {
1181
1193
return valueRet;
1182
1194
}
0 commit comments