Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Handle .pushKV() and .checkObject() edge cases.
Browse files Browse the repository at this point in the history
pushKV: Behave properly in the face of duplicate keys.

checkObject: return error, if not object.

Inspired-by: Charles Yin <yinyunqiao@gmail.com> in PR bitcoin#37
jgarzik committed Aug 3, 2017

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 107db98 commit ceb1194
Showing 3 changed files with 30 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/univalue.h
Original file line number Diff line number Diff line change
@@ -111,6 +111,7 @@ class UniValue {
}
bool push_backV(const std::vector<UniValue>& vec);

void __pushKV(const std::string& key, const UniValue& val);
bool pushKV(const std::string& key, const UniValue& val);
bool pushKV(const std::string& key, const std::string& val_) {
UniValue tmpVal(VSTR, val_);
22 changes: 16 additions & 6 deletions lib/univalue.cpp
Original file line number Diff line number Diff line change
@@ -126,13 +126,22 @@ bool UniValue::push_backV(const std::vector<UniValue>& vec)
return true;
}

void UniValue::__pushKV(const std::string& key, const UniValue& val_)
{
keys.push_back(key);
values.push_back(val_);
}

bool UniValue::pushKV(const std::string& key, const UniValue& val_)
{
if (typ != VOBJ)
return false;

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

@@ -141,10 +150,8 @@ bool UniValue::pushKVs(const UniValue& obj)
if (typ != VOBJ || obj.typ != VOBJ)
return false;

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

return true;
}
@@ -163,6 +170,9 @@ bool UniValue::findKey(const std::string& key, size_t& retIdx) const

bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t)
{
if (typ != VOBJ)
return false;

for (std::map<std::string,UniValue::VType>::const_iterator it = t.begin();
it != t.end(); ++it) {
size_t idx = 0;
13 changes: 13 additions & 0 deletions test/object.cpp
Original file line number Diff line number Diff line change
@@ -311,6 +311,19 @@ BOOST_AUTO_TEST_CASE(univalue_object)
obj.clear();
BOOST_CHECK(obj.empty());
BOOST_CHECK_EQUAL(obj.size(), 0);
BOOST_CHECK_EQUAL(obj.getType(), UniValue::VNULL);

BOOST_CHECK_EQUAL(obj.setObject(), true);
UniValue uv;
uv.setInt(42);
obj.__pushKV("age", uv);
BOOST_CHECK_EQUAL(obj.size(), 1);
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "42");

uv.setInt(43);
obj.pushKV("age", uv);
BOOST_CHECK_EQUAL(obj.size(), 1);
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "43");
}

static const char *json1 =

0 comments on commit ceb1194

Please sign in to comment.