diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.test.include | 10 | ||||
| -rw-r--r-- | src/bitcoin-tx.cpp | 28 | ||||
| -rw-r--r-- | src/qt/forms/overviewpage.ui | 6 | ||||
| -rw-r--r-- | src/rpcserver.cpp | 5 | ||||
| -rw-r--r-- | src/serialize.h | 10 | ||||
| -rw-r--r-- | src/test/bctest.py | 43 | ||||
| -rwxr-xr-x | src/test/bitcoin-util-test.py | 12 | ||||
| -rw-r--r-- | src/test/data/bitcoin-util-test.json | 9 | ||||
| -rw-r--r-- | src/test/data/blanktx.hex | 1 | ||||
| -rw-r--r-- | src/test/rpc_tests.cpp | 32 | ||||
| -rw-r--r-- | src/test/univalue_tests.cpp | 275 | ||||
| -rw-r--r-- | src/univalue/univalue.cpp | 2 | ||||
| -rw-r--r-- | src/univalue/univalue_write.cpp | 11 |
13 files changed, 409 insertions, 35 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include index b54c9be66..bf6534cf3 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -1,8 +1,15 @@ -TESTS += test/test_bitcoin +TESTS += test/test_bitcoin test/bitcoin-util-test.py bin_PROGRAMS += test/test_bitcoin TEST_SRCDIR = test TEST_BINARY=test/test_bitcoin$(EXEEXT) + +EXTRA_DIST += \ + test/bctest.py \ + test/bitcoin-util-test.py \ + test/data/bitcoin-util-test.json \ + test/data/blanktx.hex + JSON_TEST_FILES = \ test/data/script_valid.json \ test/data/base58_keys_valid.json \ @@ -51,6 +58,7 @@ BITCOIN_TESTS =\ test/test_bitcoin.cpp \ test/transaction_tests.cpp \ test/uint256_tests.cpp \ + test/univalue_tests.cpp \ test/util_tests.cpp \ test/scriptnum_tests.cpp \ test/sighash_tests.cpp diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index ffe87298f..6cd2768d7 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -13,6 +13,7 @@ #include <stdio.h> #include <boost/assign/list_of.hpp> +#include <boost/algorithm/string.hpp> using namespace std; using namespace boost::assign; @@ -501,13 +502,34 @@ static void OutputTx(const CTransaction& tx) OutputTxHex(tx); } +static string readStdin() +{ + char buf[4096]; + string ret; + + while (!feof(stdin)) { + size_t bread = fread(buf, 1, sizeof(buf), stdin); + ret.append(buf, bread); + if (bread < sizeof(buf)) + break; + } + + if (ferror(stdin)) + throw runtime_error("error reading stdin"); + + boost::algorithm::trim_right(ret); + + return ret; +} + static int CommandLineRawTx(int argc, char* argv[]) { string strPrint; int nRet = 0; try { - // Skip switches - while (argc > 1 && IsSwitchChar(argv[1][0])) { + // Skip switches; Permit common stdin convention "-" + while (argc > 1 && IsSwitchChar(argv[1][0]) && + (argv[1][1] != 0)) { argc--; argv++; } @@ -522,6 +544,8 @@ static int CommandLineRawTx(int argc, char* argv[]) // param: hex-encoded bitcoin transaction string strHexTx(argv[1]); + if (strHexTx == "-") // "-" implies standard input + strHexTx = readStdin(); if (!DecodeHexTx(txDecodeTmp, strHexTx)) throw runtime_error("invalid transaction encoding"); diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 7784a862d..53d416ef3 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -13,8 +13,8 @@ <property name="windowTitle"> <string>Form</string> </property> - <layout class="QFormLayout" name="formLayout_3"> - <item row="0" column="0" colspan="2"> + <layout class="QVBoxLayout" name="topLayout"> + <item> <widget class="QLabel" name="labelAlerts"> <property name="visible"> <bool>false</bool> @@ -30,7 +30,7 @@ </property> </widget> </item> - <item row="1" column="1"> + <item> <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1"> <item> <layout class="QVBoxLayout" name="verticalLayout_2"> diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 3b51c91e7..524627e2d 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -849,11 +849,10 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, if (!HTTPAuthorized(mapHeaders)) { LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string()); - /* Deter brute-forcing short passwords. + /* Deter brute-forcing If this results in a DoS the user really shouldn't have their RPC port exposed. */ - if (mapArgs["-rpcpassword"].size() < 20) - MilliSleep(250); + MilliSleep(250); conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush; return false; diff --git a/src/serialize.h b/src/serialize.h index 2eb69b3ec..3e5eff469 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -68,7 +68,7 @@ inline const T* end_ptr(const std::vector<T,TAl>& v) ///////////////////////////////////////////////////////////////// // // Templates for serializing to anything that looks like a stream, -// i.e. anything that supports .read(char*, int) and .write(char*, int) +// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t) // enum @@ -876,7 +876,7 @@ public: CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {} - CSizeComputer& write(const char *psz, int nSize) + CSizeComputer& write(const char *psz, size_t nSize) { this->nSize += nSize; return *this; @@ -1105,10 +1105,9 @@ public: void ReadVersion() { *this >> nVersion; } void WriteVersion() { *this << nVersion; } - CDataStream& read(char* pch, int nSize) + CDataStream& read(char* pch, size_t nSize) { // Read from the beginning of the buffer - assert(nSize >= 0); unsigned int nReadPosNext = nReadPos + nSize; if (nReadPosNext >= vch.size()) { @@ -1145,10 +1144,9 @@ public: return (*this); } - CDataStream& write(const char* pch, int nSize) + CDataStream& write(const char* pch, size_t nSize) { // Write to the end of the buffer - assert(nSize >= 0); vch.insert(vch.end(), pch, pch + nSize); return (*this); } diff --git a/src/test/bctest.py b/src/test/bctest.py new file mode 100644 index 000000000..b12647908 --- /dev/null +++ b/src/test/bctest.py @@ -0,0 +1,43 @@ +# Copyright 2014 BitPay, Inc. +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import subprocess +import os +import json +import sys + +def bctest(testDir, testObj): + execargs = testObj['exec'] + + stdinCfg = None + inputData = None + if "input" in testObj: + filename = testDir + "/" + testObj['input'] + inputData = open(filename).read() + stdinCfg = subprocess.PIPE + + outputFn = testObj['output_cmp'] + outputData = open(testDir + "/" + outputFn).read() + + proc = subprocess.Popen(execargs, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + try: + outs = proc.communicate(input=inputData) + except OSError: + print("OSError, Failed to execute " + execargs[0]) + sys.exit(1) + + if outs[0] != outputData: + print("Output data mismatch for " + outputFn) + sys.exit(1) + +def bctester(testDir, input_basename): + input_filename = testDir + "/" + input_basename + raw_data = open(input_filename).read() + input_data = json.loads(raw_data) + + for testObj in input_data: + bctest(testDir, testObj) + + sys.exit(0) + diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py new file mode 100755 index 000000000..40690c2fe --- /dev/null +++ b/src/test/bitcoin-util-test.py @@ -0,0 +1,12 @@ +#!/usr/bin/python +# Copyright 2014 BitPay, Inc. +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import os +import bctest + +if __name__ == '__main__': + bctest.bctester(os.environ["srcdir"] + "/test/data", + "bitcoin-util-test.json") + diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json new file mode 100644 index 000000000..16bcb4489 --- /dev/null +++ b/src/test/data/bitcoin-util-test.json @@ -0,0 +1,9 @@ +[ + { "exec": ["./bitcoin-tx", "-create"], + "output_cmp": "blanktx.hex" + }, + { "exec": ["./bitcoin-tx", "-"], + "input": "blanktx.hex", + "output_cmp": "blanktx.hex" + } +] diff --git a/src/test/data/blanktx.hex b/src/test/data/blanktx.hex new file mode 100644 index 000000000..36b6f00fb --- /dev/null +++ b/src/test/data/blanktx.hex @@ -0,0 +1 @@ +01000000000000000000 diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 107c0f06e..d5475a92b 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -110,14 +110,14 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) { - BOOST_CHECK(write_string(ValueFromAmount(0LL), false) == "0.00000000"); - BOOST_CHECK(write_string(ValueFromAmount(1LL), false) == "0.00000001"); - BOOST_CHECK(write_string(ValueFromAmount(17622195LL), false) == "0.17622195"); - BOOST_CHECK(write_string(ValueFromAmount(50000000LL), false) == "0.50000000"); - BOOST_CHECK(write_string(ValueFromAmount(89898989LL), false) == "0.89898989"); - BOOST_CHECK(write_string(ValueFromAmount(100000000LL), false) == "1.00000000"); - BOOST_CHECK(write_string(ValueFromAmount(2099999999999990LL), false) == "20999999.99999990"); - BOOST_CHECK(write_string(ValueFromAmount(2099999999999999LL), false) == "20999999.99999999"); + BOOST_CHECK_EQUAL(write_string(ValueFromAmount(0LL), false), "0.00000000"); + BOOST_CHECK_EQUAL(write_string(ValueFromAmount(1LL), false), "0.00000001"); + BOOST_CHECK_EQUAL(write_string(ValueFromAmount(17622195LL), false), "0.17622195"); + BOOST_CHECK_EQUAL(write_string(ValueFromAmount(50000000LL), false), "0.50000000"); + BOOST_CHECK_EQUAL(write_string(ValueFromAmount(89898989LL), false), "0.89898989"); + BOOST_CHECK_EQUAL(write_string(ValueFromAmount(100000000LL), false), "1.00000000"); + BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999990LL), false), "20999999.99999990"); + BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999999LL), false), "20999999.99999999"); } static Value ValueFromString(const std::string &str) @@ -129,14 +129,14 @@ static Value ValueFromString(const std::string &str) BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) { - BOOST_CHECK(AmountFromValue(ValueFromString("0.00000001")) == 1LL); - BOOST_CHECK(AmountFromValue(ValueFromString("0.17622195")) == 17622195LL); - BOOST_CHECK(AmountFromValue(ValueFromString("0.5")) == 50000000LL); - BOOST_CHECK(AmountFromValue(ValueFromString("0.50000000")) == 50000000LL); - BOOST_CHECK(AmountFromValue(ValueFromString("0.89898989")) == 89898989LL); - BOOST_CHECK(AmountFromValue(ValueFromString("1.00000000")) == 100000000LL); - BOOST_CHECK(AmountFromValue(ValueFromString("20999999.9999999")) == 2099999999999990LL); - BOOST_CHECK(AmountFromValue(ValueFromString("20999999.99999999")) == 2099999999999999LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001")), 1LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.17622195")), 17622195LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.5")), 50000000LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.50000000")), 50000000LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.89898989")), 89898989LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1.00000000")), 100000000LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.9999999")), 2099999999999990LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.99999999")), 2099999999999999LL); } BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp new file mode 100644 index 000000000..23bc5f6b1 --- /dev/null +++ b/src/test/univalue_tests.cpp @@ -0,0 +1,275 @@ +// Copyright 2014 BitPay, Inc. +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <stdint.h> +#include <vector> +#include <string> +#include <map> +#include "univalue/univalue.h" + +#include <boost/test/unit_test.hpp> + +using namespace std; + +BOOST_AUTO_TEST_SUITE(univalue_tests) + +BOOST_AUTO_TEST_CASE(univalue_constructor) +{ + UniValue v1; + BOOST_CHECK(v1.isNull()); + + UniValue v2(UniValue::VSTR); + BOOST_CHECK(v2.isStr()); + + UniValue v3(UniValue::VSTR, "foo"); + BOOST_CHECK(v3.isStr()); + BOOST_CHECK_EQUAL(v3.getValStr(), "foo"); + + UniValue numTest; + BOOST_CHECK(numTest.setNumStr("82")); + BOOST_CHECK(numTest.isNum()); + BOOST_CHECK_EQUAL(numTest.getValStr(), "82"); + + uint64_t vu64 = 82; + UniValue v4(vu64); + BOOST_CHECK(v4.isNum()); + BOOST_CHECK_EQUAL(v4.getValStr(), "82"); + + int64_t vi64 = -82; + UniValue v5(vi64); + BOOST_CHECK(v5.isNum()); + BOOST_CHECK_EQUAL(v5.getValStr(), "-82"); + + int vi = -688; + UniValue v6(vi); + BOOST_CHECK(v6.isNum()); + BOOST_CHECK_EQUAL(v6.getValStr(), "-688"); + + double vd = -7.21; + UniValue v7(vd); + BOOST_CHECK(v7.isNum()); + BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21"); + + string vs("yawn"); + UniValue v8(vs); + BOOST_CHECK(v8.isStr()); + BOOST_CHECK_EQUAL(v8.getValStr(), "yawn"); + + const char *vcs = "zappa"; + UniValue v9(vcs); + BOOST_CHECK(v9.isStr()); + BOOST_CHECK_EQUAL(v9.getValStr(), "zappa"); +} + +BOOST_AUTO_TEST_CASE(univalue_set) +{ + UniValue v(UniValue::VSTR, "foo"); + v.clear(); + BOOST_CHECK(v.isNull()); + BOOST_CHECK_EQUAL(v.getValStr(), ""); + + BOOST_CHECK(v.setObject()); + BOOST_CHECK(v.isObject()); + BOOST_CHECK_EQUAL(v.count(), 0); + BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ); + BOOST_CHECK(v.empty()); + + BOOST_CHECK(v.setArray()); + BOOST_CHECK(v.isArray()); + BOOST_CHECK_EQUAL(v.count(), 0); + + BOOST_CHECK(v.setStr("zum")); + BOOST_CHECK(v.isStr()); + BOOST_CHECK_EQUAL(v.getValStr(), "zum"); + + BOOST_CHECK(v.setFloat(-1.01)); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "-1.01"); + + BOOST_CHECK(v.setInt((int)1023)); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "1023"); + + BOOST_CHECK(v.setInt((int64_t)-1023LL)); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "-1023"); + + BOOST_CHECK(v.setInt((uint64_t)1023ULL)); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "1023"); + + BOOST_CHECK(v.setNumStr("-688")); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "-688"); + + BOOST_CHECK(v.setBool(false)); + BOOST_CHECK_EQUAL(v.isBool(), true); + BOOST_CHECK_EQUAL(v.isTrue(), false); + BOOST_CHECK_EQUAL(v.isFalse(), true); + BOOST_CHECK_EQUAL(v.getBool(), false); + + BOOST_CHECK(v.setBool(true)); + BOOST_CHECK_EQUAL(v.isBool(), true); + BOOST_CHECK_EQUAL(v.isTrue(), true); + BOOST_CHECK_EQUAL(v.isFalse(), false); + BOOST_CHECK_EQUAL(v.getBool(), true); + + BOOST_CHECK(!v.setNumStr("zombocom")); + + BOOST_CHECK(v.setNull()); + BOOST_CHECK(v.isNull()); +} + +BOOST_AUTO_TEST_CASE(univalue_array) +{ + UniValue arr(UniValue::VARR); + + UniValue v((int64_t)1023LL); + BOOST_CHECK(arr.push_back(v)); + + string vStr("zippy"); + BOOST_CHECK(arr.push_back(vStr)); + + const char *s = "pippy"; + BOOST_CHECK(arr.push_back(s)); + + vector<UniValue> vec; + v.setStr("boing"); + vec.push_back(v); + + v.setStr("going"); + vec.push_back(v); + + BOOST_CHECK(arr.push_backV(vec)); + + BOOST_CHECK_EQUAL(arr.empty(), false); + BOOST_CHECK_EQUAL(arr.count(), 5); + + BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023"); + BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy"); + BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy"); + BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing"); + BOOST_CHECK_EQUAL(arr[4].getValStr(), "going"); + + BOOST_CHECK_EQUAL(arr[999].getValStr(), ""); + + arr.clear(); + BOOST_CHECK(arr.empty()); + BOOST_CHECK_EQUAL(arr.count(), 0); +} + +BOOST_AUTO_TEST_CASE(univalue_object) +{ + UniValue obj(UniValue::VOBJ); + string strKey, strVal; + UniValue v; + + strKey = "age"; + v.setInt(100); + BOOST_CHECK(obj.pushKV(strKey, v)); + + strKey = "first"; + strVal = "John"; + BOOST_CHECK(obj.pushKV(strKey, strVal)); + + strKey = "last"; + const char *cVal = "Smith"; + BOOST_CHECK(obj.pushKV(strKey, cVal)); + + strKey = "distance"; + BOOST_CHECK(obj.pushKV(strKey, (int64_t) 25)); + + strKey = "time"; + BOOST_CHECK(obj.pushKV(strKey, (uint64_t) 3600)); + + strKey = "calories"; + BOOST_CHECK(obj.pushKV(strKey, (int) 12)); + + strKey = "temperature"; + BOOST_CHECK(obj.pushKV(strKey, (double) 90.012)); + + UniValue obj2(UniValue::VOBJ); + BOOST_CHECK(obj2.pushKV("cat1", 9000)); + BOOST_CHECK(obj2.pushKV("cat2", 12345)); + + BOOST_CHECK(obj.pushKVs(obj2)); + + BOOST_CHECK_EQUAL(obj.empty(), false); + BOOST_CHECK_EQUAL(obj.count(), 9); + + BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100"); + BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John"); + BOOST_CHECK_EQUAL(obj["last"].getValStr(), "Smith"); + BOOST_CHECK_EQUAL(obj["distance"].getValStr(), "25"); + BOOST_CHECK_EQUAL(obj["time"].getValStr(), "3600"); + BOOST_CHECK_EQUAL(obj["calories"].getValStr(), "12"); + BOOST_CHECK_EQUAL(obj["temperature"].getValStr(), "90.012"); + BOOST_CHECK_EQUAL(obj["cat1"].getValStr(), "9000"); + BOOST_CHECK_EQUAL(obj["cat2"].getValStr(), "12345"); + + BOOST_CHECK_EQUAL(obj["nyuknyuknyuk"].getValStr(), ""); + + BOOST_CHECK(obj.exists("age")); + BOOST_CHECK(obj.exists("first")); + BOOST_CHECK(obj.exists("last")); + BOOST_CHECK(obj.exists("distance")); + BOOST_CHECK(obj.exists("time")); + BOOST_CHECK(obj.exists("calories")); + BOOST_CHECK(obj.exists("temperature")); + BOOST_CHECK(obj.exists("cat1")); + BOOST_CHECK(obj.exists("cat2")); + + BOOST_CHECK(!obj.exists("nyuknyuknyuk")); + + map<string, UniValue::VType> objTypes; + objTypes["age"] = UniValue::VNUM; + objTypes["first"] = UniValue::VSTR; + objTypes["last"] = UniValue::VSTR; + objTypes["distance"] = UniValue::VNUM; + objTypes["time"] = UniValue::VNUM; + objTypes["calories"] = UniValue::VNUM; + objTypes["temperature"] = UniValue::VNUM; + objTypes["cat1"] = UniValue::VNUM; + objTypes["cat2"] = UniValue::VNUM; + BOOST_CHECK(obj.checkObject(objTypes)); + + objTypes["cat2"] = UniValue::VSTR; + BOOST_CHECK(!obj.checkObject(objTypes)); + + obj.clear(); + BOOST_CHECK(obj.empty()); + BOOST_CHECK_EQUAL(obj.count(), 0); +} + +static const char *json1 = +"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; + +BOOST_AUTO_TEST_CASE(univalue_readwrite) +{ + UniValue v; + BOOST_CHECK(v.read(json1)); + + string strJson1(json1); + BOOST_CHECK(v.read(strJson1)); + + BOOST_CHECK(v.isArray()); + BOOST_CHECK_EQUAL(v.count(), 2); + + BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1"); + + UniValue obj = v[1]; + BOOST_CHECK(obj.isObject()); + BOOST_CHECK_EQUAL(obj.count(), 3); + + BOOST_CHECK(obj["key1"].isStr()); + BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str"); + BOOST_CHECK(obj["key2"].isNum()); + BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800"); + BOOST_CHECK(obj["key3"].isObject()); + + BOOST_CHECK_EQUAL(strJson1, v.write()); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index afc208bff..b0171e48c 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -44,7 +44,7 @@ static bool validNumStr(const string& s) bool UniValue::setNumStr(const string& val_) { - if (!validNumStr(val)) + if (!validNumStr(val_)) return false; clear(); diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp index 70762a1ef..042091a82 100644 --- a/src/univalue/univalue_write.cpp +++ b/src/univalue/univalue_write.cpp @@ -91,8 +91,11 @@ void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, s if (prettyIndent) s += indentStr(prettyIndent, indentLevel); s += values[i].write(prettyIndent, indentLevel + 1); - if (i != (values.size() - 1)) - s += ", "; + if (i != (values.size() - 1)) { + s += ","; + if (prettyIndent) + s += " "; + } if (prettyIndent) s += "\n"; } @@ -111,7 +114,9 @@ void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, for (unsigned int i = 0; i < keys.size(); i++) { if (prettyIndent) s += indentStr(prettyIndent, indentLevel); - s += "\"" + json_escape(keys[i]) + "\": "; + s += "\"" + json_escape(keys[i]) + "\":"; + if (prettyIndent) + s += " "; s += values[i].write(prettyIndent, indentLevel + 1); if (i != (values.size() - 1)) s += ","; |