common: handle negative unsigneds in config
refs #4489
Change-Id: Ibeab0aad9ac95bef1ef2f17178b795cde4a79fea
diff --git a/daemon/common/config-file.hpp b/daemon/common/config-file.hpp
index 20e778b..09ac1a2 100644
--- a/daemon/common/config-file.hpp
+++ b/daemon/common/config-file.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2019, Regents of the University of California,
+ * Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -108,7 +108,9 @@
static_assert(std::is_arithmetic<T>::value, "T must be an arithmetic type");
boost::optional<T> value = node.get_value_optional<T>();
- if (value) {
+ // Unsigned logic is workaround for https://redmine.named-data.net/issues/4489
+ if (value &&
+ (std::is_signed<T>() || node.get_value<std::string>().find("-") == std::string::npos)) {
return *value;
}
NDN_THROW(Error("Invalid value '" + node.get_value<std::string>() +
diff --git a/tests/daemon/common/config-file.t.cpp b/tests/daemon/common/config-file.t.cpp
index 8eae4fb..2a2cff4 100644
--- a/tests/daemon/common/config-file.t.cpp
+++ b/tests/daemon/common/config-file.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2019, Regents of the University of California,
+ * Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -325,6 +325,56 @@
BOOST_CHECK(subB.allCallbacksFired());
}
+BOOST_AUTO_TEST_CASE(ParseNumber)
+{
+ std::istringstream input(R"CONFIG(
+ a -125
+ b 156
+ c 100000
+ d efg
+ e 123.456e-10
+ f 123abc
+ g ""
+ h " -1"
+ )CONFIG");
+ ConfigSection section;
+ boost::property_tree::read_info(input, section);
+
+ // Read various types and ensure they return the correct value
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<short>(section.get_child("a"), "a", "section"), -125);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<int>(section.get_child("a"), "a", "section"), -125);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<long>(section.get_child("a"), "a", "section"), -125);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<double>(section.get_child("a"), "a", "section"), -125.0);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<float>(section.get_child("a"), "a", "section"), -125.0);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<short>(section.get_child("b"), "b", "section"), 156);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<int>(section.get_child("b"), "b", "section"), 156);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<long>(section.get_child("b"), "b", "section"), 156);
+ BOOST_CHECK_CLOSE(ConfigFile::parseNumber<double>(section.get_child("e"), "e", "section"), 123.456e-10, 0.0001);
+ BOOST_CHECK_CLOSE(ConfigFile::parseNumber<float>(section.get_child("e"), "e", "section"), 123.456e-10, 0.0001);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<int>(section.get_child("h"), "h", "section"), -1);
+
+ // Check throw on out of range
+ BOOST_CHECK_THROW(ConfigFile::parseNumber<int16_t>(section.get_child("c"), "c", "section"),
+ ConfigFile::Error);
+
+ // Check throw on non-integer for integer types
+ BOOST_CHECK_THROW(ConfigFile::parseNumber<int>(section.get_child("d"), "d", "section"),
+ ConfigFile::Error);
+ BOOST_CHECK_THROW(ConfigFile::parseNumber<int>(section.get_child("e"), "e", "section"),
+ ConfigFile::Error);
+ BOOST_CHECK_THROW(ConfigFile::parseNumber<int>(section.get_child("f"), "f", "section"),
+ ConfigFile::Error);
+ BOOST_CHECK_THROW(ConfigFile::parseNumber<int>(section.get_child("g"), "g", "section"),
+ ConfigFile::Error);
+
+ // Should throw exception if try to read unsigned from negative value
+ BOOST_CHECK_THROW(ConfigFile::parseNumber<uint16_t>(section.get_child("a"), "a", "section"),
+ ConfigFile::Error);
+ BOOST_CHECK_EQUAL(ConfigFile::parseNumber<uint16_t>(section.get_child("b"), "b", "section"), 156);
+ BOOST_CHECK_THROW(ConfigFile::parseNumber<uint32_t>(section.get_child("h"), "h", "section"),
+ ConfigFile::Error);
+}
+
BOOST_AUTO_TEST_SUITE_END() // TestConfigFile
} // namespace tests
diff --git a/tests/daemon/face/ethernet-factory.t.cpp b/tests/daemon/face/ethernet-factory.t.cpp
index e204cee..605d3e2 100644
--- a/tests/daemon/face/ethernet-factory.t.cpp
+++ b/tests/daemon/face/ethernet-factory.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2019, Regents of the University of California,
+ * Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -334,7 +334,6 @@
BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
}
-BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(BadIdleTimeout, 2) // Bug #4489
BOOST_AUTO_TEST_CASE(BadIdleTimeout)
{
// not a number
diff --git a/tests/daemon/face/tcp-factory.t.cpp b/tests/daemon/face/tcp-factory.t.cpp
index 3c00134..95e6c2b 100644
--- a/tests/daemon/face/tcp-factory.t.cpp
+++ b/tests/daemon/face/tcp-factory.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2019, Regents of the University of California,
+ * Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -267,7 +267,6 @@
BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
}
-BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(BadPort, 2) // Bug #4489
BOOST_AUTO_TEST_CASE(BadPort)
{
// not a number
diff --git a/tests/daemon/face/udp-factory.t.cpp b/tests/daemon/face/udp-factory.t.cpp
index 0c10276..c09fe62 100644
--- a/tests/daemon/face/udp-factory.t.cpp
+++ b/tests/daemon/face/udp-factory.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2019, Regents of the University of California,
+ * Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -579,7 +579,6 @@
BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
}
-BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(BadPort, 2) // Bug #4489
BOOST_AUTO_TEST_CASE(BadPort)
{
// not a number
@@ -625,7 +624,6 @@
BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
}
-BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(BadIdleTimeout, 2) // Bug #4489
BOOST_AUTO_TEST_CASE(BadIdleTimeout)
{
// not a number
diff --git a/tests/daemon/face/websocket-factory.t.cpp b/tests/daemon/face/websocket-factory.t.cpp
index 1234737..b684cee 100644
--- a/tests/daemon/face/websocket-factory.t.cpp
+++ b/tests/daemon/face/websocket-factory.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -203,7 +203,6 @@
BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
}
-BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(BadPort, 2) // Bug #4489
BOOST_AUTO_TEST_CASE(BadPort)
{
// not a number