Skip to content

[BUG] MathExpressionConverter doesn't support negative numbers when in Arabic (ar_AR) #2721

@stephenquan

Description

@stephenquan

Is there an existing issue for this?

  • I have searched the existing issues

Did you read the "Reporting a bug" section on Contributing file?

Current Behavior

When your CultureInfo.CurrentCulture = new CultureInfo("ar-AR") the MathExpressionConverter will raise an exception when the expression contains negative numbers (e.g. x0 ? -90 : 90):

HResult: -2146233033 (0x80131537)
Message: The input string '-90' was not in a correct format.

Here's the call stack:

at System.Number.ThrowFormatException[TChar](ReadOnlySpan1 value) at System.Double.Parse(String s) at CommunityToolkit.Maui.Converters.MathExpression.ParsePrimary() in /_/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 365 at CommunityToolkit.Maui.Converters.MathExpression.ParseBinaryOperators(Regex BinaryOperators, Func1 ParseNext) in //src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 337
at CommunityToolkit.Maui.Converters.MathExpression.ParsePower() in /
/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 333
at CommunityToolkit.Maui.Converters.MathExpression.ParseBinaryOperators(Regex BinaryOperators, Func1 ParseNext) in /_/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 337 at CommunityToolkit.Maui.Converters.MathExpression.ParseProduct() in /_/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 331 at CommunityToolkit.Maui.Converters.MathExpression.ParseBinaryOperators(Regex BinaryOperators, Func1 ParseNext) in //src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 337
at CommunityToolkit.Maui.Converters.MathExpression.ParseSum() in /
/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 329
at CommunityToolkit.Maui.Converters.MathExpression.ParseBinaryOperators(Regex BinaryOperators, Func1 ParseNext) in /_/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 337 at CommunityToolkit.Maui.Converters.MathExpression.ParseCompare() in /_/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 327 at CommunityToolkit.Maui.Converters.MathExpression.ParseBinaryOperators(Regex BinaryOperators, Func1 ParseNext) in //src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 357
at CommunityToolkit.Maui.Converters.MathExpression.ParseEquality() in /
/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 325
at CommunityToolkit.Maui.Converters.MathExpression.ParseBinaryOperators(Regex BinaryOperators, Func1 ParseNext) in /_/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 337 at CommunityToolkit.Maui.Converters.MathExpression.ParseLogicalAnd() in /_/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 323 at CommunityToolkit.Maui.Converters.MathExpression.ParseBinaryOperators(Regex BinaryOperators, Func1 ParseNext) in //src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 337
at CommunityToolkit.Maui.Converters.MathExpression.ParseLogicalOR() in /
/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 321
at CommunityToolkit.Maui.Converters.MathExpression.ParseConditional() in //src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 302
at CommunityToolkit.Maui.Converters.MathExpression.ParseExpr() in /
/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 287
at CommunityToolkit.Maui.Converters.MathExpression.ParseExpression() in //src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 282
at CommunityToolkit.Maui.Converters.MathExpression.CalculateResult() in /
/src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs:line 128
at CommunityToolkit.Maui.Converters.MathExpressionConverter.ConvertFrom(Object inputValue, String parameter, CultureInfo culture) in //src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpressionConverter.shared.cs:line 25
at CommunityToolkit.Maui.Converters.BaseConverter`3.CommunityToolkit.Maui.Converters.ICommunityToolkitValueConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) in /
/src/CommunityToolkit.Maui/Converters/BaseConverter.shared.cs:line 91
at CommunityToolkit.Maui.Converters.ICommunityToolkitValueConverter.Microsoft.Maui.Controls.IValueConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) in /_/src/CommunityToolkit.Maui/Converters/ICommunityToolkitValueConverter.shared.cs:line 57
at Microsoft.Maui.Controls.Binding.GetSourceValue(Object value, Type targetPropertyType)
at Microsoft.Maui.Controls.BindingExpression.ApplyCore(Object sourceObject, BindableObject target, BindableProperty property, Boolean fromTarget, SetterSpecificity specificity)
at Microsoft.Maui.Controls.BindingExpression.Apply(Boolean fromTarget)
at Microsoft.Maui.Controls.BindingExpression.BindingExpressionPart.b__50_0()
at Microsoft.Maui.Controls.DispatcherExtensions.DispatchIfRequired(IDispatcher dispatcher, Action action)
at Microsoft.Maui.Controls.BindingExpression.BindingExpressionPart.PropertyChanged(Object sender, PropertyChangedEventArgs args)
at Microsoft.Maui.Controls.BindingExpression.WeakPropertyChangedProxy.OnPropertyChanged(Object sender, PropertyChangedEventArgs e)
at Microsoft.Maui.Controls.BindableObject.OnPropertyChanged(String propertyName)
at Microsoft.Maui.Controls.Element.OnPropertyChanged(String propertyName)
at Microsoft.Maui.Controls.BindableObject.OnBindablePropertySet(BindableProperty property, Object original, Object value, Boolean didChange, Boolean willFirePropertyChanged)
at Microsoft.Maui.Controls.Element.OnBindablePropertySet(BindableProperty property, Object original, Object value, Boolean changed, Boolean willFirePropertyChanged)
at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value, SetterSpecificity specificity)
at Microsoft.Maui.Controls.CheckBox.Microsoft.Maui.ICheckBox.set_IsChecked(Boolean value)
at Microsoft.Maui.Handlers.CheckBoxHandler.OnChecked(Object sender, RoutedEventArgs e)
at WinRT._EventSource_global__Microsoft_UI_Xaml_RoutedEventHandler.EventState.b__1_0(Object sender, RoutedEventArgs e)
at ABI.Microsoft.UI.Xaml.RoutedEventHandler.Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e)

Expected Behavior

The MathExpressionConverter should be able to handle expressions with negative numbers without encountering exceptions.

Steps To Reproduce

The following is a XAML minimal repro case

<VerticalStackLayout Padding="30,0" Spacing="25">
    <Label Text="Click on the CheckBox below and observe the corresponding Label changing its orientation. When set to Arabic, however, clicking on the CheckBox will crash the app." />
    <CheckBox x:Name="ExpandedCheck" IsChecked="True" />
    <Label
         HorizontalOptions="Start"
         Rotation="{Binding IsChecked,
                            Source={Reference ExpandedCheck},
                            x:DataType=CheckBox,
                            Converter={StaticResource MathExpressionConverter},
                            ConverterParameter='x0 ? -90 : 90'}"
         Text="&gt;" />
</VerticalStackLayout>

Link to public reproduction project repository

https://github.com/stephenquan/MauiMCTMinusBug

Environment

- .NET MAUI CommunityToolkit: 12.0
- OS: Windows 11
- .NET MAUI: 9.0.70

Anything else?

I believe the bug is on the following offending line:

RPN.Add(new MathToken(MathTokenType.Value, _number, double.Parse(_number)));

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions