diff options
author | David Percy <david.percy@mongodb.com> | 2022-01-10 19:05:31 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-01-11 03:29:22 +0000 |
commit | 91b7243ea143ee56a0c098b8d5226b68fe682a39 (patch) | |
tree | 836ee252bfec7e3025abc5d0650823bfe4e5bb2e | |
parent | 7a8c1f038c04d679342b19914be66720b470a4c1 (diff) | |
download | mongo-91b7243ea143ee56a0c098b8d5226b68fe682a39.tar.gz |
SERVER-62481 Fix crash in $_internalBucketGeoWithin parser
-rw-r--r-- | jstests/core/timeseries/timeseries_internal_bucket_geo_within.js | 33 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_parser.cpp | 8 |
2 files changed, 39 insertions, 2 deletions
diff --git a/jstests/core/timeseries/timeseries_internal_bucket_geo_within.js b/jstests/core/timeseries/timeseries_internal_bucket_geo_within.js index 2354b62f326..b4b7f083552 100644 --- a/jstests/core/timeseries/timeseries_internal_bucket_geo_within.js +++ b/jstests/core/timeseries/timeseries_internal_bucket_geo_within.js @@ -274,4 +274,35 @@ results = coll.aggregate(pipeline).toArray(); assert.sameMembers(results, [ {_id: 3, a: 4, x: {y: {type: "Point", coordinates: [2, 1]}}, time: now, meta: {sensorId: 100}} ]); -}());
\ No newline at end of file + +// Test some parse errors. +{ + coll.drop(); + + pipeline = [{$match: {$_internalBucketGeoWithin: {}}}]; + let err = assert.throws(() => coll.explain().aggregate(pipeline)); + assert.eq(err.code, ErrorCodes.FailedToParse, err); + + pipeline = [{ + $match: { + $_internalBucketGeoWithin: { + withinRegion: 7, + field: 'loc', + } + } + }]; + err = assert.throws(() => coll.explain().aggregate(pipeline)); + assert.eq(err.code, ErrorCodes.TypeMismatch, err); + + pipeline = [{ + $match: { + $_internalBucketGeoWithin: { + withinRegion: {}, + field: 'loc', + } + } + }]; + err = assert.throws(() => coll.explain().aggregate(pipeline)); + assert.eq(err.code, ErrorCodes.BadValue, err); +} +}()); diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp index e5dd4c3816f..0e86cd4e06b 100644 --- a/src/mongo/db/matcher/expression_parser.cpp +++ b/src/mongo/db/matcher/expression_parser.cpp @@ -1037,7 +1037,7 @@ StatusWithMatchExpression parseInternalBucketGeoWithinMatchExpression( auto subobj = elem.embeddedObject(); - std::shared_ptr<GeometryContainer> geoContainer = std::make_shared<GeometryContainer>(); + std::shared_ptr<GeometryContainer> geoContainer; if (!subobj.hasField("withinRegion") || !subobj.hasField("field")) { return {ErrorCodes::FailedToParse, str::stream() << InternalBucketGeoWithinMatchExpression::kName @@ -1055,10 +1055,16 @@ StatusWithMatchExpression parseInternalBucketGeoWithinMatchExpression( while (geoIt.more()) { BSONElement elt = geoIt.next(); // The element must be a geo specifier. "$box", "$center", "$geometry", etc. + geoContainer = std::make_shared<GeometryContainer>(); Status status = geoContainer->parseFromQuery(elt); if (!status.isOK()) return status; } + if (!geoContainer) { + return Status(ErrorCodes::BadValue, + str::stream() << InternalBucketGeoWithinMatchExpression::kName + << "'s 'withinRegion' can't be an empty object"); + } if (subobj["field"].type() != BSONType::String) { return {ErrorCodes::TypeMismatch, |