Skip to content

Commit

Permalink
Implement missing string conversions for JSON
Browse files Browse the repository at this point in the history
`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
  • Loading branch information
thejohnfreeman committed Nov 20, 2018
1 parent cc82468 commit c0e9418
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/ripple/json/impl/json_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,11 @@ Value::asString () const
return beast::lexicalCastThrow <std::string> (value_.int_);

case uintValue:
return beast::lexicalCastThrow <std::string> (value_.uint_);

case realValue:
return beast::lexicalCastThrow <std::string> (value_.real_);

case arrayValue:
case objectValue:
JSON_ASSERT_MESSAGE ( false, "Type is not convertible to string" );
Expand Down
2 changes: 2 additions & 0 deletions src/ripple/json/json_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,14 @@ class Value
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;
Expand Down
37 changes: 37 additions & 0 deletions src/test/json/json_value_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <ripple/beast/type_name.h>

#include <algorithm>
#include <regex>

namespace ripple {

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand Down

0 comments on commit c0e9418

Please sign in to comment.