[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