From c354809e1c7e00b0bd79fe2d4f542de4cde0921d Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 19 Nov 2018 12:36:02 -0600 Subject: [PATCH] Implement missing string conversions for JSON `Json::Value::isConvertibleTo` indicates that unsigned integers and reals are convertible to string, but trying to do so (with `Json::Value::asString`) throws an exception because its internal switch is missing these cases. This change fills them in (and adds tests). Acknowledgements: Ripple thanks Guido Vranken for responsibly disclosing this issue. Closes #2778 --- src/ripple/json/impl/json_value.cpp | 4 ++++ src/ripple/json/json_value.h | 2 ++ src/test/json/json_value_test.cpp | 37 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/src/ripple/json/impl/json_value.cpp b/src/ripple/json/impl/json_value.cpp index 88e0a429e9..10ff20e30c 100644 --- a/src/ripple/json/impl/json_value.cpp +++ b/src/ripple/json/impl/json_value.cpp @@ -523,7 +523,11 @@ Value::asString () const return beast::lexicalCastThrow (value_.int_); case uintValue: + return beast::lexicalCastThrow (value_.uint_); + case realValue: + return beast::lexicalCastThrow (value_.real_); + case arrayValue: case objectValue: JSON_ASSERT_MESSAGE ( false, "Type is not convertible to string" ); diff --git a/src/ripple/json/json_value.h b/src/ripple/json/json_value.h index 242c22004b..ee1fae0e5c 100644 --- a/src/ripple/json/json_value.h +++ b/src/ripple/json/json_value.h @@ -246,12 +246,14 @@ public: ValueType type () const; const char* asCString () const; + /** Returns the unquoted string value. */ std::string asString () const; Int asInt () const; UInt asUInt () const; double asDouble () const; bool asBool () const; + // TODO: What is the "empty()" method this docstring mentions? /** isNull() tests to see if this field is null. Don't use this method to test for emptiness: use empty(). */ bool isNull () const; diff --git a/src/test/json/json_value_test.cpp b/src/test/json/json_value_test.cpp index 82de38f473..e587ce6d46 100644 --- a/src/test/json/json_value_test.cpp +++ b/src/test/json/json_value_test.cpp @@ -24,6 +24,7 @@ #include #include +#include namespace ripple { @@ -250,6 +251,41 @@ struct json_value_test : beast::unit_test::suite } } + void test_conversions () + { + // We have Json::Int, but not Json::Double or Json::Real. + // We have Json::Int, Json::Value::Int, and Json::ValueType::intValue. + // We have Json::ValueType::realValue but Json::Value::asDouble. + // TODO: What's the thinking here? + { + // null + Json::Value val; + BEAST_EXPECT(val.isNull()); + BEAST_EXPECT(val.asString() == ""); + } + { + // bool + Json::Value val = true; + BEAST_EXPECT(val.asString() == "true"); + } + { + // int + Json::Value val = -1234; + BEAST_EXPECT(val.asString() == "-1234"); + } + { + // uint + Json::Value val = 1234U; + BEAST_EXPECT(val.asString() == "1234"); + } + { + // real + Json::Value val = 2.0; + BEAST_EXPECT(std::regex_match( + val.asString(), std::regex("^2\\.0*$"))); + } + } + void test_nest_limits () { Json::Reader r; @@ -316,6 +352,7 @@ struct json_value_test : beast::unit_test::suite test_move (); test_comparisons (); test_compact (); + test_conversions(); test_nest_limits (); test_leak(); }