Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/jarro2783/cxxopts.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevCodeOne <christian.r.dev@googlemail.com>2017-11-02 00:14:21 +0300
committerjarro2783 <jarro.2783@gmail.com>2017-11-02 00:14:21 +0300
commitd7b930846cdccfc8bcecc4d7150ddcbadffac360 (patch)
treeb44c6eaa876358fca535018bf67c05e10728cd64
parent8ce9a587fa280cddb433c20d52253d8eefecceb0 (diff)
Fix some strange issues in integer_parser (#80)v1.4.4
* Prevent malformed numbers from being parsed as correct numbers. Fixes #78. If you passed a string for example "test" it would get parsed to 1400. The problem was that the parser did not throw an exception when an incorrect char was encountered. Also a number without 0x in front with hexadecimal digits in it got parsed. The number was treated as a hexadecimal number but it was still calculated with base 10. So now before the current char is used, it is checked if it is valid in the current base. Furthermore the number 0x0 was not a valid number, it now is a special case in the `integer_pattern`. * Fixed `integer_pattern` so it works correctly under clang. Added testcase for invalid integers and for 0x0 being a valid number.
-rw-r--r--include/cxxopts.hpp10
-rw-r--r--test/options.cpp18
2 files changed, 23 insertions, 5 deletions
diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp
index e0509e8..17bb590 100644
--- a/include/cxxopts.hpp
+++ b/include/cxxopts.hpp
@@ -431,7 +431,7 @@ namespace cxxopts
namespace
{
std::basic_regex<char> integer_pattern
- ("(-)?(0x)?([1-9a-zA-Z][0-9a-zA-Z]*)|(0)");
+ ("(-)?(0x)?([1-9a-zA-Z][0-9a-zA-Z]*)|((0x)?0)");
}
namespace detail
@@ -533,14 +533,18 @@ namespace cxxopts
{
digit = *iter - '0';
}
- else if (*iter >= 'a' && *iter <= 'f')
+ else if (base == 16 && *iter >= 'a' && *iter <= 'f')
{
digit = *iter - 'a' + 10;
}
- else if (*iter >= 'A' && *iter <= 'F')
+ else if (base == 16 && *iter >= 'A' && *iter <= 'F')
{
digit = *iter - 'A' + 10;
}
+ else
+ {
+ throw argument_incorrect_type(text);
+ }
if (umax - digit < result * base)
{
diff --git a/test/options.cpp b/test/options.cpp
index 1446929..d428f9a 100644
--- a/test/options.cpp
+++ b/test/options.cpp
@@ -246,7 +246,7 @@ TEST_CASE("Integers", "[options]")
options.add_options()
("positional", "Integers", cxxopts::value<std::vector<int>>());
- Argv av({"ints", "--", "5", "6", "-6", "0", "0xab", "0xAf"});
+ Argv av({"ints", "--", "5", "6", "-6", "0", "0xab", "0xAf", "0x0"});
char** argv = av.argv();
auto argc = av.argc();
@@ -254,7 +254,7 @@ TEST_CASE("Integers", "[options]")
options.parse_positional("positional");
options.parse(argc, argv);
- REQUIRE(options.count("positional") == 6);
+ REQUIRE(options.count("positional") == 7);
auto& positional = options["positional"].as<std::vector<int>>();
CHECK(positional[0] == 5);
@@ -263,6 +263,7 @@ TEST_CASE("Integers", "[options]")
CHECK(positional[3] == 0);
CHECK(positional[4] == 0xab);
CHECK(positional[5] == 0xaf);
+ CHECK(positional[6] == 0x0);
}
TEST_CASE("Unsigned integers", "[options]")
@@ -364,3 +365,16 @@ TEST_CASE("Floats", "[options]")
CHECK(positional[3] == -1.5e6);
}
+TEST_CASE("Invalid integers", "[integer]") {
+ cxxopts::Options options("invalid_integers", "rejects invalid integers");
+ options.add_options()
+ ("positional", "Integers", cxxopts::value<std::vector<int>>());
+
+ Argv av({"ints", "--", "Ae"});
+
+ char **argv = av.argv();
+ auto argc = av.argc();
+
+ options.parse_positional("positional");
+ CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type);
+}