This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git


The following commit(s) were added to refs/heads/master by this push:
     new 9c0787682 Fixed inf scalar value parsing.
9c0787682 is described below

commit 9c0787682c5f4c169b42146f376b8552fa740559
Author: Ilya Pronin <[email protected]>
AuthorDate: Wed Dec 4 16:59:36 2019 -0800

    Fixed inf scalar value parsing.
    
    Infinite and NaN values are not usable with SCALAR values. However,
    there are use-cases where they are valid TEXT values, e.g. in the agent
    attribute specifying its rack name.
    
    Differential Revision: https://phabricator.twitter.biz/D409445
---
 src/common/values.cpp      | 20 ++++++++++++++++----
 src/tests/values_tests.cpp | 42 ++++++++++++++++++++++++++++++++++--------
 src/v1/values.cpp          | 21 ++++++++++++++++-----
 3 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/src/common/values.cpp b/src/common/values.cpp
index d7bc91bcf..4dfb4cbbe 100644
--- a/src/common/values.cpp
+++ b/src/common/values.cpp
@@ -732,12 +732,24 @@ Try<Value> parse(const string& text)
     } else if (index == string::npos) {
       Try<double> value_ = numify<double>(temp);
       if (!value_.isError()) {
-        Option<Error> error =
-          common::validation::validateInputScalarValue(*value_);
-        if (error.isSome()) {
-          return Error("Invalid scalar value '" + temp + "':" + 
error->message);
+        // Check if this is a floating point value that we can work
+        // with. If not, we will handle it as text.
+        switch (std::fpclassify(value_.get())) {
+          case FP_INFINITE:
+          case FP_NAN:
+            value_ = Error("Unsupported floating point value");
+            break;
+          case FP_NORMAL:
+            if (value_.get() < 0) {
+              value_ = Error("Negative values not supported");
+            }
+            break;
+          case FP_SUBNORMAL:
+            return Error("Subnormal values not supported");
         }
+      }
 
+      if (!value_.isError()) {
         // This is a scalar.
         Value::Scalar* scalar = value.mutable_scalar();
         value.set_type(Value::SCALAR);
diff --git a/src/tests/values_tests.cpp b/src/tests/values_tests.cpp
index d67e4eb86..27b41e512 100644
--- a/src/tests/values_tests.cpp
+++ b/src/tests/values_tests.cpp
@@ -73,6 +73,37 @@ TEST(ValuesTest, ValidInput)
   ASSERT_SOME(result4);
   ASSERT_EQ(Value::TEXT, result4->type());
   ASSERT_EQ("123abc,s", result4->text().value());
+
+  // Test parsing unsupported scalar values.
+  Try<Value> result5 = parse("inf");
+  ASSERT_SOME(result5);
+  ASSERT_EQ(Value::TEXT, result5->type());
+  ASSERT_EQ("inf", result5->text().value());
+
+  Try<Value> result6 = parse("-inf");
+  ASSERT_SOME(result6);
+  ASSERT_EQ(Value::TEXT, result6->type());
+  ASSERT_EQ("-inf", result6->text().value());
+
+  Try<Value> result7 = parse("infinity");
+  ASSERT_SOME(result7);
+  ASSERT_EQ(Value::TEXT, result7->type());
+  ASSERT_EQ("infinity", result7->text().value());
+
+  Try<Value> result8 = parse("-infinity");
+  ASSERT_SOME(result8);
+  ASSERT_EQ(Value::TEXT, result8->type());
+  ASSERT_EQ("-infinity", result8->text().value());
+
+  Try<Value> result9 = parse("nan");
+  ASSERT_SOME(result9);
+  ASSERT_EQ(Value::TEXT, result9->type());
+  ASSERT_EQ("nan", result9->text().value());
+
+  Try<Value> result10 = parse("-nan");
+  ASSERT_SOME(result10);
+  ASSERT_EQ(Value::TEXT, result10->type());
+  ASSERT_EQ("-nan", result10->text().value());
 }
 
 
@@ -90,14 +121,9 @@ TEST(ValuesTest, InvalidInput)
   // Test when giving empty string.
   EXPECT_ERROR(parse("  "));
 
-  EXPECT_ERROR(parse("nan"));
-  EXPECT_ERROR(parse("-nan"));
-
-  EXPECT_ERROR(parse("inf"));
-  EXPECT_ERROR(parse("-inf"));
-
-  EXPECT_ERROR(parse("infinity"));
-  EXPECT_ERROR(parse("-infinity"));
+  // Test subnormal scalar value.
+  EXPECT_ERROR(parse("7.63918e-313"));
+  EXPECT_ERROR(parse("-7.63918e-313"));
 }
 
 
diff --git a/src/v1/values.cpp b/src/v1/values.cpp
index 6193dbd8b..917302431 100644
--- a/src/v1/values.cpp
+++ b/src/v1/values.cpp
@@ -755,13 +755,24 @@ Try<Value> parse(const string& text)
     } else if (index == string::npos) {
       Try<double> value_ = numify<double>(temp);
       if (!value_.isError()) {
-        Option<Error> error =
-          mesos::internal::common::validation::validateInputScalarValue(
-              *value_);
-        if (error.isSome()) {
-          return Error("Invalid scalar value '" + temp + "':" + 
error->message);
+        // Check if this is a floating point value that we can work
+        // with. If not, we will handle it as text.
+        switch (std::fpclassify(value_.get())) {
+          case FP_INFINITE:
+          case FP_NAN:
+            value_ = Error("Unsupported floating point value");
+            break;
+          case FP_NORMAL:
+            if (value_.get() < 0) {
+              value_ = Error("Negative values not supported");
+            }
+            break;
+          case FP_SUBNORMAL:
+            return Error("Subnormal values not supported");
         }
+      }
 
+      if (!value_.isError()) {
         // This is a scalar.
         Value::Scalar* scalar = value.mutable_scalar();
         value.set_type(Value::SCALAR);

Reply via email to