summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Percy <david.percy@mongodb.com>2022-01-10 19:05:31 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-01-11 03:29:22 +0000
commit91b7243ea143ee56a0c098b8d5226b68fe682a39 (patch)
tree836ee252bfec7e3025abc5d0650823bfe4e5bb2e
parent7a8c1f038c04d679342b19914be66720b470a4c1 (diff)
downloadmongo-91b7243ea143ee56a0c098b8d5226b68fe682a39.tar.gz
SERVER-62481 Fix crash in $_internalBucketGeoWithin parser
-rw-r--r--jstests/core/timeseries/timeseries_internal_bucket_geo_within.js33
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp8
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,