From 19a9a012610b32ab8f5b589db919910bd556053d Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Fri, 10 Mar 2023 12:17:11 +0100 Subject: [PATCH 1/2] Add information to readme for breaking change in 1.3.0 --- .../DynamicExpressionParserTests.cs | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs b/test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs index 818037e1..b61cd630 100644 --- a/test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs +++ b/test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs @@ -77,6 +77,17 @@ public class CustomClassWithStaticMethod public static int GetAge(int x) => x; } + public class CustomClassWithMethod + { + public int GetAge(int x) => x; + } + + [DynamicLinqType] + public class CustomClassWithStaticMethodWithDynamicLinqTypeAttribute + { + public static int GetAge(int x) => x; + } + public class CustomTextClass { public CustomTextClass(string origin) @@ -1010,7 +1021,7 @@ public void DynamicExpressionParser_ParseLambda_TupleToStringMethodCall_ReturnsS } [Fact] - public void DynamicExpressionParser_ParseLambda_CustomMethod() + public void DynamicExpressionParser_ParseLambda_CustomStaticMethod_WhenClassIsReturnedByCustomTypeProvider_ShouldWorkCorrect() { // Assign var config = new ParsingConfig @@ -1030,6 +1041,35 @@ public void DynamicExpressionParser_ParseLambda_CustomMethod() Check.That(result).IsEqualTo(10); } + [Fact] + public void DynamicExpressionParser_ParseLambda_CustomStaticMethod_WhenClassHasDynamicLinqTypeAttribute_ShouldWorkCorrect() + { + // Assign + var context = new CustomClassWithStaticMethodWithDynamicLinqTypeAttribute(); + var expression = $"{nameof(CustomClassWithStaticMethodWithDynamicLinqTypeAttribute)}.{nameof(CustomClassWithStaticMethodWithDynamicLinqTypeAttribute.GetAge)}(10)"; + + // Act + var lambdaExpression = DynamicExpressionParser.ParseLambda(typeof(CustomClassWithStaticMethodWithDynamicLinqTypeAttribute), null, expression); + var del = lambdaExpression.Compile(); + var result = (int)del.DynamicInvoke(context); + + // Assert + Check.That(result).IsEqualTo(10); + } + + [Fact] + public void DynamicExpressionParser_ParseLambda_CustomMethod_WhenClassDoesNotHaveDynamicLinqTypeAttribute_ShouldThrowException() + { + // Assign + var expression = $"{nameof(CustomClassWithMethod.GetAge)}(10)"; + + // Act + Action action = () => DynamicExpressionParser.ParseLambda(typeof(CustomClassWithMethod), null, expression); + + // Assert + action.Should().Throw().WithMessage("Methods on type 'CustomClassWithMethod' are not accessible"); + } + // [Fact] public void DynamicExpressionParser_ParseLambda_With_InnerStringLiteral() { From 29deca892f0770b5a0cef157246158c769690e34 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Fri, 10 Mar 2023 13:18:17 +0100 Subject: [PATCH 2/2] readme --- README.md | 21 ++++++++++++++++-- .../DynamicExpressionParserTests.cs | 22 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c54e1ec2..abe2b88d 100644 --- a/README.md +++ b/README.md @@ -30,12 +30,29 @@ int c = 10; db.Customers.WhereInterpolated($"City == {cityName} and Orders.Count >= {c}"); ``` +## :exclamation: Breaking changes + +### v1.3.0 +A breaking change is introduced in version 1.3.0 which is related to calling methods on classes. +Due to security reasons, it's now only allowed to call methods on the standard predefined classes like (`bool`, `int`, `string` ...). +If you want to call a method on an own custom class, annotate that class with the [DynamicLinqType](https://dynamic-linq.net/advanced-extending#dynamiclinqtype-attribute). +Example: +``` c# +[DynamicLinqType] +public class MyCustomClass +{ + public int GetAge(int x) => x; +} +``` + +If it's not possible to add that attribute, you need to implement a custom [CustomTypeProvider](https://dynamic-linq.net/advanced-configuration#customtypeprovider) and set this to the `ParsingConfig` and provide that config to the dynamic call. + ## Useful links -- [Website](https://dynamic-linq.net/) +- [Website](https://dynamic-linq.net) - [Documentation](https://dynamic-linq.net/overview) - [Online examples](https://dynamic-linq.net/online-examples) -- [nuget](https://www.nuget.org/packages/System.Linq.Dynamic.Core/) +- [NuGet](https://www.nuget.org/packages/System.Linq.Dynamic.Core) ## Info | | | diff --git a/test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs b/test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs index b61cd630..0a93e8c5 100644 --- a/test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs +++ b/test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs @@ -82,6 +82,12 @@ public class CustomClassWithMethod public int GetAge(int x) => x; } + [DynamicLinqType] + public class CustomClassWithMethodWithDynamicLinqTypeAttribute + { + public int GetAge(int x) => x; + } + [DynamicLinqType] public class CustomClassWithStaticMethodWithDynamicLinqTypeAttribute { @@ -1057,6 +1063,22 @@ public void DynamicExpressionParser_ParseLambda_CustomStaticMethod_WhenClassHasD Check.That(result).IsEqualTo(10); } + [Fact] + public void DynamicExpressionParser_ParseLambda_CustomMethod_WhenClassHasDynamicLinqTypeAttribute_ShouldWorkCorrect() + { + // Assign + var context = new CustomClassWithMethodWithDynamicLinqTypeAttribute(); + var expression = $"{nameof(CustomClassWithMethodWithDynamicLinqTypeAttribute.GetAge)}(10)"; + + // Act + var lambdaExpression = DynamicExpressionParser.ParseLambda(typeof(CustomClassWithMethodWithDynamicLinqTypeAttribute), null, expression); + var del = lambdaExpression.Compile(); + var result = (int)del.DynamicInvoke(context); + + // Assert + Check.That(result).IsEqualTo(10); + } + [Fact] public void DynamicExpressionParser_ParseLambda_CustomMethod_WhenClassDoesNotHaveDynamicLinqTypeAttribute_ShouldThrowException() {