Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Add support for thousands separators in [bigint] casting#25396

Merged
iSazonov merged 28 commits into
PowerShell:masterPowerShell/PowerShell:masterfrom
AbishekPonmudi:patch-3AbishekPonmudi/PowerShell:patch-3Copy head branch name to clipboard
May 8, 2025
Merged

Add support for thousands separators in [bigint] casting#25396
iSazonov merged 28 commits into
PowerShell:masterPowerShell/PowerShell:masterfrom
AbishekPonmudi:patch-3AbishekPonmudi/PowerShell:patch-3Copy head branch name to clipboard

Conversation

@AbishekPonmudi

@AbishekPonmudi AbishekPonmudi commented Apr 21, 2025

Copy link
Copy Markdown
Contributor

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 an InvalidArgument exception. The root cause is the absence of NumberStyles.AllowThousands and 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 in LanguagePrimitives.cs include:

  • Casting sourceValue using (string) instead of as string for type safety.
  • Dynamically handling culture-specific formatting to ensure group separators are correctly removed.
  • Including NumberStyles.AllowThousands for accurate parsing of BigInteger.

Error Message Before Fix

InvalidArgument: Cannot convert value "1,000" to type "System.Numerics.BigInteger". Error: "The value could not be parsed."

After Fix

PS> [bigint] '1,000'
'1000'

Why This Fix?

  • Prevents casting errors when handling numeric strings with thousands separators.
  • Improves PowerShell’s type conversion reliability.
  • Ensures compatibility with standard numeric formatting.

PR Checklist

Related Issues

FIXED ----

Comment thread src/System.Management.Automation/engine/LanguagePrimitives.cs Outdated
AbishekPonmudi added a commit to AbishekPonmudi/PowerShell that referenced this pull request Apr 22, 2025
…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.
@AbishekPonmudi AbishekPonmudi requested a review from iSazonov April 22, 2025 07:01
@iSazonov

Copy link
Copy Markdown
Collaborator

In related issue there is a reference to code where exception is raised

if (resultType == typeof(BigInteger))
{
// Fallback for BigInteger: manual parsing using any common format.
NumberStyles style = NumberStyles.AllowLeadingSign
| NumberStyles.AllowDecimalPoint
| NumberStyles.AllowExponent
| NumberStyles.AllowHexSpecifier;
return BigInteger.Parse(strToConvert, style, NumberFormatInfo.InvariantInfo);
}

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.

@AbishekPonmudi

Copy link
Copy Markdown
Contributor Author

Hey @iSazonov,

Thanks for the heads-up! I went ahead and tweaked LanguagePrimitives.cs (lines 2957–2966) to fix that BigInteger.Parse() issue with thousands separators. I ditched NumberStyles.AllowHexSpecifier, swapped BigInteger.Parse() for BigInteger.TryParse() to keep things smooth, and made sure it handles stuff like "1,000" → 1000 and "5,432,100" → 5432100 correctly.

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.");
}

Comment thread src/System.Management.Automation/engine/LanguagePrimitives.cs Outdated
Comment thread src/System.Management.Automation/engine/LanguagePrimitives.cs Outdated
Comment thread src/System.Management.Automation/engine/LanguagePrimitives.cs Outdated

@AbishekPonmudi AbishekPonmudi left a comment

Copy link
Copy Markdown
Contributor Author

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!

@iSazonov

Copy link
Copy Markdown
Collaborator

@AbishekPonmudi Please add new tests to cover the code. (The tests should use current culture NumberGroupSeparator .)

Comment thread src/System.Management.Automation/engine/LanguagePrimitives.cs Outdated

@AbishekPonmudi AbishekPonmudi left a comment

Copy link
Copy Markdown
Contributor Author

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!

@iSazonov

Copy link
Copy Markdown
Collaborator

@AbishekPonmudi Please add tests to cover all scenarios you are trying to fix.

@AbishekPonmudi

AbishekPonmudi commented Apr 26, 2025

Copy link
Copy Markdown
Contributor Author

@AbishekPonmudi Please add tests to cover all scenarios you are trying to fix.

I ran manual tests for different locales using the file BigIntegerCultureHandling.ps1 as mentioned in the visual reference. I verified that PowerShell correctly handles thousands of separators, everything seems to be working fine based on these tests.
Please let me know if there are any issues or if any further refinements are needed :)

@iSazonov

Copy link
Copy Markdown
Collaborator

@AbishekPonmudi You should add tests to the PR.

AbishekPonmudi added a commit to AbishekPonmudi/PowerShell that referenced this pull request Apr 27, 2025
AbishekPonmudi added a commit to AbishekPonmudi/PowerShell that referenced this pull request Apr 27, 2025
@AbishekPonmudi

Copy link
Copy Markdown
Contributor Author

Hi @iSazonov,

I have submitted a separate Pull Request (#25463) that includes the necessary unit tests for BigInteger parsing across different cultures. These tests verify correct handling of thousands separators using PowerShell’s current culture settings.

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....

@iSazonov

Copy link
Copy Markdown
Collaborator

@AbishekPonmudi If the PR fix #25368 we need tests in the PR which cover scenarios from that issue.

AbishekPonmudi added a commit to AbishekPonmudi/PowerShell that referenced this pull request Apr 28, 2025
@AbishekPonmudi AbishekPonmudi requested a review from mklement0 May 7, 2025 19:29
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")

Copy link
Copy Markdown
Contributor

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' {

Copy link
Copy Markdown
Contributor

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' {

Copy link
Copy Markdown
Contributor

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

Copy link
Copy Markdown
Contributor Author

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 :)

@AbishekPonmudi AbishekPonmudi requested a review from mklement0 May 7, 2025 19:50

@mklement0 mklement0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@iSazonov, everything LGTM now.

@AbishekPonmudi AbishekPonmudi requested a review from iSazonov May 7, 2025 19:55
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

Describe 'PowerShell Type Conversion - BigInteger Parsing' -Tag 'CI' {

Copy link
Copy Markdown
Collaborator

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

@AbishekPonmudi AbishekPonmudi requested a review from iSazonov May 8, 2025 07:40
Comment on lines +189 to +194
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
}

Copy link
Copy Markdown
Collaborator

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.

@AbishekPonmudi AbishekPonmudi requested a review from iSazonov May 8, 2025 09:53
@AbishekPonmudi

Copy link
Copy Markdown
Contributor Author

@iSazonov Is everything is resolved.

@iSazonov

This comment was marked as outdated.

@azure-pipelines

This comment was marked as outdated.

@PowerShell PowerShell deleted a comment from azure-pipelines Bot May 8, 2025
@iSazonov iSazonov merged commit 1b786d2 into PowerShell:master May 8, 2025
36 checks passed
@microsoft-github-policy-service

microsoft-github-policy-service Bot commented May 8, 2025

Copy link
Copy Markdown
Contributor

📣 Hey @@AbishekPonmudi, how did we do? We would love to hear your feedback with the link below! 🗣️

🔗 https://aka.ms/PSRepoFeedback

@iSazonov

iSazonov commented May 8, 2025

Copy link
Copy Markdown
Collaborator

@AbishekPonmudi Thanks for your contribution! Please update the PR description to exactly reflect the change.

@iSazonov

iSazonov commented May 8, 2025

Copy link
Copy Markdown
Collaborator

@mklement0 Thanks for review!

@AbishekPonmudi

AbishekPonmudi commented May 8, 2025

Copy link
Copy Markdown
Contributor Author

@iSazonov Thank you for reviewing my contribution! I appreciate your feedback. I have updated the PR description to reflect the implemented changes.

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

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bigint] casting breaks with strings containing thousands separators (commas)

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.