Commit e17c6b08278da073693fa2c1cc2297953fe978b9

Authored by Jarryd Beck
1 parent 3e5ecf1d

Fix integer parsing again

include/cxxopts.hpp
@@ -29,6 +29,7 @@ THE SOFTWARE. @@ -29,6 +29,7 @@ THE SOFTWARE.
29 #include <cctype> 29 #include <cctype>
30 #include <exception> 30 #include <exception>
31 #include <iostream> 31 #include <iostream>
  32 +#include <limits>
32 #include <map> 33 #include <map>
33 #include <memory> 34 #include <memory>
34 #include <regex> 35 #include <regex>
@@ -485,7 +486,7 @@ namespace cxxopts @@ -485,7 +486,7 @@ namespace cxxopts
485 { 486 {
486 if (negative) 487 if (negative)
487 { 488 {
488 - if (u > -static_cast<U>((std::numeric_limits<T>::min)())) 489 + if (u > static_cast<U>((std::numeric_limits<T>::min)()))
489 { 490 {
490 throw argument_incorrect_type(text); 491 throw argument_incorrect_type(text);
491 } 492 }
@@ -583,12 +584,13 @@ namespace cxxopts @@ -583,12 +584,13 @@ namespace cxxopts
583 throw argument_incorrect_type(text); 584 throw argument_incorrect_type(text);
584 } 585 }
585 586
586 - if (umax - digit < result * base) 587 + US next = result * base + digit;
  588 + if (result > next)
587 { 589 {
588 throw argument_incorrect_type(text); 590 throw argument_incorrect_type(text);
589 } 591 }
590 592
591 - result = result * base + digit; 593 + result = next;
592 } 594 }
593 595
594 detail::check_signed_range<T>(negative, result, text); 596 detail::check_signed_range<T>(negative, result, text);
test/options.cpp
@@ -408,6 +408,8 @@ TEST_CASE(&quot;Overflow on boundary&quot;, &quot;[integer]&quot;) @@ -408,6 +408,8 @@ TEST_CASE(&quot;Overflow on boundary&quot;, &quot;[integer]&quot;)
408 408
409 TEST_CASE("Integer overflow", "[options]") 409 TEST_CASE("Integer overflow", "[options]")
410 { 410 {
  411 + using namespace cxxopts::values;
  412 +
411 cxxopts::Options options("reject_overflow", "rejects overflowing integers"); 413 cxxopts::Options options("reject_overflow", "rejects overflowing integers");
412 options.add_options() 414 options.add_options()
413 ("positional", "Integers", cxxopts::value<std::vector<int8_t>>()); 415 ("positional", "Integers", cxxopts::value<std::vector<int8_t>>());
@@ -419,6 +421,10 @@ TEST_CASE(&quot;Integer overflow&quot;, &quot;[options]&quot;) @@ -419,6 +421,10 @@ TEST_CASE(&quot;Integer overflow&quot;, &quot;[options]&quot;)
419 421
420 options.parse_positional("positional"); 422 options.parse_positional("positional");
421 CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type&); 423 CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type&);
  424 +
  425 + int integer = 0;
  426 + CHECK_THROWS_AS((integer_parser("23423423423", integer)), cxxopts::argument_incorrect_type&);
  427 + CHECK_THROWS_AS((integer_parser("234234234234", integer)), cxxopts::argument_incorrect_type&);
422 } 428 }
423 429
424 TEST_CASE("Floats", "[options]") 430 TEST_CASE("Floats", "[options]")