[Pkg-bitcoin-commits] [libunivalue] 01/05: Add patches cherry-picked upstream.

Jonas Smedegaard dr at jones.dk
Sun May 21 11:57:32 UTC 2017


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository libunivalue.

commit af21f0bb6c6ef3757d83033f9f6c9331c363e9a0
Author: Jonas Smedegaard <dr at jones.dk>
Date:   Sun May 21 13:26:13 2017 +0200

    Add patches cherry-picked upstream.
    
      * Reject unterminated strings
      * Have operator[] take size_t index parameter (not unsigned int)
      * Make findKey() size_t clean, and return bool on failure
      * Import UniValue class unit tests from bitcoin project
      * Add ::push_back(double) method for feature parity
      * Move exception-throwing get_* methods to separate module
      * Move one-line implementation of UniValue::read() to header
---
 debian/patches/020161101~4fd5444.patch |  47 ++++
 debian/patches/020170501~0d3e74d.patch |  28 +++
 debian/patches/020170501~640158f.patch |  71 ++++++
 debian/patches/020170502~1dfe464.patch | 397 +++++++++++++++++++++++++++++++++
 debian/patches/020170504~107db98.patch |  47 ++++
 debian/patches/020170504~52e85b3.patch | 320 ++++++++++++++++++++++++++
 debian/patches/020170504~d415300.patch |  34 +++
 debian/patches/README                  |   3 +
 debian/patches/series                  |   7 +
 9 files changed, 954 insertions(+)

diff --git a/debian/patches/020161101~4fd5444.patch b/debian/patches/020161101~4fd5444.patch
new file mode 100644
index 0000000..1817307
--- /dev/null
+++ b/debian/patches/020161101~4fd5444.patch
@@ -0,0 +1,47 @@
+Description: Reject unterminated strings
+ Fixes following test failures in https://github.com/nst/JSONTestSuite:
+ .
+ bitcoin SHOULD_HAVE_FAILED  n_string_single_doublequote.json
+Origin: upstream, https://github.com/jgarzik/univalue/commit/4fd5444
+Author: Russell Yanofsky <russ at yanofsky.org>
+Forwarded: yes
+Last-Update: 2017-05-21
+
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -88,6 +88,7 @@
+ 	$(TEST_DATA_DIR)/fail40.json \
+ 	$(TEST_DATA_DIR)/fail41.json \
+ 	$(TEST_DATA_DIR)/fail42.json \
++	$(TEST_DATA_DIR)/fail44.json \
+ 	$(TEST_DATA_DIR)/fail3.json \
+ 	$(TEST_DATA_DIR)/fail4.json \
+ 	$(TEST_DATA_DIR)/fail5.json \
+--- a/lib/univalue_read.cpp
++++ b/lib/univalue_read.cpp
+@@ -177,8 +177,8 @@
+         string valStr;
+         JSONUTF8StringFilter writer(valStr);
+ 
+-        while (raw < end) {
+-            if ((unsigned char)*raw < 0x20)
++        while (true) {
++            if (raw >= end || (unsigned char)*raw < 0x20)
+                 return JTOK_ERR;
+ 
+             else if (*raw == '\\') {
+--- /dev/null
++++ b/test/fail44.json
+@@ -0,0 +1 @@
++"This file ends without a newline or close-quote.
+\ No newline at end of file
+--- a/test/unitester.cpp
++++ b/test/unitester.cpp
+@@ -114,6 +114,7 @@
+         "fail40.json",               // invalid unicode: broken UTF-8
+         "fail41.json",               // invalid unicode: unfinished UTF-8
+         "fail42.json",               // valid json with garbage following a nul byte
++        "fail44.json",               // unterminated string
+         "fail3.json",
+         "fail4.json",                // extra comma
+         "fail5.json",
diff --git a/debian/patches/020170501~0d3e74d.patch b/debian/patches/020170501~0d3e74d.patch
new file mode 100644
index 0000000..f020332
--- /dev/null
+++ b/debian/patches/020170501~0d3e74d.patch
@@ -0,0 +1,28 @@
+Description: Have operator[] take size_t index parameter (not unsigned int)
+Origin: upstream, https://github.com/jgarzik/univalue/commit/0d3e74d
+Author: kozyilmaz <kazim at monolytic.com>
+Forwarded: yes
+Last-Update: 2017-05-21
+
+--- a/include/univalue.h
++++ b/include/univalue.h
+@@ -71,7 +71,7 @@
+     bool getBool() const { return isTrue(); }
+     bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes);
+     const UniValue& operator[](const std::string& key) const;
+-    const UniValue& operator[](unsigned int index) const;
++    const UniValue& operator[](size_t index) const;
+     bool exists(const std::string& key) const { size_t i; return findKey(key, i); }
+ 
+     bool isNull() const { return (typ == VNULL); }
+--- a/lib/univalue.cpp
++++ b/lib/univalue.cpp
+@@ -251,7 +251,7 @@
+     return values.at(index);
+ }
+ 
+-const UniValue& UniValue::operator[](unsigned int index) const
++const UniValue& UniValue::operator[](size_t index) const
+ {
+     if (typ != VOBJ && typ != VARR)
+         return NullUniValue;
diff --git a/debian/patches/020170501~640158f.patch b/debian/patches/020170501~640158f.patch
new file mode 100644
index 0000000..1c69517
--- /dev/null
+++ b/debian/patches/020170501~640158f.patch
@@ -0,0 +1,71 @@
+Description: Make findKey() size_t clean, and return bool on failure
+Origin: upstream, https://github.com/jgarzik/univalue/commit/640158f
+Author: kozyilmaz <kazim at monolytic.com>
+Forwarded: yes
+Last-Update: 2017-05-21
+
+--- a/include/univalue.h
++++ b/include/univalue.h
+@@ -72,7 +72,7 @@
+     bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes);
+     const UniValue& operator[](const std::string& key) const;
+     const UniValue& operator[](unsigned int index) const;
+-    bool exists(const std::string& key) const { return (findKey(key) >= 0); }
++    bool exists(const std::string& key) const { size_t i; return findKey(key, i); }
+ 
+     bool isNull() const { return (typ == VNULL); }
+     bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
+@@ -148,7 +148,7 @@
+     std::vector<std::string> keys;
+     std::vector<UniValue> values;
+ 
+-    int findKey(const std::string& key) const;
++    bool findKey(const std::string& key, size_t& retIdx) const;
+     void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
+     void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
+ 
+--- a/lib/univalue.cpp
++++ b/lib/univalue.cpp
+@@ -212,22 +212,24 @@
+     return true;
+ }
+ 
+-int UniValue::findKey(const std::string& key) const
++bool UniValue::findKey(const std::string& key, size_t& retIdx) const
+ {
+-    for (unsigned int i = 0; i < keys.size(); i++) {
+-        if (keys[i] == key)
+-            return (int) i;
++    for (size_t i = 0; i < keys.size(); i++) {
++        if (keys[i] == key) {
++            retIdx = i;
++            return true;
++        }
+     }
+ 
+-    return -1;
++    return false;
+ }
+ 
+ bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t)
+ {
+     for (std::map<std::string,UniValue::VType>::const_iterator it = t.begin();
+          it != t.end(); ++it) {
+-        int idx = findKey(it->first);
+-        if (idx < 0)
++        size_t idx = 0;
++        if (!findKey(it->first, idx))
+             return false;
+ 
+         if (values.at(idx).getType() != it->second)
+@@ -242,8 +244,8 @@
+     if (typ != VOBJ)
+         return NullUniValue;
+ 
+-    int index = findKey(key);
+-    if (index < 0)
++    size_t index = 0;
++    if (!findKey(key, index))
+         return NullUniValue;
+ 
+     return values.at(index);
diff --git a/debian/patches/020170502~1dfe464.patch b/debian/patches/020170502~1dfe464.patch
new file mode 100644
index 0000000..28d8344
--- /dev/null
+++ b/debian/patches/020170502~1dfe464.patch
@@ -0,0 +1,397 @@
+Description: Import UniValue class unit tests from bitcoin project
+Origin: upstream, https://github.com/jgarzik/univalue/commit/1dfe464
+Author: Jeff Garzik <jeff at bloq.com>
+Forwarded: yes
+Last-Update: 2017-05-21
+
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -20,7 +20,7 @@
+ 	-no-undefined
+ libunivalue_la_CXXFLAGS = -I$(top_srcdir)/include
+ 
+-TESTS = test/unitester test/no_nul
++TESTS = test/object test/unitester test/no_nul
+ 
+ GENBIN = gen/gen$(BUILD_EXEEXT)
+ GEN_SRCS = gen/gen.cpp
+@@ -52,6 +52,11 @@
+ test_no_nul_CXXFLAGS = -I$(top_srcdir)/include
+ test_no_nul_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS)
+ 
++test_object_SOURCES = test/object.cpp
++test_object_LDADD = libunivalue.la
++test_object_CXXFLAGS = -I$(top_srcdir)/include
++test_object_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS)
++
+ TEST_FILES = \
+ 	$(TEST_DATA_DIR)/fail10.json \
+ 	$(TEST_DATA_DIR)/fail11.json \
+--- /dev/null
++++ b/test/object.cpp
+@@ -0,0 +1,365 @@
++// Copyright (c) 2014 BitPay Inc.
++// Copyright (c) 2014-2016 The Bitcoin Core developers
++// Distributed under the MIT 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 <cassert>
++#include <stdexcept>
++#include <univalue.h>
++
++#define BOOST_FIXTURE_TEST_SUITE(a, b)
++#define BOOST_AUTO_TEST_CASE(funcName) void funcName()
++#define BOOST_AUTO_TEST_SUITE_END()
++#define BOOST_CHECK(expr) assert(expr)
++#define BOOST_CHECK_EQUAL(v1, v2) assert((v1) == (v2))
++#define BOOST_CHECK_THROW(stmt, excMatch) { \
++        try { \
++            (stmt); \
++        } catch (excMatch & e) { \
++	} catch (...) { \
++	    assert(0); \
++	} \
++    }
++#define BOOST_CHECK_NO_THROW(stmt) { \
++        try { \
++            (stmt); \
++	} catch (...) { \
++	    assert(0); \
++	} \
++    }
++
++BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup)
++
++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");
++
++    std::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_typecheck)
++{
++    UniValue v1;
++    BOOST_CHECK(v1.setNumStr("1"));
++    BOOST_CHECK(v1.isNum());
++    BOOST_CHECK_THROW(v1.get_bool(), std::runtime_error);
++
++    UniValue v2;
++    BOOST_CHECK(v2.setBool(true));
++    BOOST_CHECK_EQUAL(v2.get_bool(), true);
++    BOOST_CHECK_THROW(v2.get_int(), std::runtime_error);
++
++    UniValue v3;
++    BOOST_CHECK(v3.setNumStr("32482348723847471234"));
++    BOOST_CHECK_THROW(v3.get_int64(), std::runtime_error);
++    BOOST_CHECK(v3.setNumStr("1000"));
++    BOOST_CHECK_EQUAL(v3.get_int64(), 1000);
++
++    UniValue v4;
++    BOOST_CHECK(v4.setNumStr("2147483648"));
++    BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648);
++    BOOST_CHECK_THROW(v4.get_int(), std::runtime_error);
++    BOOST_CHECK(v4.setNumStr("1000"));
++    BOOST_CHECK_EQUAL(v4.get_int(), 1000);
++    BOOST_CHECK_THROW(v4.get_str(), std::runtime_error);
++    BOOST_CHECK_EQUAL(v4.get_real(), 1000);
++    BOOST_CHECK_THROW(v4.get_array(), std::runtime_error);
++    BOOST_CHECK_THROW(v4.getKeys(), std::runtime_error);
++    BOOST_CHECK_THROW(v4.getValues(), std::runtime_error);
++    BOOST_CHECK_THROW(v4.get_obj(), std::runtime_error);
++
++    UniValue v5;
++    BOOST_CHECK(v5.read("[true, 10]"));
++    BOOST_CHECK_NO_THROW(v5.get_array());
++    std::vector<UniValue> vals = v5.getValues();
++    BOOST_CHECK_THROW(vals[0].get_int(), std::runtime_error);
++    BOOST_CHECK_EQUAL(vals[0].get_bool(), true);
++
++    BOOST_CHECK_EQUAL(vals[1].get_int(), 10);
++    BOOST_CHECK_THROW(vals[1].get_bool(), std::runtime_error);
++}
++
++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.size(), 0);
++    BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ);
++    BOOST_CHECK(v.empty());
++
++    BOOST_CHECK(v.setArray());
++    BOOST_CHECK(v.isArray());
++    BOOST_CHECK_EQUAL(v.size(), 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));
++
++    std::string vStr("zippy");
++    BOOST_CHECK(arr.push_back(vStr));
++
++    const char *s = "pippy";
++    BOOST_CHECK(arr.push_back(s));
++
++    std::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.size(), 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.size(), 0);
++}
++
++BOOST_AUTO_TEST_CASE(univalue_object)
++{
++    UniValue obj(UniValue::VOBJ);
++    std::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.size(), 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"));
++
++    std::map<std::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.size(), 0);
++}
++
++static const char *json1 =
++"[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,\"key3\":{\"name\":\"martian http://test.com\"}}]";
++
++BOOST_AUTO_TEST_CASE(univalue_readwrite)
++{
++    UniValue v;
++    BOOST_CHECK(v.read(json1));
++
++    std::string strJson1(json1);
++    BOOST_CHECK(v.read(strJson1));
++
++    BOOST_CHECK(v.isArray());
++    BOOST_CHECK_EQUAL(v.size(), 2);
++
++    BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000");
++
++    UniValue obj = v[1];
++    BOOST_CHECK(obj.isObject());
++    BOOST_CHECK_EQUAL(obj.size(), 3);
++
++    BOOST_CHECK(obj["key1"].isStr());
++    std::string correctValue("str");
++    correctValue.push_back('\0');
++    BOOST_CHECK_EQUAL(obj["key1"].getValStr(), correctValue);
++    BOOST_CHECK(obj["key2"].isNum());
++    BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800");
++    BOOST_CHECK(obj["key3"].isObject());
++
++    BOOST_CHECK_EQUAL(strJson1, v.write());
++
++    /* Check for (correctly reporting) a parsing error if the initial
++       JSON construct is followed by more stuff.  Note that whitespace
++       is, of course, exempt.  */
++
++    BOOST_CHECK(v.read("  {}\n  "));
++    BOOST_CHECK(v.isObject());
++    BOOST_CHECK(v.read("  []\n  "));
++    BOOST_CHECK(v.isArray());
++
++    BOOST_CHECK(!v.read("@{}"));
++    BOOST_CHECK(!v.read("{} garbage"));
++    BOOST_CHECK(!v.read("[]{}"));
++    BOOST_CHECK(!v.read("{}[]"));
++    BOOST_CHECK(!v.read("{} 42"));
++}
++
++BOOST_AUTO_TEST_SUITE_END()
++
++int main (int argc, char *argv[])
++{
++    univalue_constructor();
++    univalue_typecheck();
++    univalue_set();
++    univalue_array();
++    univalue_object();
++    univalue_readwrite();
++    return 0;
++}
++
diff --git a/debian/patches/020170504~107db98.patch b/debian/patches/020170504~107db98.patch
new file mode 100644
index 0000000..cfc2600
--- /dev/null
+++ b/debian/patches/020170504~107db98.patch
@@ -0,0 +1,47 @@
+Description: Add ::push_back(double) method for feature parity
+ Add tests for this and other push_back()'s.
+Origin: upstream, https://github.com/jgarzik/univalue/commit/107db98
+Author: Jeff Garzik <jeff at bloq.com>
+Forwarded: yes
+Last-Update: 2017-05-21
+
+--- a/include/univalue.h
++++ b/include/univalue.h
+@@ -104,6 +104,10 @@
+         UniValue tmpVal(val_);
+         return push_back(tmpVal);
+     }
++    bool push_back(double val_) {
++        UniValue tmpVal(val_);
++        return push_back(tmpVal);
++    }
+     bool push_backV(const std::vector<UniValue>& vec);
+ 
+     bool pushKV(const std::string& key, const UniValue& val);
+--- a/test/object.cpp
++++ b/test/object.cpp
+@@ -205,14 +205,23 @@
+ 
+     BOOST_CHECK(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_EQUAL(arr.empty(), false);
+-    BOOST_CHECK_EQUAL(arr.size(), 5);
++    BOOST_CHECK_EQUAL(arr.size(), 9);
+ 
+     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[5].getValStr(), "400");
++    BOOST_CHECK_EQUAL(arr[6].getValStr(), "-400");
++    BOOST_CHECK_EQUAL(arr[7].getValStr(), "-401");
++    BOOST_CHECK_EQUAL(arr[8].getValStr(), "-40.1");
+ 
+     BOOST_CHECK_EQUAL(arr[999].getValStr(), "");
+ 
diff --git a/debian/patches/020170504~52e85b3.patch b/debian/patches/020170504~52e85b3.patch
new file mode 100644
index 0000000..f9b02d7
--- /dev/null
+++ b/debian/patches/020170504~52e85b3.patch
@@ -0,0 +1,320 @@
+Description: Move exception-throwing get_* methods to separate module
+Origin: upstream, https://github.com/jgarzik/univalue/commit/52e85b3
+Author: Jeff Garzik <jeff at bloq.com>
+Forwarded: yes
+Last-Update: 2017-05-21
+
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -12,6 +12,7 @@
+ 
+ libunivalue_la_SOURCES = \
+ 	lib/univalue.cpp \
++	lib/univalue_get.cpp \
+ 	lib/univalue_read.cpp \
+ 	lib/univalue_write.cpp
+ 
+--- a/lib/univalue.cpp
++++ b/lib/univalue.cpp
+@@ -4,75 +4,12 @@
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
+ 
+ #include <stdint.h>
+-#include <errno.h>
+ #include <iomanip>
+-#include <limits>
+ #include <sstream>
+-#include <stdexcept>
+ #include <stdlib.h>
+-#include <string.h>
+ 
+ #include "univalue.h"
+ 
+-namespace 
+-{
+-static bool ParsePrechecks(const std::string& str)
+-{
+-    if (str.empty()) // No empty string allowed
+-        return false;
+-    if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
+-        return false;
+-    if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
+-        return false;
+-    return true;
+-}
+-
+-bool ParseInt32(const std::string& str, int32_t *out)
+-{
+-    if (!ParsePrechecks(str))
+-        return false;
+-    char *endp = NULL;
+-    errno = 0; // strtol will not set errno if valid
+-    long int n = strtol(str.c_str(), &endp, 10);
+-    if(out) *out = (int32_t)n;
+-    // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
+-    // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
+-    // platforms the size of these types may be different.
+-    return endp && *endp == 0 && !errno &&
+-        n >= std::numeric_limits<int32_t>::min() &&
+-        n <= std::numeric_limits<int32_t>::max();
+-}
+-
+-bool ParseInt64(const std::string& str, int64_t *out)
+-{
+-    if (!ParsePrechecks(str))
+-        return false;
+-    char *endp = NULL;
+-    errno = 0; // strtoll will not set errno if valid
+-    long long int n = strtoll(str.c_str(), &endp, 10);
+-    if(out) *out = (int64_t)n;
+-    // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
+-    // we still have to check that the returned value is within the range of an *int64_t*.
+-    return endp && *endp == 0 && !errno &&
+-        n >= std::numeric_limits<int64_t>::min() &&
+-        n <= std::numeric_limits<int64_t>::max();
+-}
+-
+-bool ParseDouble(const std::string& str, double *out)
+-{
+-    if (!ParsePrechecks(str))
+-        return false;
+-    if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
+-        return false;
+-    std::istringstream text(str);
+-    text.imbue(std::locale::classic());
+-    double result;
+-    text >> result;
+-    if(out) *out = result;
+-    return text.eof() && !text.fail();
+-}
+-}
+-
+ using namespace std;
+ 
+ const UniValue NullUniValue;
+@@ -285,75 +222,3 @@
+     return NullUniValue;
+ }
+ 
+-const std::vector<std::string>& UniValue::getKeys() const
+-{
+-    if (typ != VOBJ)
+-        throw std::runtime_error("JSON value is not an object as expected");
+-    return keys;
+-}
+-
+-const std::vector<UniValue>& UniValue::getValues() const
+-{
+-    if (typ != VOBJ && typ != VARR)
+-        throw std::runtime_error("JSON value is not an object or array as expected");
+-    return values;
+-}
+-
+-bool UniValue::get_bool() const
+-{
+-    if (typ != VBOOL)
+-        throw std::runtime_error("JSON value is not a boolean as expected");
+-    return getBool();
+-}
+-
+-const std::string& UniValue::get_str() const
+-{
+-    if (typ != VSTR)
+-        throw std::runtime_error("JSON value is not a string as expected");
+-    return getValStr();
+-}
+-
+-int UniValue::get_int() const
+-{
+-    if (typ != VNUM)
+-        throw std::runtime_error("JSON value is not an integer as expected");
+-    int32_t retval;
+-    if (!ParseInt32(getValStr(), &retval))
+-        throw std::runtime_error("JSON integer out of range");
+-    return retval;
+-}
+-
+-int64_t UniValue::get_int64() const
+-{
+-    if (typ != VNUM)
+-        throw std::runtime_error("JSON value is not an integer as expected");
+-    int64_t retval;
+-    if (!ParseInt64(getValStr(), &retval))
+-        throw std::runtime_error("JSON integer out of range");
+-    return retval;
+-}
+-
+-double UniValue::get_real() const
+-{
+-    if (typ != VNUM)
+-        throw std::runtime_error("JSON value is not a number as expected");
+-    double retval;
+-    if (!ParseDouble(getValStr(), &retval))
+-        throw std::runtime_error("JSON double out of range");
+-    return retval;
+-}
+-
+-const UniValue& UniValue::get_obj() const
+-{
+-    if (typ != VOBJ)
+-        throw std::runtime_error("JSON value is not an object as expected");
+-    return *this;
+-}
+-
+-const UniValue& UniValue::get_array() const
+-{
+-    if (typ != VARR)
+-        throw std::runtime_error("JSON value is not an array as expected");
+-    return *this;
+-}
+-
+--- /dev/null
++++ b/lib/univalue_get.cpp
+@@ -0,0 +1,147 @@
++// Copyright 2014 BitPay Inc.
++// Copyright 2015 Bitcoin Core Developers
++// Distributed under the MIT software license, see the accompanying
++// file COPYING or http://www.opensource.org/licenses/mit-license.php.
++
++#include <stdint.h>
++#include <errno.h>
++#include <string.h>
++#include <stdlib.h>
++#include <stdexcept>
++#include <vector>
++#include <limits>
++#include <string>
++
++#include "univalue.h"
++
++namespace
++{
++static bool ParsePrechecks(const std::string& str)
++{
++    if (str.empty()) // No empty string allowed
++        return false;
++    if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
++        return false;
++    if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
++        return false;
++    return true;
++}
++
++bool ParseInt32(const std::string& str, int32_t *out)
++{
++    if (!ParsePrechecks(str))
++        return false;
++    char *endp = NULL;
++    errno = 0; // strtol will not set errno if valid
++    long int n = strtol(str.c_str(), &endp, 10);
++    if(out) *out = (int32_t)n;
++    // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
++    // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
++    // platforms the size of these types may be different.
++    return endp && *endp == 0 && !errno &&
++        n >= std::numeric_limits<int32_t>::min() &&
++        n <= std::numeric_limits<int32_t>::max();
++}
++
++bool ParseInt64(const std::string& str, int64_t *out)
++{
++    if (!ParsePrechecks(str))
++        return false;
++    char *endp = NULL;
++    errno = 0; // strtoll will not set errno if valid
++    long long int n = strtoll(str.c_str(), &endp, 10);
++    if(out) *out = (int64_t)n;
++    // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
++    // we still have to check that the returned value is within the range of an *int64_t*.
++    return endp && *endp == 0 && !errno &&
++        n >= std::numeric_limits<int64_t>::min() &&
++        n <= std::numeric_limits<int64_t>::max();
++}
++
++bool ParseDouble(const std::string& str, double *out)
++{
++    if (!ParsePrechecks(str))
++        return false;
++    if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
++        return false;
++    std::istringstream text(str);
++    text.imbue(std::locale::classic());
++    double result;
++    text >> result;
++    if(out) *out = result;
++    return text.eof() && !text.fail();
++}
++}
++
++const std::vector<std::string>& UniValue::getKeys() const
++{
++    if (typ != VOBJ)
++        throw std::runtime_error("JSON value is not an object as expected");
++    return keys;
++}
++
++const std::vector<UniValue>& UniValue::getValues() const
++{
++    if (typ != VOBJ && typ != VARR)
++        throw std::runtime_error("JSON value is not an object or array as expected");
++    return values;
++}
++
++bool UniValue::get_bool() const
++{
++    if (typ != VBOOL)
++        throw std::runtime_error("JSON value is not a boolean as expected");
++    return getBool();
++}
++
++const std::string& UniValue::get_str() const
++{
++    if (typ != VSTR)
++        throw std::runtime_error("JSON value is not a string as expected");
++    return getValStr();
++}
++
++int UniValue::get_int() const
++{
++    if (typ != VNUM)
++        throw std::runtime_error("JSON value is not an integer as expected");
++    int32_t retval;
++    if (!ParseInt32(getValStr(), &retval))
++        throw std::runtime_error("JSON integer out of range");
++    return retval;
++}
++
++int64_t UniValue::get_int64() const
++{
++    if (typ != VNUM)
++        throw std::runtime_error("JSON value is not an integer as expected");
++    int64_t retval;
++    if (!ParseInt64(getValStr(), &retval))
++        throw std::runtime_error("JSON integer out of range");
++    return retval;
++}
++
++double UniValue::get_real() const
++{
++    if (typ != VNUM)
++        throw std::runtime_error("JSON value is not a number as expected");
++    double retval;
++    if (!ParseDouble(getValStr(), &retval))
++        throw std::runtime_error("JSON double out of range");
++    return retval;
++}
++
++const UniValue& UniValue::get_obj() const
++{
++    if (typ != VOBJ)
++        throw std::runtime_error("JSON value is not an object as expected");
++    return *this;
++}
++
++const UniValue& UniValue::get_array() const
++{
++    if (typ != VARR)
++        throw std::runtime_error("JSON value is not an array as expected");
++    return *this;
++}
++
diff --git a/debian/patches/020170504~d415300.patch b/debian/patches/020170504~d415300.patch
new file mode 100644
index 0000000..b045c0a
--- /dev/null
+++ b/debian/patches/020170504~d415300.patch
@@ -0,0 +1,34 @@
+Description: Move one-line implementation of UniValue::read() to header
+Origin: upstream, https://github.com/jgarzik/univalue/commit/d415300
+Author: Jeff Garzik <jeff at bloq.com>
+Forwarded: yes
+Last-Update: 2017-05-21
+
+--- a/include/univalue.h
++++ b/include/univalue.h
+@@ -7,6 +7,7 @@
+ #define __UNIVALUE_H__
+ 
+ #include <stdint.h>
++#include <string.h>
+ 
+ #include <string>
+ #include <vector>
+@@ -141,7 +142,7 @@
+                       unsigned int indentLevel = 0) const;
+ 
+     bool read(const char *raw, size_t len);
+-    bool read(const char *raw);
++    bool read(const char *raw) { return read(raw, strlen(raw)); }
+     bool read(const std::string& rawStr) {
+         return read(rawStr.data(), rawStr.size());
+     }
+--- a/lib/univalue_read.cpp
++++ b/lib/univalue_read.cpp
+@@ -449,6 +449,3 @@
+     return true;
+ }
+ 
+-bool UniValue::read(const char *raw) {
+-    return read(raw, strlen(raw));
+-}
diff --git a/debian/patches/README b/debian/patches/README
new file mode 100644
index 0000000..80c1584
--- /dev/null
+++ b/debian/patches/README
@@ -0,0 +1,3 @@
+0xxx: Grabbed from upstream development.
+1xxx: Possibly relevant for upstream adoption.
+2xxx: Only relevant for official Debian release.
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..1cb69cf
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,7 @@
+020161101~4fd5444.patch
+020170501~640158f.patch
+020170501~0d3e74d.patch
+020170502~1dfe464.patch
+020170504~107db98.patch
+020170504~52e85b3.patch
+020170504~d415300.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-bitcoin/libunivalue.git



More information about the Pkg-bitcoin-commits mailing list