Commit ca9a12872010732b91ab928230c488c9b3c1ba0b
Committed by
GitHub
1 parent
8f8344bf
test for out of bounds long long (#807)
* test for out of bounds long long * style: pre-commit.ci fixes * change to use std types * style: pre-commit.ci fixes Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Showing
3 changed files
with
114 additions
and
1 deletions
include/CLI/TypeTools.hpp
| ... | ... | @@ -816,11 +816,15 @@ inline std::string type_name() { |
| 816 | 816 | /// Convert to an unsigned integral |
| 817 | 817 | template <typename T, enable_if_t<std::is_unsigned<T>::value, detail::enabler> = detail::dummy> |
| 818 | 818 | bool integral_conversion(const std::string &input, T &output) noexcept { |
| 819 | - if(input.empty()) { | |
| 819 | + if(input.empty() || input.front() == '-') { | |
| 820 | 820 | return false; |
| 821 | 821 | } |
| 822 | 822 | char *val = nullptr; |
| 823 | + errno = 0; | |
| 823 | 824 | std::uint64_t output_ll = std::strtoull(input.c_str(), &val, 0); |
| 825 | + if(errno == ERANGE) { | |
| 826 | + return false; | |
| 827 | + } | |
| 824 | 828 | output = static_cast<T>(output_ll); |
| 825 | 829 | if(val == (input.c_str() + input.size()) && static_cast<std::uint64_t>(output) == output_ll) { |
| 826 | 830 | return true; |
| ... | ... | @@ -841,7 +845,11 @@ bool integral_conversion(const std::string &input, T &output) noexcept { |
| 841 | 845 | return false; |
| 842 | 846 | } |
| 843 | 847 | char *val = nullptr; |
| 848 | + errno = 0; | |
| 844 | 849 | std::int64_t output_ll = std::strtoll(input.c_str(), &val, 0); |
| 850 | + if(errno == ERANGE) { | |
| 851 | + return false; | |
| 852 | + } | |
| 845 | 853 | output = static_cast<T>(output_ll); |
| 846 | 854 | if(val == (input.c_str() + input.size()) && static_cast<std::int64_t>(output) == output_ll) { |
| 847 | 855 | return true; | ... | ... |
tests/AppTest.cpp
| ... | ... | @@ -1995,6 +1995,31 @@ TEST_CASE_METHOD(TApp, "typeCheck", "[app]") { |
| 1995 | 1995 | CHECK_THROWS_AS(run(), CLI::ValidationError); |
| 1996 | 1996 | } |
| 1997 | 1997 | |
| 1998 | +TEST_CASE_METHOD(TApp, "NeedsTrue", "[app]") { | |
| 1999 | + std::string str; | |
| 2000 | + app.add_option("-s,--string", str); | |
| 2001 | + app.add_flag("--opt1")->check([&](const std::string &) { | |
| 2002 | + return (str != "val_with_opt1") ? std::string("--opt1 requires --string val_with_opt1") : std::string{}; | |
| 2003 | + }); | |
| 2004 | + | |
| 2005 | + run(); | |
| 2006 | + | |
| 2007 | + args = {"--opt1"}; | |
| 2008 | + CHECK_THROWS_AS(run(), CLI::ValidationError); | |
| 2009 | + | |
| 2010 | + args = {"--string", "val"}; | |
| 2011 | + run(); | |
| 2012 | + | |
| 2013 | + args = {"--string", "val", "--opt1"}; | |
| 2014 | + CHECK_THROWS_AS(run(), CLI::ValidationError); | |
| 2015 | + | |
| 2016 | + args = {"--string", "val_with_opt1", "--opt1"}; | |
| 2017 | + run(); | |
| 2018 | + | |
| 2019 | + args = {"--opt1", "--string", "val_with_opt1"}; // order is not revelant | |
| 2020 | + run(); | |
| 2021 | +} | |
| 2022 | + | |
| 1998 | 2023 | // Check to make sure programmatic access to left over is available |
| 1999 | 2024 | TEST_CASE_METHOD(TApp, "AllowExtras", "[app]") { |
| 2000 | 2025 | ... | ... |
tests/OptionTypeTest.cpp
| ... | ... | @@ -405,6 +405,86 @@ TEST_CASE_METHOD(TApp, "VectorIndexedValidator", "[optiontype]") { |
| 405 | 405 | CHECK_THROWS_AS(run(), CLI::ValidationError); |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | +TEST_CASE_METHOD(TApp, "IntegerOverFlowShort", "[optiontype]") { | |
| 409 | + std::int16_t A{0}; | |
| 410 | + std::uint16_t B{0}; | |
| 411 | + | |
| 412 | + app.add_option("-a", A); | |
| 413 | + app.add_option("-b", B); | |
| 414 | + | |
| 415 | + args = {"-a", "2626254242"}; | |
| 416 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 417 | + | |
| 418 | + args = {"-b", "2626254242"}; | |
| 419 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 420 | + | |
| 421 | + args = {"-b", "-26262"}; | |
| 422 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 423 | + | |
| 424 | + args = {"-b", "-262624262525"}; | |
| 425 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 426 | +} | |
| 427 | + | |
| 428 | +TEST_CASE_METHOD(TApp, "IntegerOverFlowInt", "[optiontype]") { | |
| 429 | + int A{0}; | |
| 430 | + unsigned int B{0}; | |
| 431 | + | |
| 432 | + app.add_option("-a", A); | |
| 433 | + app.add_option("-b", B); | |
| 434 | + | |
| 435 | + args = {"-a", "262625424225252"}; | |
| 436 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 437 | + | |
| 438 | + args = {"-b", "262625424225252"}; | |
| 439 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 440 | + | |
| 441 | + args = {"-b", "-2626225252"}; | |
| 442 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 443 | + | |
| 444 | + args = {"-b", "-26262426252525252"}; | |
| 445 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 446 | +} | |
| 447 | + | |
| 448 | +TEST_CASE_METHOD(TApp, "IntegerOverFlowLong", "[optiontype]") { | |
| 449 | + std::int32_t A{0}; | |
| 450 | + std::uint32_t B{0}; | |
| 451 | + | |
| 452 | + app.add_option("-a", A); | |
| 453 | + app.add_option("-b", B); | |
| 454 | + | |
| 455 | + args = {"-a", "1111111111111111111111111111"}; | |
| 456 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 457 | + | |
| 458 | + args = {"-b", "1111111111111111111111111111"}; | |
| 459 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 460 | + | |
| 461 | + args = {"-b", "-2626225252"}; | |
| 462 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 463 | + | |
| 464 | + args = {"-b", "-111111111111111111111111"}; | |
| 465 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 466 | +} | |
| 467 | + | |
| 468 | +TEST_CASE_METHOD(TApp, "IntegerOverFlowLongLong", "[optiontype]") { | |
| 469 | + std::int64_t A{0}; | |
| 470 | + std::uint64_t B{0}; | |
| 471 | + | |
| 472 | + app.add_option("-a", A); | |
| 473 | + app.add_option("-b", B); | |
| 474 | + | |
| 475 | + args = {"-a", "1111111111111111111111111111111111111111111111111111111111"}; | |
| 476 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 477 | + | |
| 478 | + args = {"-b", "1111111111111111111111111111111111111111111111111111111111"}; | |
| 479 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 480 | + | |
| 481 | + args = {"-b", "-2626225252"}; | |
| 482 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 483 | + | |
| 484 | + args = {"-b", "-111111111111111111111111111111111111111111111111111111111"}; | |
| 485 | + CHECK_THROWS_AS(run(), CLI::ConversionError); | |
| 486 | +} | |
| 487 | + | |
| 408 | 488 | TEST_CASE_METHOD(TApp, "VectorUnlimString", "[optiontype]") { |
| 409 | 489 | std::vector<std::string> strvec; |
| 410 | 490 | std::vector<std::string> answer{"mystring", "mystring2", "mystring3"}; | ... | ... |