Skip to content

Commit

Permalink
[xaml] fix potential NRE in {Binding}
Browse files Browse the repository at this point in the history
Fixes: dotnet#24740

Using this in a project:

    <PackageReference Include="akgul.Maui.DataGrid" Version="4.0.4" />

Then, in a XAML file:

    xmlns:dg="clr-namespace:Maui.DataGrid;assembly=Maui.DataGrid"
    ...
    <dg:DataGrid />

Would crash with:

    [0:] [13:46:57 FTL] Inner Exception:
    System.NullReferenceException: Object reference not set to an instance of an object.
    at Microsoft.Maui.Controls.Xaml.BindingExtension.<Microsoft.Maui.Controls.Xaml.IMarkupExtension<Microsoft.Maui.Controls.BindingBase>.ProvideValue>g__CreateBinding|40_0(<>c__DisplayClass40_0& ) in /_/src/Controls/src/Xaml/MarkupExtensions/BindingExtension.cs:line 46
    at Microsoft.Maui.Controls.Xaml.BindingExtension.Microsoft.Maui.Controls.Xaml.IMarkupExtension<Microsoft.Maui.Controls.BindingBase>.ProvideValue(IServiceProvider serviceProvider) in /_/src/Controls/src/Xaml/MarkupExtensions/BindingExtension.cs:line 27
    at Maui.DataGrid.DataGrid.InitializeComponent() in D:\Maui.DataGrid\Maui.DataGrid\Microsoft.Maui.Controls.SourceGen\Microsoft.Maui.Controls.SourceGen.CodeBehindGenerator\DataGrid.xaml.sg.cs:line 53
    at Maui.DataGrid.DataGrid..ctor() in D:\Maui.DataGrid\Maui.DataGrid\DataGrid.xaml.cs:line 46
    at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Constructor(Object obj, IntPtr* args)
    at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Inspecting the IL, I see:

    BindingBase val115 = ((IMarkupExtension<BindingBase>)(object)val31).ProvideValue((IServiceProvider)null);

So, it is indeed passed a `null` `IServiceProvider`.

Introduce a unit test and check for `null` as a fix.
  • Loading branch information
jonathanpeppers authored and PureWeen committed Sep 21, 2024
1 parent d0b2b69 commit d43b55c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Controls/src/Xaml/MarkupExtensions/BindingExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ BindingBase IMarkupExtension<BindingBase>.ProvideValue(IServiceProvider serviceP
BindingBase CreateBinding()
{
Type bindingXDataType = null;
if ((serviceProvider.GetService(typeof(IXamlTypeResolver)) is IXamlTypeResolver typeResolver)
if (serviceProvider is not null &&
(serviceProvider.GetService(typeof(IXamlTypeResolver)) is IXamlTypeResolver typeResolver)
&& (serviceProvider.GetService(typeof(IXamlDataTypeProvider)) is IXamlDataTypeProvider dataTypeProvider)
&& dataTypeProvider.BindingDataType != null)
{
Expand Down
14 changes: 14 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/BindingExtensionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using NUnit.Framework;

namespace Microsoft.Maui.Controls.Xaml.UnitTests;

[TestFixture]
public class BindingExtensionTests
{
[Test]
public void ProvideValue_Null()
{
IMarkupExtension<BindingBase> binding = new BindingExtension { Path = "Foo" };
binding.ProvideValue(null); // This should not throw
}
}

0 comments on commit d43b55c

Please sign in to comment.