Skip to content

Commit ceb1194

Browse files
committed
Handle .pushKV() and .checkObject() edge cases.
pushKV: Behave properly in the face of duplicate keys. checkObject: return error, if not object. Inspired-by: Charles Yin <[email protected]> in PR #37
1 parent 107db98 commit ceb1194

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

include/univalue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class UniValue {
111111
}
112112
bool push_backV(const std::vector<UniValue>& vec);
113113

114+
void __pushKV(const std::string& key, const UniValue& val);
114115
bool pushKV(const std::string& key, const UniValue& val);
115116
bool pushKV(const std::string& key, const std::string& val_) {
116117
UniValue tmpVal(VSTR, val_);

lib/univalue.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,22 @@ bool UniValue::push_backV(const std::vector<UniValue>& vec)
126126
return true;
127127
}
128128

129+
void UniValue::__pushKV(const std::string& key, const UniValue& val_)
130+
{
131+
keys.push_back(key);
132+
values.push_back(val_);
133+
}
134+
129135
bool UniValue::pushKV(const std::string& key, const UniValue& val_)
130136
{
131137
if (typ != VOBJ)
132138
return false;
133139

134-
keys.push_back(key);
135-
values.push_back(val_);
140+
size_t idx;
141+
if (findKey(key, idx))
142+
values[idx] = val_;
143+
else
144+
__pushKV(key, val_);
136145
return true;
137146
}
138147

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

144-
for (unsigned int i = 0; i < obj.keys.size(); i++) {
145-
keys.push_back(obj.keys[i]);
146-
values.push_back(obj.values.at(i));
147-
}
153+
for (size_t i = 0; i < obj.keys.size(); i++)
154+
__pushKV(obj.keys[i], obj.values.at(i));
148155

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

164171
bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t)
165172
{
173+
if (typ != VOBJ)
174+
return false;
175+
166176
for (std::map<std::string,UniValue::VType>::const_iterator it = t.begin();
167177
it != t.end(); ++it) {
168178
size_t idx = 0;

test/object.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,19 @@ BOOST_AUTO_TEST_CASE(univalue_object)
311311
obj.clear();
312312
BOOST_CHECK(obj.empty());
313313
BOOST_CHECK_EQUAL(obj.size(), 0);
314+
BOOST_CHECK_EQUAL(obj.getType(), UniValue::VNULL);
315+
316+
BOOST_CHECK_EQUAL(obj.setObject(), true);
317+
UniValue uv;
318+
uv.setInt(42);
319+
obj.__pushKV("age", uv);
320+
BOOST_CHECK_EQUAL(obj.size(), 1);
321+
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "42");
322+
323+
uv.setInt(43);
324+
obj.pushKV("age", uv);
325+
BOOST_CHECK_EQUAL(obj.size(), 1);
326+
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "43");
314327
}
315328

316329
static const char *json1 =

0 commit comments

Comments
 (0)