-
Notifications
You must be signed in to change notification settings - Fork 8k
Add support for thousands separators in [bigint] casting #25396
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
…casting errors (PowerShell#25396) # Issue Summary PowerShell fails to convert numeric strings with thousands separators (e.g., commas) to `[bigint]`, causing casting errors. This occurs because the `ConvertFrom()` method in `LanguagePrimitives.cs` doesn’t handle formatted numbers. ## Cause - The `ConvertTo()` method doesn’t remove thousands separators (e.g., `,` in en-US), leading to `BigInteger.Parse()` failures. - This affects scripts handling large numbers with separators. ## Solution Modify `ConvertFrom()` to: - Detect the culture-specific thousands separator. - Remove it before conversion.
|
In related issue there is a reference to code where exception is raised PowerShell/src/System.Management.Automation/engine/LanguagePrimitives.cs Lines 2946 to 2955 in dd1fb91
I guess it is right place for a fix. Also I don't think we should do any normalizations since BigInteger.(Try)Parser() can do all work. |
|
Hey @iSazonov, Thanks for the heads-up! I went ahead and tweaked if (resultType == typeof(BigInteger))
{
// Adjust NumberStyles to remove AllowHexSpecifier for standard numeric parsing
NumberStyles style = NumberStyles.AllowLeadingSign
| NumberStyles.AllowDecimalPoint
| NumberStyles.AllowExponent; // Removed AllowHexSpecifier
BigInteger parsedValue;
if (BigInteger.TryParse(strToConvert, style, NumberFormatInfo.InvariantInfo, out parsedValue))
{
return parsedValue;
}
throw new PSInvalidCastException("Failed to convert string to BigInteger.");
} |
…ted numeric strings (PowerShell#25396)
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.
Thanks for the review, @iSazonov! I’ve updated LanguagePrimitives.cs to remove the unnecessary comment, replaced BigInteger.TryParse() with BigInteger.Parse(), and adjusted NumberStyles to allow thousands separators. Let me know if any further refinements are needed!
|
@AbishekPonmudi Please add new tests to cover the code. (The tests should use current culture NumberGroupSeparator .) |
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.
Thanks for the review, @iSazonov! I’ve updated the code to remove manual separator normalization and now rely on BigInteger.Parse() with NumberStyles.AllowThousands to handle formatted numeric strings directly. Let me know if any further refinements are needed!
|
@AbishekPonmudi Please add tests to cover all scenarios you are trying to fix. |
I ran manual tests for different locales using the file |
|
@AbishekPonmudi You should add tests to the PR. |
|
Hi @iSazonov, I have submitted a separate Pull Request ( Please refer to the test PR here: Tests for BigInteger parsing across cultures (#25463). Let me know if any changes or refinements are needed to do better with the expected behavior.... |
|
@AbishekPonmudi If the PR fix #25368 we need tests in the PR which cover scenarios from that issue. |
| Describe 'PowerShell Type Conversion - BigInteger Parsing' -Tag 'CI' { | ||
|
|
||
| It 'Can convert formatted numbers using PowerShell type system' { | ||
| [System.Globalization.CultureInfo]::CurrentCulture = [System.Globalization.CultureInfo]::GetCultureInfo("en-US") |
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.
Since the culture angle is now covered by the de-DE test, I suggest removing this.
| $convertedValue | Should -Be 1000 | ||
| } | ||
|
|
||
| It 'Handles large comma-separated numbers that previously failed' { |
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.
Quibble: perhaps better: `Handles large numbers with thousands separators that previously failed'
| $convertedValue | Should -Be 1000000 | ||
| } | ||
|
|
||
| It 'Parses number using de-DE culture but falls back to invariant behavior' { |
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.
Quibble: Since the current culture never comes into play, I wouldn't say "Parses number using de-DE". Perhaps better: Parses a number string using the invariant culture, irrespective of the current culture
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.
Thanks for the feedback @mklement0 , I have removed the line as suggested, and updated the "Handles large comma-separated numbers" test to "Handles large numbers with thousands separators" for clarity. Also, I have reworded the "de-DE" test to better reflect that it uses invariant culture, irrespective of the current culture.
Get me again ! if anything needed to better :)
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.
@iSazonov, everything LGTM now.
| # Copyright (c) Microsoft Corporation. | ||
| # Licensed under the MIT License. | ||
|
|
||
| Describe 'PowerShell Type Conversion - BigInteger Parsing' -Tag 'CI' { |
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.
Please all tests in LanguagePrimitive.Tests.ps1
| It 'Can convert formatted numbers using PowerShell type system' { | ||
| [System.Globalization.CultureInfo]::CurrentCulture = [System.Globalization.CultureInfo]::GetCultureInfo("en-US") | ||
| $formattedNumber = "1,000" | ||
| $convertedValue = [System.Management.Automation.LanguagePrimitives]::ConvertTo($formattedNumber, [bigint]) | ||
| $convertedValue | Should -Be 1000 | ||
| } |
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.
The test was removed before.
|
@iSazonov Is everything is resolved. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
|
📣 Hey @@AbishekPonmudi, how did we do? We would love to hear your feedback with the link below! 🗣️ 🔗 https://aka.ms/PSRepoFeedback |
|
@AbishekPonmudi Thanks for your contribution! Please update the PR description to exactly reflect the change. |
|
@mklement0 Thanks for review! |
|
@iSazonov Thank you for reviewing my contribution! I appreciate your feedback. I have updated the PR description to reflect the implemented changes. |
PR Summary
This PR resolves a parsing issue in PowerShell where numeric strings containing thousands separators (e.g.,
1,000) fail to convert into[bigint], resulting in anInvalidArgumentexception. The root cause is the absence ofNumberStyles.AllowThousandsand lack of formatting cleanup before conversion. This update ensures consistent and locale-aware conversion behavior for large numeric strings.PR Context
The issue occurs when users attempt to cast strings like
'1,000'to[bigint], and PowerShell does not account for grouping symbols defined by culture. This leads to type conversion errors in scripts or user input relying on formatted numbers.Solution
Updates made to the
ConvertFrom()method inLanguagePrimitives.csinclude:sourceValueusing(string)instead ofas stringfor type safety.NumberStyles.AllowThousandsfor accurate parsing ofBigInteger.Error Message Before Fix
After Fix
Why This Fix?
PR Checklist
PR has a meaningful title
Summarized changes
Make sure all
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerThis PR is ready to merge. If this PR is a work in progress, please open this as a Draft Pull Request and mark it as Ready to Review when it is ready to merge.
Breaking changes
User-facing changes
Testing - New and feature
Related Issues
FIXED ----
[bigint]casting breaks with strings containing thousands separators (commas) #25368