-
Notifications
You must be signed in to change notification settings - Fork 37.7k
util: Replace use of locale dependent atoi(…) with locale-independent std::from_chars(…) (C++17) #20452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Note that we have a function However these didn't turn out to be actually locale-independent. Maybe this can replace them eventually. |
This is good to hear at least. From https://en.cppreference.com/w/cpp/utility/from_chars#Notes :
Concept ACK. |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
I think we need to make a choice here (either one or both):
|
be0efcd
to
25ad608
Compare
Good point. I thought about those options as well. I think we should do both. This PR is meant as a pure refactoring: it is not meant to change any behaviour that is defined by I've now made it more clear that this PR is meant as a quirk-by-quirk compatible replacement for Good point about naming: we should keep the name |
f23f854
to
8c1142e
Compare
Okay, agree. I guess it could replace |
8c1142e
to
6a6a71e
Compare
@laanwj Done! I've now replaced all instances of |
Thanks, looks good to me now except the documentation nit. |
f14668e
to
04271a9
Compare
… leading +/-/0:s 05c1095 test: Add testing of ParseInt/ParseUInt edge cases with leading +/-/0:s (practicalswift) Pull request description: Add testing of `ParseInt`/`ParseUInt` edge cases with leading `+`/`-`/`0`:s. Context: While working on #20457 and #20452 I noticed some edge cases which our unit tests are currently not covering. ACKs for top commit: MarcoFalke: review ACK 05c1095 laanwj: Code review ACK 05c1095 jonatack: ACK 05c1095 promag: Code review ACK 05c1095. Tree-SHA512: bdfb94d8fa0293512dbba89907cb6dd0f8b1418d878267dd6d49c8c397a0e5b9714441345565d41a6a909a1cda052ef7cccece822f355ff604fcf85f2dc8136f
04271a9
to
638cfd3
Compare
…es with leading +/-/0:s 05c1095 test: Add testing of ParseInt/ParseUInt edge cases with leading +/-/0:s (practicalswift) Pull request description: Add testing of `ParseInt`/`ParseUInt` edge cases with leading `+`/`-`/`0`:s. Context: While working on bitcoin#20457 and bitcoin#20452 I noticed some edge cases which our unit tests are currently not covering. ACKs for top commit: MarcoFalke: review ACK 05c1095 laanwj: Code review ACK 05c1095 jonatack: ACK 05c1095 promag: Code review ACK 05c1095. Tree-SHA512: bdfb94d8fa0293512dbba89907cb6dd0f8b1418d878267dd6d49c8c397a0e5b9714441345565d41a6a909a1cda052ef7cccece822f355ff604fcf85f2dc8136f
I don't get the CI error. Is
|
4747efa
to
43434b1
Compare
…from_chars(…) (C++17) test: Add test cases for LocaleIndependentAtoi fuzz: Assert legacy atoi(s) == LocaleIndependentAtoi<int>(s) fuzz: Assert legacy atoi64(s) == LocaleIndependentAtoi<int64_t>(s)
43434b1
to
4343f11
Compare
Concept ACK |
Code review ACK 4343f11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK 4343f11
// LocaleIndependentAtoi is provided for backwards compatibility reasons. | ||
// | ||
// New code should use the ParseInt64/ParseUInt64/ParseInt32/ParseUInt32 functions | ||
// which provide parse error feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a really important comment. I hope we can get rid of these functions entirely at some point. The implicit error handling behavior of atoi
and atoi64
is pretty much always undesirable.
(so I would normally comment "these function names are long and clunky, please shorten them" but it's good in this case, we want using them to be ugly 😄 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
concept ack
Follow up in #23184 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
withdrawn my comments
…es with leading +/-/0:s 05c1095 test: Add testing of ParseInt/ParseUInt edge cases with leading +/-/0:s (practicalswift) Pull request description: Add testing of `ParseInt`/`ParseUInt` edge cases with leading `+`/`-`/`0`:s. Context: While working on bitcoin#20457 and bitcoin#20452 I noticed some edge cases which our unit tests are currently not covering. ACKs for top commit: MarcoFalke: review ACK 05c1095 laanwj: Code review ACK 05c1095 jonatack: ACK 05c1095 promag: Code review ACK 05c1095. Tree-SHA512: bdfb94d8fa0293512dbba89907cb6dd0f8b1418d878267dd6d49c8c397a0e5b9714441345565d41a6a909a1cda052ef7cccece822f355ff604fcf85f2dc8136f
The new locale-independent atoi64 method introduced in bitcoin#20452 behaves differently for values passed which are greater than the uint64_t max. This commit is proof of that, meant to spur discussion on how to handle such an incompatibility. The change as committed in bitcoin#20542 may break some scripts which invoke bitcoind, but more than that may have consensus implications as this deserialization mechanism is used in CScript::ParseScript. I think this means it's possible that bitcoin#20542 could have been an accidental soft fork?
Introduce LocaleIndependentAtoi64 which behaves the same way that previous versions of Bitcoin Core has when faced with under- and overflow. This behavior was implicitly changed in bitcoin#20452, but has not yet been included in a release. Attempts to use LocaleIndependentAtoi for int64_t return values will result in a compilation error.
Introduce LocaleIndependentAtoi64 which behaves the same way that previous versions of Bitcoin Core has when faced with under- and overflow. This behavior was implicitly changed in bitcoin#20452, but has not yet been included in a release. Attempts to use LocaleIndependentAtoi for int64_t return values will result in a compilation error.
The new locale-independent atoi64 method introduced in bitcoin#20452 behaves differently for values passed which are greater than the uint64_t max. This commit is proof of that, meant to spur discussion on how to handle such an incompatibility. Introduce LocaleIndependentAtoi64 which behaves the same way that previous versions of Bitcoin Core has when faced with under- and overflow. This behavior was implicitly changed in bitcoin#20452, but has not yet been included in a release. Attempts to use LocaleIndependentAtoi for int64_t return values will result in a compilation error.
The new locale-independent atoi64 method introduced in bitcoin#20452 behaves differently for values passed which are greater than the uint64_t max. This commit is proof of that, meant to spur discussion on how to handle such an incompatibility. Introduce LocaleIndependentAtoi64 which behaves the same way that previous versions of Bitcoin Core has when faced with under- and overflow. This behavior was implicitly changed in bitcoin#20452, but has not yet been included in a release. Attempts to use LocaleIndependentAtoi for int64_t return values will result in a compilation error.
The new locale-independent atoi64 method introduced in bitcoin#20452 parses large integer values higher than maximum representable value as 0 instead of the maximum value, which breaks backwards compatibility. This commit restores compatibility and adds test coverage for this case. Co-authored-by: James O'Beirne <james.obeirne@pm.me>
The new locale-independent atoi64 method introduced in bitcoin#20452 parses large integer values higher than maximum representable value as 0 instead of the maximum value, which breaks backwards compatibility. This commit restores compatibility and adds test coverage for this case in terms of the related GetIntArg and strtoll functions. Co-authored-by: James O'Beirne <james.obeirne@pm.me>
The new locale-independent atoi64 method introduced in bitcoin#20452 parses large integer values higher than maximum representable value as 0 instead of the maximum value, which breaks backwards compatibility. This commit restores compatibility and adds test coverage for this case in terms of the related GetIntArg and strtoll functions. Co-authored-by: James O'Beirne <james.obeirne@pm.me>
The new locale-independent atoi64 method introduced in bitcoin#20452 parses large integer values higher than maximum representable value as 0 instead of the maximum value, which breaks backwards compatibility. This commit restores compatibility and adds test coverage for this case in terms of the related GetIntArg and strtoll functions. Co-authored-by: James O'Beirne <james.obeirne@pm.me>
The new locale-independent atoi64 method introduced in bitcoin#20452 parses large integer values higher than maximum representable value as 0 instead of the maximum value, which breaks backwards compatibility. This commit restores compatibility and adds test coverage for this case in terms of the related GetIntArg and strtoll functions. Co-authored-by: James O'Beirne <james.obeirne@pm.me>
The new locale-independent atoi64 method introduced in bitcoin#20452 parses large integer values higher than maximum representable value as 0 instead of the maximum value, which breaks backwards compatibility. This commit restores compatibility and adds test coverage for this case in terms of the related GetIntArg and strtoll functions. Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
b5c9bb5 util: Restore GetIntArg saturating behavior (James O'Beirne) Pull request description: The new locale-independent atoi64 method introduced in #20452 parses large integer values higher than maximum representable value as 0 instead of the maximum value, which breaks backwards compatibility. This commit restores compatibility and adds test coverage for this case in terms of the related GetIntArg and strtoll functions. Specifically, command line or bitcoin.conf integer values greater than `9223372036854775807` (`2**63-1`) used to be parsed as `9223372036854775807` before #20452. Then #20452 caused them to be parsed as `0`. And after this PR they will be parsed as `9223372036854775807` again. This change is a stripped-down alternative version of #23841 by jamesob ACKs for top commit: jamesob: Github ACK b5c9bb5 vincenzopalazzo: ACK b5c9bb5 MarcoFalke: review ACK b5c9bb5 🌘 Tree-SHA512: 4e8abdbabf3cf4713cf5a7c5169539159f359ab4109a4e7e644cc2e9b2b0c3c532fad9f6b772daf015e1c5340ce59280cd9a41f2730afda6099cbf636b7d23ae
The new locale-independent atoi64 method introduced in bitcoin#20452 parses large integer values higher than maximum representable value as 0 instead of the maximum value, which breaks backwards compatibility. This commit restores compatibility and adds test coverage for this case in terms of the related GetIntArg and strtoll functions. Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
Replace use of locale dependent
atoi(…)
with locale-independentstd::from_chars(…)
(C++17).