From ab9802213c7afc0f88d497dee44c83ec6466435c Mon Sep 17 00:00:00 2001 From: Rui Liu Date: Tue, 30 Nov 2021 10:37:15 +0000 Subject: SERVER-61566 Fix and extract coercion to 32-bit int logic in expression parsing --- src/mongo/bson/bsonelement.cpp | 18 +++++++++++++++++- src/mongo/bson/bsonelement.h | 13 ++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'src/mongo/bson') diff --git a/src/mongo/bson/bsonelement.cpp b/src/mongo/bson/bsonelement.cpp index d93f928861c..e02dfd07f33 100644 --- a/src/mongo/bson/bsonelement.cpp +++ b/src/mongo/bson/bsonelement.cpp @@ -515,7 +515,8 @@ StatusWith BSONElement::parseIntegerElementToNonNegativeLong() const if (number.getValue() < 0) { return Status(ErrorCodes::FailedToParse, - str::stream() << "Expected a positive number in: " << toString(true, true)); + str::stream() + << "Expected a non-negative number in: " << toString(true, true)); } return number; @@ -585,6 +586,21 @@ StatusWith BSONElement::parseIntegerElementToInt() const { return static_cast(valueLong); } +StatusWith BSONElement::parseIntegerElementToNonNegativeInt() const { + auto number = parseIntegerElementToInt(); + if (!number.isOK()) { + return number; + } + + if (number.getValue() < 0) { + return Status(ErrorCodes::FailedToParse, + str::stream() + << "Expected a non-negative number in: " << toString(true, true)); + } + + return number; +} + BSONObj BSONElement::embeddedObjectUserCheck() const { if (MONGO_likely(isABSONObj())) return BSONObj(value(), BSONObj::LargeSizeTrait{}); diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h index 11a8ad6994a..c99623c7e80 100644 --- a/src/mongo/bson/bsonelement.h +++ b/src/mongo/bson/bsonelement.h @@ -412,7 +412,7 @@ public: long long exactNumberLong() const; /** - * Parses a BSONElement of any numeric type into a positive long long, failing if the value + * Parses a BSONElement of any numeric type into a non-negative long long, failing if the value * is any of the following: * * - NaN. @@ -432,6 +432,17 @@ public: */ StatusWith parseIntegerElementToLong() const; + /** + * Parses a BSONElement of any numeric type into a non-negative int, failing if the value + * is any of the following: + * + * - NaN + * - Negative + * - a non-integral number + * - too large in the positive or negative direction to fit in an int + */ + StatusWith parseIntegerElementToNonNegativeInt() const; + /** * Parses a BSONElement of any numeric type into an integer, failing if the value is: * -- cgit v1.2.1