Skip to content
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

OData $filter=contains and NullReferenceExceptions in LINQ to SQL #2808

Open
drweb86 opened this issue Sep 22, 2023 · 2 comments
Open

OData $filter=contains and NullReferenceExceptions in LINQ to SQL #2808

drweb86 opened this issue Sep 22, 2023 · 2 comments
Assignees

Comments

@drweb86
Copy link

drweb86 commented Sep 22, 2023

When you filter over string property with null value, null reference exception is happening

Assemblies affected

Microsoft.AspNet.OData.5.7.0\lib\net45\System.Web.OData.dll 5.7.0.0

Reproduce steps

  1. Create table Test with Name nullable string

  2. Create OData controller for it with Get
    Modify method like this

  3. Put into table record with NULL as name.

        [CustomQueryable]
        public IQueryable<Test> Get( ODataQueryOptions<Test> queryOptions)
        {
            var items = dbContext.Tests.ToList();
             // some security trimming.
            return items .AsQueryable();
        }
  1. Execute in Postman https://.../Tests?$filter=contains(Name,'123')

Expected result

The same as for execution in the database. Skip null values. So
.Where(x => x.Name.Contains("123"))
translate into
.Where(x => x.Name?.Contains("123"))

Actual result

After ToList(); statement all items are inside memory (i understand how bad is it for database, but we need it for security trimming)
contains(Name,'123') is transformed into .Where(x => x.Name.Contains("123")). When x.Name is null exception happens

System.Reflection.TargetInvocationException: at System.RuntimeMethodHandle.InvokeMethod (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Reflection.RuntimeMethodInfo.Invoke (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Web.OData.Query.ODataQueryOptions.LimitResults (System.Web.OData, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.OData.Query.ODataQueryOptions.ApplyTo (System.Web.OData, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.OData.EnableQueryAttribute.ExecuteQuery (System.Web.OData, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.OData.EnableQueryAttribute.OnActionExecuted (System.Web.OData, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.Http.Filters.ActionFilterAttribute.OnActionExecutedAsync (System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Web.Http.Filters.ActionFilterAttribute+<CallOnActionExecutedAsync>d__5.MoveNext (System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Web.Http.Filters.ActionFilterAttribute+<ExecuteActionFilterAsyncCore>d__0.MoveNext (System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Web.Http.Controllers.ActionFilterResult+<ExecuteAsync>d__2.MoveNext (System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Web.Http.Filters.AuthorizationFilterAttribute+<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext (System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Web.Http.Dispatcher.HttpControllerDispatcher+<SendAsync>d__1.MoveNext (System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) Inner exception System.NullReferenceException handled at System.RuntimeMethodHandle.InvokeMethod: at lambda_method (Anonymously Hosted DynamicMethods Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null) at System.Linq.Enumerable+WhereArrayIterator1.MoveNext (System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
at System.Linq.Buffer1..ctor (System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Linq.OrderedEnumerable1+d__1.MoveNext (System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
at System.Linq.Enumerable+d__251.MoveNext (System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at System.Collections.Generic.List1..ctor (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
at System.Web.OData.Query.TruncatedCollection`1..ctor (System.Web.OData, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
at System.Web.OData.Query.ODataQueryOptions.LimitResults (System.Web.OData, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)

`
It does not reproduce when query is executed in database, since SQL LIKE operator does not fail with null Name.
So there's a clear difference between in-sql and non sql approach how its handled by OData.

Additional detail

Optional, details of the root cause if known. Delete this section if you have no additional details to add.

@gathogojr
Copy link
Contributor

Thank you @drweb86 for reporting the issue. Microsoft.AspNet.OData.5.7.0 is in maintenance mode and we can only implement critical/security fixes. Have you tried version 7 and 8 of the library? The two versions handle null propagation properly.

@gathogojr gathogojr self-assigned this Sep 26, 2023
@drweb86
Copy link
Author

drweb86 commented Sep 28, 2023

Hi. Thank you for the response. Unfortunately, I won't be able to check it with latest version since we stuck with this version. But it will be a point to start conversation about upgrading to latest version in the future, since you probably at some point drop support for this version of library even for security fixes...

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

No branches or pull requests

2 participants