Skip to content

Commit

Permalink
univalue: Throw exception on invalid pushes over silent ignore
Browse files Browse the repository at this point in the history
  • Loading branch information
MacroFake committed Jul 13, 2022
1 parent ccccc17 commit fa277cd
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 48 deletions.
15 changes: 7 additions & 8 deletions src/univalue/include/univalue.h
Expand Up @@ -82,14 +82,14 @@ class UniValue {
bool isArray() const { return (typ == VARR); }
bool isObject() const { return (typ == VOBJ); }

bool push_back(const UniValue& val);
bool push_backV(const std::vector<UniValue>& vec);
void push_back(const UniValue& val);
void push_backV(const std::vector<UniValue>& vec);
template <class It>
bool push_backV(It first, It last);
void push_backV(It first, It last);

void __pushKV(const std::string& key, const UniValue& val);
bool pushKV(const std::string& key, const UniValue& val);
bool pushKVs(const UniValue& obj);
void pushKV(const std::string& key, const UniValue& val);
void pushKVs(const UniValue& obj);

std::string write(unsigned int prettyIndent = 0,
unsigned int indentLevel = 0) const;
Expand Down Expand Up @@ -140,11 +140,10 @@ class UniValue {
};

template <class It>
bool UniValue::push_backV(It first, It last)
void UniValue::push_backV(It first, It last)
{
if (typ != VARR) return false;
if (typ != VARR) throw std::runtime_error{"JSON value is not an array as expected"};
values.insert(values.end(), first, last);
return true;
}

enum jtokentype {
Expand Down
28 changes: 10 additions & 18 deletions src/univalue/lib/univalue.cpp
Expand Up @@ -108,53 +108,45 @@ bool UniValue::setObject()
return true;
}

bool UniValue::push_back(const UniValue& val_)
void UniValue::push_back(const UniValue& val_)
{
if (typ != VARR)
return false;
if (typ != VARR) throw std::runtime_error{"JSON value is not an array as expected"};

values.push_back(val_);
return true;
}

bool UniValue::push_backV(const std::vector<UniValue>& vec)
void UniValue::push_backV(const std::vector<UniValue>& vec)
{
if (typ != VARR)
return false;
if (typ != VARR) throw std::runtime_error{"JSON value is not an array as expected"};

values.insert(values.end(), vec.begin(), vec.end());

return true;
}

void UniValue::__pushKV(const std::string& key, const UniValue& val_)
{
if (typ != VOBJ) throw std::runtime_error{"JSON value is not an object as expected"};

keys.push_back(key);
values.push_back(val_);
}

bool UniValue::pushKV(const std::string& key, const UniValue& val_)
void UniValue::pushKV(const std::string& key, const UniValue& val_)
{
if (typ != VOBJ)
return false;
if (typ != VOBJ) throw std::runtime_error{"JSON value is not an object as expected"};

size_t idx;
if (findKey(key, idx))
values[idx] = val_;
else
__pushKV(key, val_);
return true;
}

bool UniValue::pushKVs(const UniValue& obj)
void UniValue::pushKVs(const UniValue& obj)
{
if (typ != VOBJ || obj.typ != VOBJ)
return false;
if (typ != VOBJ || obj.typ != VOBJ) throw std::runtime_error{"JSON value is not an object as expected"};

for (size_t i = 0; i < obj.keys.size(); i++)
__pushKV(obj.keys[i], obj.values.at(i));

return true;
}

void UniValue::getObjMap(std::map<std::string,UniValue>& kv) const
Expand Down
54 changes: 32 additions & 22 deletions src/univalue/test/object.cpp
Expand Up @@ -85,6 +85,16 @@ BOOST_AUTO_TEST_CASE(univalue_constructor)
BOOST_CHECK_EQUAL(v9.getValStr(), "zappa");
}

BOOST_AUTO_TEST_CASE(univalue_push_throw)
{
UniValue j;
BOOST_CHECK_THROW(j.push_back(1), std::runtime_error);
BOOST_CHECK_THROW(j.push_backV({1}), std::runtime_error);
BOOST_CHECK_THROW(j.__pushKV("k", 1), std::runtime_error);
BOOST_CHECK_THROW(j.pushKV("k", 1), std::runtime_error);
BOOST_CHECK_THROW(j.pushKVs({}), std::runtime_error);
}

BOOST_AUTO_TEST_CASE(univalue_typecheck)
{
UniValue v1;
Expand Down Expand Up @@ -198,13 +208,13 @@ BOOST_AUTO_TEST_CASE(univalue_array)
UniValue arr(UniValue::VARR);

UniValue v((int64_t)1023LL);
BOOST_CHECK(arr.push_back(v));
arr.push_back(v);

std::string vStr("zippy");
BOOST_CHECK(arr.push_back(vStr));
arr.push_back(vStr);

const char *s = "pippy";
BOOST_CHECK(arr.push_back(s));
arr.push_back(s);

std::vector<UniValue> vec;
v.setStr("boing");
Expand All @@ -213,13 +223,13 @@ BOOST_AUTO_TEST_CASE(univalue_array)
v.setStr("going");
vec.push_back(v);

BOOST_CHECK(arr.push_backV(vec));
arr.push_backV(vec);

BOOST_CHECK(arr.push_back((uint64_t) 400ULL));
BOOST_CHECK(arr.push_back((int64_t) -400LL));
BOOST_CHECK(arr.push_back((int) -401));
BOOST_CHECK(arr.push_back(-40.1));
BOOST_CHECK(arr.push_back(true));
arr.push_back(uint64_t{400ULL});
arr.push_back(int64_t{-400LL});
arr.push_back(int{-401});
arr.push_back(-40.1);
arr.push_back(true);

BOOST_CHECK_EQUAL(arr.empty(), false);
BOOST_CHECK_EQUAL(arr.size(), 10);
Expand Down Expand Up @@ -260,39 +270,39 @@ BOOST_AUTO_TEST_CASE(univalue_object)

strKey = "age";
v.setInt(100);
BOOST_CHECK(obj.pushKV(strKey, v));
obj.pushKV(strKey, v);

strKey = "first";
strVal = "John";
BOOST_CHECK(obj.pushKV(strKey, strVal));
obj.pushKV(strKey, strVal);

strKey = "last";
const char *cVal = "Smith";
BOOST_CHECK(obj.pushKV(strKey, cVal));
const char* cVal = "Smith";
obj.pushKV(strKey, cVal);

strKey = "distance";
BOOST_CHECK(obj.pushKV(strKey, (int64_t) 25));
obj.pushKV(strKey, int64_t{25});

strKey = "time";
BOOST_CHECK(obj.pushKV(strKey, (uint64_t) 3600));
obj.pushKV(strKey, uint64_t{3600});

strKey = "calories";
BOOST_CHECK(obj.pushKV(strKey, (int) 12));
obj.pushKV(strKey, int{12});

strKey = "temperature";
BOOST_CHECK(obj.pushKV(strKey, (double) 90.012));
obj.pushKV(strKey, double{90.012});

strKey = "moon";
BOOST_CHECK(obj.pushKV(strKey, true));
obj.pushKV(strKey, true);

strKey = "spoon";
BOOST_CHECK(obj.pushKV(strKey, false));
obj.pushKV(strKey, false);

UniValue obj2(UniValue::VOBJ);
BOOST_CHECK(obj2.pushKV("cat1", 9000));
BOOST_CHECK(obj2.pushKV("cat2", 12345));
obj2.pushKV("cat1", 9000);
obj2.pushKV("cat2", 12345);

BOOST_CHECK(obj.pushKVs(obj2));
obj.pushKVs(obj2);

BOOST_CHECK_EQUAL(obj.empty(), false);
BOOST_CHECK_EQUAL(obj.size(), 11);
Expand Down

0 comments on commit fa277cd

Please sign in to comment.