diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
index ada4b2b9..32a7bc54 100644
--- a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
@@ -998,6 +998,10 @@ private Expression ParseIdentifier()
return ParseFunctionIsNull();
case KeywordsHelper.FUNCTION_NEW:
+ if (_parsingConfig.DisallowNewKeyword)
+ {
+ throw ParseError(Res.NewOperatorIsNotAllowed);
+ }
return ParseNew();
case KeywordsHelper.FUNCTION_NULLPROPAGATION:
@@ -1354,9 +1358,10 @@ private Expression ParseNew()
if (_textParser.CurrentToken.Id == TokenId.Identifier)
{
var newTypeName = _textParser.CurrentToken.Text;
+
_textParser.NextToken();
- while (_textParser.CurrentToken.Id == TokenId.Dot || _textParser.CurrentToken.Id == TokenId.Plus)
+ while (_textParser.CurrentToken.Id is TokenId.Dot or TokenId.Plus)
{
var sep = _textParser.CurrentToken.Text;
_textParser.NextToken();
diff --git a/src/System.Linq.Dynamic.Core/ParsingConfig.cs b/src/System.Linq.Dynamic.Core/ParsingConfig.cs
index 6b574054..157aadd0 100644
--- a/src/System.Linq.Dynamic.Core/ParsingConfig.cs
+++ b/src/System.Linq.Dynamic.Core/ParsingConfig.cs
@@ -14,12 +14,12 @@ public class ParsingConfig
///
/// Default ParsingConfig
///
- public static ParsingConfig Default { get; } = new ParsingConfig();
+ public static ParsingConfig Default { get; } = new();
///
/// Default ParsingConfig for EntityFramework Core 2.1 and higher
///
- public static ParsingConfig DefaultEFCore21 { get; } = new ParsingConfig
+ public static ParsingConfig DefaultEFCore21 { get; } = new()
{
EvaluateGroupByAtDatabase = true
};
@@ -30,7 +30,7 @@ public class ParsingConfig
///
/// Default ParsingConfig for CosmosDb
///
- public static ParsingConfig DefaultCosmosDb { get; } = new ParsingConfig
+ public static ParsingConfig DefaultCosmosDb { get; } = new()
{
RenameEmptyParameterExpressionNames = true
};
@@ -227,4 +227,11 @@ public IQueryableAnalyzer QueryableAnalyzer
/// Default value is false.
///
public bool SupportDotInPropertyNames { get; set; } = false;
+
+ ///
+ /// Disallows the New() keyword to be used to construct a class.
+ ///
+ /// Default value is false.
+ ///
+ public bool DisallowNewKeyword { get; set; } = false;
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core/Res.cs b/src/System.Linq.Dynamic.Core/Res.cs
index 0b897a85..faaaa21a 100644
--- a/src/System.Linq.Dynamic.Core/Res.cs
+++ b/src/System.Linq.Dynamic.Core/Res.cs
@@ -54,6 +54,7 @@ internal static class Res
public const string MinusCannotBeAppliedToUnsignedInteger = "'-' cannot be applied to unsigned integers.";
public const string MissingAsClause = "Expression is missing an 'as' clause";
public const string NeitherTypeConvertsToOther = "Neither of the types '{0}' and '{1}' converts to the other";
+ public const string NewOperatorIsNotAllowed = "Using the new operator is not allowed via the ParsingConfig.";
public const string NoApplicableAggregate = "No applicable aggregate method '{0}({1})' exists";
public const string NoApplicableIndexer = "No applicable indexer exists in type '{0}'";
public const string NoApplicableMethod = "No applicable method '{0}' exists in type '{1}'";
diff --git a/test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.MemberAccess.cs b/test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.MemberAccess.cs
index a21c9814..8f266e69 100644
--- a/test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.MemberAccess.cs
+++ b/test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.MemberAccess.cs
@@ -1,6 +1,4 @@
-using System.Linq.Dynamic.Core.Parser;
-using System.Linq.Expressions;
-using FluentAssertions;
+using FluentAssertions;
using Xunit;
namespace System.Linq.Dynamic.Core.Tests.Parser
@@ -11,7 +9,7 @@ partial class ExpressionParserTests
public void ParseMemberAccess_DictionaryIndex_On_Dynamic()
{
// Arrange
- var products = (new ProductDynamic[0]).AsQueryable();
+ var products = new ProductDynamic[0].AsQueryable();
// Act
var expression = products.Where("Properties.Name == @0", "First Product").Expression;
@@ -31,4 +29,4 @@ public class ProductDynamic
public dynamic Properties { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.TypeAccess.cs b/test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.TypeAccess.cs
index 9c92c1b3..45548e49 100644
--- a/test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.TypeAccess.cs
+++ b/test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.TypeAccess.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq.Dynamic.Core.Exceptions;
using System.Linq.Dynamic.Core.Parser;
using System.Linq.Expressions;
using FluentAssertions;
@@ -216,9 +217,10 @@ public void ParseTypeAccess_Via_Constructor_DynamicType_To_String(string newExpr
// Arrange
var parameter = Expression.Parameter(typeof(int));
var parameter2 = Expression.Parameter(typeof(int));
- var returnType = DynamicClassFactory.CreateType(new List {
- new DynamicProperty("a", typeof(int)),
- new DynamicProperty("b", typeof(int))
+ var returnType = DynamicClassFactory.CreateType(new List
+ {
+ new("a", typeof(int)),
+ new("b", typeof(int))
});
// Act
@@ -228,4 +230,27 @@ public void ParseTypeAccess_Via_Constructor_DynamicType_To_String(string newExpr
// Assert
expression.ToString().Should().Match(newExpression2);
}
+
+ [Fact]
+ public void Parse_NewOperator_When_DisallowNewKeyword_Is_True_Should_Throw_Exception()
+ {
+ // Arrange
+ var parameter = Expression.Parameter(typeof(int));
+ var returnType = DynamicClassFactory.CreateType(new List
+ {
+ new("a", typeof(int))
+ });
+ var config = new ParsingConfig
+ {
+ DisallowNewKeyword = true
+ };
+
+ // Act
+ var parser = new ExpressionParser(new[] { parameter }, "new(1 as a)", new object[] { }, config);
+
+ Action action = () => parser.Parse(returnType);
+
+ // Assert
+ action.Should().Throw().Which.Message.Should().Be(Res.NewOperatorIsNotAllowed);
+ }
}
\ No newline at end of file