Simplify RPCclient, adapt json_parse_error test

# Conflicts:
#	src/test/rpc_tests.cpp
This commit is contained in:
Wladimir J. van der Laan 2015-06-04 10:31:22 +02:00 committed by Jonas Schnelli
parent 519eedeba7
commit 043df2b568
3 changed files with 30 additions and 33 deletions

View file

@ -121,6 +121,18 @@ CRPCConvertTable::CRPCConvertTable()
static CRPCConvertTable rpcCvtTable; static CRPCConvertTable rpcCvtTable;
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
* as well as objects and arrays.
*/
UniValue ParseNonRFCJSONValue(const std::string& strVal)
{
UniValue jVal;
if (!jVal.read(std::string("[")+strVal+std::string("]")) ||
!jVal.isArray() || jVal.size()!=1)
throw runtime_error(string("Error parsing JSON:")+strVal);
return jVal[0];
}
/** Convert strings to command-specific RPC representation */ /** Convert strings to command-specific RPC representation */
UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams) UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
{ {
@ -129,28 +141,12 @@ UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::s
for (unsigned int idx = 0; idx < strParams.size(); idx++) { for (unsigned int idx = 0; idx < strParams.size(); idx++) {
const std::string& strVal = strParams[idx]; const std::string& strVal = strParams[idx];
// insert string value directly
if (!rpcCvtTable.convert(strMethod, idx)) { if (!rpcCvtTable.convert(strMethod, idx)) {
// insert string value directly
params.push_back(strVal); params.push_back(strVal);
} } else {
// parse string as JSON, insert bool/number/object/etc. value // parse string as JSON, insert bool/number/object/etc. value
else { params.push_back(ParseNonRFCJSONValue(strVal));
//according to rfc4627 null, true, false are not valid json strings
UniValue jVal;
if(strVal == "null")
jVal.setNull();
else if(strVal == "true")
jVal.setBool(true);
else if(strVal == "false")
jVal.setBool(false);
else
{
if (!jVal.read(strVal) || (jVal.isNull() && strVal.size() > 0))
if(!jVal.setNumStr(strVal) || jVal.isNull())
throw runtime_error(string("Error parsing JSON:")+strVal);
}
params.push_back(jVal);
} }
} }

View file

@ -9,5 +9,9 @@
#include "univalue/univalue.h" #include "univalue/univalue.h"
UniValue RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams); UniValue RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams);
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
* as well as objects and arrays.
*/
UniValue ParseNonRFCJSONValue(const std::string& strVal);
#endif // BITCOIN_RPCCLIENT_H #endif // BITCOIN_RPCCLIENT_H

View file

@ -143,23 +143,20 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values)
BOOST_AUTO_TEST_CASE(json_parse_errors) BOOST_AUTO_TEST_CASE(json_parse_errors)
{ {
UniValue value;
// Valid // Valid
BOOST_CHECK_EQUAL(value.read(std::string("1.0")), false); BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0").get_real(), 1.0);
BOOST_CHECK_EQUAL(value.read(std::string("[1.0]")), true); // Valid, with leading or trailing whitespace
// Valid, with trailing whitespace BOOST_CHECK_EQUAL(ParseNonRFCJSONValue(" 1.0").get_real(), 1.0);
BOOST_CHECK_EQUAL(value.read(std::string("1.0 ")), false); BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0 ").get_real(), 1.0);
BOOST_CHECK_EQUAL(value.read(std::string("[1.0 ] ")), true);
// Invalid, initial garbage // Invalid, initial garbage
BOOST_CHECK_EQUAL(value.read(std::string("[1.0")), false); BOOST_CHECK_THROW(ParseNonRFCJSONValue("[1.0"), std::runtime_error);
BOOST_CHECK_EQUAL(value.read(std::string("[a1.0]")), false); BOOST_CHECK_THROW(ParseNonRFCJSONValue("a1.0"), std::runtime_error);
BOOST_CHECK_EQUAL(value.read(std::string("[\"a1.0\"]")), true);
// Invalid, trailing garbage // Invalid, trailing garbage
BOOST_CHECK_EQUAL(value.read(std::string("1.0sds")), false); BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0sds"), std::runtime_error);
BOOST_CHECK_EQUAL(value.read(std::string("1.0]")), false); BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0]"), std::runtime_error);
// BTC addresses should fail parsing // BTC addresses should fail parsing
BOOST_CHECK_EQUAL(value.read(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")), false); BOOST_CHECK_THROW(ParseNonRFCJSONValue("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), std::runtime_error);
BOOST_CHECK_EQUAL(value.read(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL")), false); BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error);
} }
BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr)