Skip to content

Reject partial parses in stou32 - #4555

Open
Daksha1611 wants to merge 1 commit into
openvinotoolkit:mainfrom
Daksha1611:fix-stou32-partial-parse
Open

Reject partial parses in stou32#4555
Daksha1611 wants to merge 1 commit into
openvinotoolkit:mainfrom
Daksha1611:fix-stou32-partial-parse

Conversation

@Daksha1611

@Daksha1611 Daksha1611 commented Sep 12, 2026

Copy link
Copy Markdown

🛠 Summary

Fixes #4554.

stou32() is the only converter in stringutils that does not verify the whole string was consumed. std::stoul stops at the first character it cannot use and still reports success, so stou32("12abc") returned 12, stou32("3.9") returned 3 and stou32("0x10") returned 0. Its siblings all guard against this by passing &idx and comparing against the length — stou64 at :143-147, stoi32 at :161-165, stof at :203-206. This adds the same check.

Two call sites are affected. grpcservermodule.cpp:79 reads the GRPC_SERVERS environment variable, so GRPC_SERVERS=4x silently started 4 servers instead of being rejected and falling back to config.grpcWorkers(). s2t_servable.cpp:81 uses it as a fallback for the transcription temperature field; that endpoint is also addressed in #4553, and either change alone fixes it — they do not conflict.

The surrounding erase_spaces() call is deliberately left alone, so stou32("12 34") still yields 1234. That is a separate question from partial parsing — note stou64 rejects " 100 " outright — and I did not want two behaviour changes in one commit.

The existing StringUtils.stou32 case covers a negative value, overflow and the maximum, none of which change. Adds StringUtils.stou32RejectsPartialParse for the trailing-garbage spellings plus plain numbers.

I have no OVMS build container available, so this is not compiled against the full tree and CI will need to confirm the build. I did check the change in isolation and confirmed the existing test inputs are unaffected. Draft for that reason.

🧪 Checklist

  • Unit tests added.
  • The documentation updated.
  • Change follows security best practices.

stou32() is the only converter in stringutils that does not verify the whole
string was consumed. std::stoul stops at the first character it cannot use
and still reports success, so:

  stou32("12abc") == 12
  stou32("3.9")   == 3
  stou32("0x10")  == 0
  stou32("100%")  == 100

Its siblings all guard against this by passing &idx and comparing against
the length - stou64 at :143-147, stoi32 at :161-165, stof at :203-206.
(stoi64 at :181-185 validates by scanning digits first, which is
equivalent.) Add the same check.

Call sites this affects:

  grpcservermodule.cpp:79 - the GRPC_SERVERS environment variable.
    GRPC_SERVERS=4x silently started 4 servers instead of being rejected
    and falling back to config.grpcWorkers().
  s2t_servable.cpp:81 - the transcription temperature field, where the
    value is used as a fallback after ovms::stof has already rejected it.

The surrounding erase_spaces() call is deliberately left alone, so
stou32("12 34") still yields 1234. That is a separate question from partial
parsing - note stou64 rejects "   100 " outright - and changing it would be
a second behaviour change in one commit.

Tests: the existing StringUtils.stou32 case only covers a negative value,
overflow and the maximum, none of which change. Adds
StringUtils.stou32RejectsPartialParse for the trailing-garbage spellings
above, plus the plain-number cases to pin that valid input still parses.
@Daksha1611
Daksha1611 marked this pull request as ready for review September 12, 2026 07:09
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.

stou32() accepts partial parses, unlike the other stringutils converters

1 participant