Skip to content

Reject negative input and partial parsing for unsigned argument types#135

Merged
Taywee merged 2 commits intoTaywee:masterfrom
metsw24-max:unsigned-parsing-validation
Apr 20, 2026
Merged

Reject negative input and partial parsing for unsigned argument types#135
Taywee merged 2 commits intoTaywee:masterfrom
metsw24-max:unsigned-parsing-validation

Conversation

@metsw24-max
Copy link
Copy Markdown
Contributor

This patch fixes a parsing flaw in ValueReader where invalid numeric input could be silently accepted.

Issues addressed:

  1. Negative values for unsigned types:
    Inputs such as "-1" were previously accepted and converted via
    wraparound (e.g., to UINT_MAX), which can bypass validation logic
    in downstream applications.

  2. Partial numeric parsing:
    Inputs like "123abc" were partially parsed as 123 and accepted,
    ignoring trailing invalid characters.

Fix:

  • Reject negative values for unsigned integral destinations
  • Require full-string consumption during numeric parsing

@Taywee
Copy link
Copy Markdown
Owner

Taywee commented Apr 18, 2026

Feels a bit hacky, but that's the best you can really get when you're working with C++ iostreams.

Unfortunately, this does cause other unrelated tests to start failing:

taylor@project-zeus> make runtests
g++ test.cxx -o test.o -I. -std=c++11 -O0 -c -MMD -Wall -Wextra -Wno-unused-parameter -Werror -pedantic
g++ -o argstest test.o -std=c++11 -O0
./argstest

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
argstest is a Catch v2.13.7 host application.
Run with -? for options

-------------------------------------------------------------------------------
Argument flags work as expected, with clustering
-------------------------------------------------------------------------------
test.cxx:67
...............................................................................

test.cxx:67: FAILED:
due to unexpected exception with message:
  Argument 'BAZ' received invalid value type '7.555e2'

-------------------------------------------------------------------------------
Unified argument lists for match work
-------------------------------------------------------------------------------
test.cxx:93
...............................................................................

test.cxx:93: FAILED:
due to unexpected exception with message:
  Argument 'BAZ' received invalid value type '7.555e2'

-------------------------------------------------------------------------------
Argument flag lists work as expected
-------------------------------------------------------------------------------
test.cxx:142
...............................................................................

test.cxx:142: FAILED:
due to unexpected exception with message:
  Argument 'FOO' received invalid value type '7'

-------------------------------------------------------------------------------
Argument flag lists replace default values
-------------------------------------------------------------------------------
test.cxx:158
...............................................................................

test.cxx:158: FAILED:
due to unexpected exception with message:
  Argument 'FOO' received invalid value type '7'

-------------------------------------------------------------------------------
Positional lists work as expected
-------------------------------------------------------------------------------
test.cxx:166
...............................................................................

test.cxx:166: FAILED:
due to unexpected exception with message:
  Argument 'FOO' received invalid value type '7'

-------------------------------------------------------------------------------
Positional lists replace default values
-------------------------------------------------------------------------------
test.cxx:182
...............................................................................

test.cxx:182: FAILED:
due to unexpected exception with message:
  Argument 'FOO' received invalid value type '7'

-------------------------------------------------------------------------------
Positional arguments and positional argument lists work as expected
-------------------------------------------------------------------------------
test.cxx:200
...............................................................................

test.cxx:200: FAILED:
due to unexpected exception with message:
  Argument 'BAR' received invalid value type '0'

-------------------------------------------------------------------------------
The option terminator works as expected
-------------------------------------------------------------------------------
test.cxx:215
...............................................................................

test.cxx:215: FAILED:
due to unexpected exception with message:
  Argument 'BAR' received invalid value type '0'

-------------------------------------------------------------------------------
Custom types work
-------------------------------------------------------------------------------
test.cxx:355
...............................................................................

test.cxx:361: FAILED:
  {Unknown expression after the reported line}
due to unexpected exception with message:
  Argument 'INTS' received invalid value type '1,2'

-------------------------------------------------------------------------------
Custom parser prefixes (dd-style)
-------------------------------------------------------------------------------
test.cxx:373
...............................................................................

test.cxx:373: FAILED:
due to unexpected exception with message:
  Argument 'BYTES' received invalid value type '8'

-------------------------------------------------------------------------------
Custom parser prefixes (Some Windows styles)
-------------------------------------------------------------------------------
test.cxx:393
...............................................................................

test.cxx:393: FAILED:
due to unexpected exception with message:
  Argument 'BYTES' received invalid value type '8'

-------------------------------------------------------------------------------
Help menu can be grabbed as a string, passed into a stream, or by using the
overloaded stream operator
-------------------------------------------------------------------------------
test.cxx:413
...............................................................................

test.cxx:413: FAILED:
due to unexpected exception with message:
  Argument 'BYTES' received invalid value type '8'

-------------------------------------------------------------------------------
Required flags work as expected
-------------------------------------------------------------------------------
test.cxx:623
...............................................................................

test.cxx:623: FAILED:
due to unexpected exception with message:
  Argument 'foo' received invalid value type '42'

-------------------------------------------------------------------------------
Implicit values work as expected
-------------------------------------------------------------------------------
test.cxx:663
...............................................................................

test.cxx:671: FAILED:
  REQUIRE_NOTHROW( parser.ParseArgs(std::vector<std::string>{"-j4"}) )
due to unexpected exception with message:
  Argument 'parallel' received invalid value type '4'

-------------------------------------------------------------------------------
Nargs work as expected
-------------------------------------------------------------------------------
test.cxx:686
...............................................................................

test.cxx:697: FAILED:
  REQUIRE_NOTHROW( parser.ParseArgs(std::vector<std::string>{"-a", "1", "2"}) )
due to unexpected exception with message:
  Argument '' received invalid value type '1'

-------------------------------------------------------------------------------
ValueParser works as expected
-------------------------------------------------------------------------------
test.cxx:1197
...............................................................................

test.cxx:1217: FAILED:
  REQUIRE_NOTHROW( p.ParseArgs(std::vector<std::string>{"-i", " 12"}) )
due to unexpected exception with message:
  Argument 'name' received invalid value type ' 12'

-------------------------------------------------------------------------------
Noexcept mode works as expected
-------------------------------------------------------------------------------
test.cxx:1378
...............................................................................

test.cxx:1418: FAILED:
  REQUIRE( parser.GetError() == argstest::Error::None )
with expansion:
  2 == 0

-------------------------------------------------------------------------------
Required flags work as expected in noexcept mode
-------------------------------------------------------------------------------
test.cxx:1452
...............................................................................

test.cxx:1460: FAILED:
  REQUIRE( parser1.GetError() == argstest::Error::None )
with expansion:
  2 == 0

===============================================================================
test cases:  60 |  42 passed | 18 failed
assertions: 260 | 242 passed | 18 failed

Copy link
Copy Markdown
Owner

@Taywee Taywee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests are failing now and need to be fixed.

make runtests is usually the easiest way to run them.

Copy link
Copy Markdown
Owner

@Taywee Taywee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks good to me now, and tests now pass.

@Taywee Taywee merged commit ec995c9 into Taywee:master Apr 20, 2026
@Taywee
Copy link
Copy Markdown
Owner

Taywee commented Apr 20, 2026

Thank you for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants