summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_value_test.cpp
diff options
context:
space:
mode:
authorTed Tuckman <ted.tuckman@mongodb.com>2019-05-03 14:08:17 -0400
committerTed Tuckman <ted.tuckman@mongodb.com>2019-06-05 15:55:29 -0400
commitbcad0d20e517e10f0dab71a0cfabe0a9e25c401b (patch)
treeddc95863325069e508241f24fe8ce3e499dd60a9 /src/mongo/db/pipeline/document_value_test.cpp
parentd5d674930f1c67f6c87d73715f82f608668d72fa (diff)
downloadmongo-bcad0d20e517e10f0dab71a0cfabe0a9e25c401b.tar.gz
SERVER-40869 Error when coercing out of bounds double to long
Diffstat (limited to 'src/mongo/db/pipeline/document_value_test.cpp')
-rw-r--r--src/mongo/db/pipeline/document_value_test.cpp106
1 files changed, 104 insertions, 2 deletions
diff --git a/src/mongo/db/pipeline/document_value_test.cpp b/src/mongo/db/pipeline/document_value_test.cpp
index e758dadf2a3..bb7a6031eff 100644
--- a/src/mongo/db/pipeline/document_value_test.cpp
+++ b/src/mongo/db/pipeline/document_value_test.cpp
@@ -27,6 +27,8 @@
* it in the license file.
*/
+#include <math.h>
+
#include "mongo/platform/basic.h"
#include "mongo/bson/bson_depth.h"
@@ -1168,8 +1170,8 @@ class LongToInt : public ToIntBase {
Value value() {
return Value(0xff00000007LL);
}
- int expected() {
- return 7;
+ bool asserts() {
+ return true;
}
};
@@ -1211,6 +1213,46 @@ public:
}
};
+/** Coerce maxInt to int */
+class MaxIntToInt : public ToIntBase {
+ Value value() {
+ return Value((double)std::numeric_limits<int>::max());
+ }
+ int expected() {
+ return std::numeric_limits<int>::max();
+ }
+};
+
+/** Coerce minInt to int */
+class MinIntToInt : public ToIntBase {
+ Value value() {
+ return Value((double)std::numeric_limits<int>::min());
+ }
+ int expected() {
+ return std::numeric_limits<int>::min();
+ }
+};
+
+/** Coerce maxInt + 1 to int */
+class TooLargeToInt : public ToIntBase {
+ Value value() {
+ return Value((double)std::numeric_limits<int>::max() + 1);
+ }
+ bool asserts() {
+ return true;
+ }
+};
+
+/** Coerce minInt - 1 to int */
+class TooLargeNegativeToInt : public ToIntBase {
+ Value value() {
+ return Value((double)std::numeric_limits<int>::min() - 1);
+ }
+ bool asserts() {
+ return true;
+ }
+};
+
class ToLongBase {
public:
virtual ~ToLongBase() {}
@@ -1261,6 +1303,57 @@ class DoubleToLong : public ToLongBase {
}
};
+/** Coerce infinity to long. */
+class InfToLong : public ToLongBase {
+ Value value() {
+ return Value(std::numeric_limits<double>::infinity());
+ }
+ bool asserts() {
+ return true;
+ }
+};
+
+/** Coerce negative infinity to long. **/
+class NegInfToLong : public ToLongBase {
+ Value value() {
+ return Value(std::numeric_limits<double>::infinity() * -1);
+ }
+ bool asserts() {
+ return true;
+ }
+};
+
+/** Coerce large to long. **/
+class InvalidLargeToLong : public ToLongBase {
+ Value value() {
+ return Value(pow(2, 63));
+ }
+ bool asserts() {
+ return true;
+ }
+};
+
+/** Coerce lowest double to long. **/
+class LowestDoubleToLong : public ToLongBase {
+ Value value() {
+ return Value(static_cast<double>(std::numeric_limits<long long>::lowest()));
+ }
+ long long expected() {
+ return std::numeric_limits<long long>::lowest();
+ }
+};
+
+/** Coerce 'towards infinity' to long **/
+class TowardsInfinityToLong : public ToLongBase {
+ Value value() {
+ return Value(static_cast<double>(std::nextafter(std::numeric_limits<long long>::lowest(),
+ std::numeric_limits<double>::lowest())));
+ }
+ bool asserts() {
+ return true;
+ }
+};
+
/** Coerce null to long. */
class NullToLong : public ToLongBase {
Value value() {
@@ -1949,12 +2042,21 @@ public:
add<Value::Coerce::NullToInt>();
add<Value::Coerce::UndefinedToInt>();
add<Value::Coerce::StringToInt>();
+ add<Value::Coerce::MaxIntToInt>();
+ add<Value::Coerce::MinIntToInt>();
+ add<Value::Coerce::TooLargeToInt>();
+ add<Value::Coerce::TooLargeNegativeToInt>();
add<Value::Coerce::IntToLong>();
add<Value::Coerce::LongToLong>();
add<Value::Coerce::DoubleToLong>();
add<Value::Coerce::NullToLong>();
add<Value::Coerce::UndefinedToLong>();
add<Value::Coerce::StringToLong>();
+ add<Value::Coerce::InfToLong>();
+ add<Value::Coerce::NegInfToLong>();
+ add<Value::Coerce::InvalidLargeToLong>();
+ add<Value::Coerce::LowestDoubleToLong>();
+ add<Value::Coerce::TowardsInfinityToLong>();
add<Value::Coerce::IntToDouble>();
add<Value::Coerce::LongToDouble>();
add<Value::Coerce::DoubleToDouble>();