Skip to content

Commit 1aa0f08

Browse files
committed
variable assignation in expression in place of script + OptionVariableAssignationActive
+ All options to true by default and no blocked types
1 parent a57f48a commit 1aa0f08

File tree

1 file changed

+69
-48
lines changed

1 file changed

+69
-48
lines changed

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -392,12 +392,8 @@ private enum IfBlockEvaluatedState
392392

393393
/// <summary>
394394
/// A list of type to block an keep un usable in Expression Evaluation for security purpose
395-
/// By default just contains ExpressionEvaluation
396395
/// </summary>
397-
public List<Type> TypesToBlock { get; set; } = new List<Type>()
398-
{
399-
typeof(ExpressionEvaluator)
400-
};
396+
public List<Type> TypesToBlock { get; set; } = new List<Type>();
401397

402398
/// <summary>
403399
/// A list of statics types where to find extensions methods
@@ -534,9 +530,17 @@ public bool OptionNewFunctionEvaluationActive
534530

535531
/// <summary>
536532
/// If <c>true</c> Evaluate function is callables in an expression. If <c>false</c> Evaluate is not callable.
537-
/// By default : false for security (also ensure that ExpressionEvaluator type is in TypesToBlock list)
533+
/// By default : true
534+
/// if set to false for security (also ensure that ExpressionEvaluator type is in TypesToBlock list)
538535
/// </summary>
539-
public bool OptionEvaluateFunctionActive { get; set; } = false;
536+
public bool OptionEvaluateFunctionActive { get; set; } = true;
537+
538+
/// <summary>
539+
/// If <c>true</c> allow to assign a value to a variable in the Variable disctionary with (=, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, ++ or --)
540+
/// If <c>false</c> unactive this functionality
541+
/// By default : true
542+
/// </summary>
543+
public bool OptionVariableAssignationActive { get; set; } = true;
540544

541545
/// <summary>
542546
/// If <c>true</c> allow to set/modify a property or a field value with (=, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, ++ or --)
@@ -547,9 +551,10 @@ public bool OptionNewFunctionEvaluationActive
547551

548552
/// <summary>
549553
/// If <c>true</c> ScriptEvaluate function is callables in an expression. If <c>false</c> Evaluate is not callable.
550-
/// By default : false for security (also ensure that ExpressionEvaluator type is in TypesToBlock list)
554+
/// By default : true
555+
/// if set to false for security (also ensure that ExpressionEvaluator type is in TypesToBlock list)
551556
/// </summary>
552-
public bool OptionScriptEvaluateFunctionActive { get; set; } = false;
557+
public bool OptionScriptEvaluateFunctionActive { get; set; } = true;
553558

554559
/// <summary>
555560
/// If <c>ReturnAutomaticallyLastEvaluatedExpression</c> ScriptEvaluate return automatically the last evaluated expression if no return keyword is met.
@@ -697,11 +702,9 @@ private object ScriptEvaluate(string script, ref bool valueReturned, ref bool br
697702
IfBlockEvaluatedState ifBlockEvaluatedState = IfBlockEvaluatedState.NoBlockEvaluated;
698703
List<List<string>> ifElseStatementsList = new List<List<string>>();
699704

700-
object AssignationOrExpressionEval(string expression)
705+
object ManageJumpStatementsOrExpressionEval(string expression)
701706
{
702707
string baseExpression = expression;
703-
bool isAssignation = false;
704-
string variableToAssign = string.Empty;
705708
object result = null;
706709

707710
expression = expression.Trim();
@@ -729,35 +732,8 @@ object AssignationOrExpressionEval(string expression)
729732
return match.Value.Contains("(") ? "(" : string.Empty;
730733
});
731734

732-
Match variableAssignationMatch = variableAssignationRegex.Match(expression);
733-
734-
if (variableAssignationMatch.Success)
735-
{
736-
variableToAssign = variableAssignationMatch.Groups["name"].Value;
737-
expression = expression.Remove(0, variableAssignationMatch.Length).TrimStart();
738-
isAssignation = true;
739-
}
740-
741735
result = Evaluate(expression);
742736

743-
if (isAssignation)
744-
{
745-
if(variableAssignationMatch.Groups["assignmentPrefix"].Success)
746-
{
747-
ExpressionOperator op = operatorsDictionary[variableAssignationMatch.Groups["assignmentPrefix"].Value];
748-
try
749-
{
750-
result = operatorsEvaluations.Find(dict => dict.ContainsKey(op))[op](Variables[variableToAssign], result);
751-
}
752-
catch(Exception exception)
753-
{
754-
throw new ExpressionEvaluatorSyntaxErrorException($"Variable [{variableToAssign}] unknown in expression : [{baseExpression}]", exception);
755-
}
756-
}
757-
758-
Variables[variableToAssign] = result;
759-
}
760-
761737
return result;
762738
}
763739

@@ -767,7 +743,7 @@ object ScriptExpressionEvaluate(ref int index)
767743

768744
startOfExpression = index + 1;
769745

770-
return AssignationOrExpressionEval(expression);
746+
return ManageJumpStatementsOrExpressionEval(expression);
771747
}
772748

773749
bool TryParseStringAndParenthis(ref int index)
@@ -795,7 +771,7 @@ void ExecuteIfList()
795771
{
796772
if (ifElseStatementsList.Count > 0)
797773
{
798-
string ifScript = ifElseStatementsList.Find(statement => (bool)AssignationOrExpressionEval(statement[0]))?[1];
774+
string ifScript = ifElseStatementsList.Find(statement => (bool)ManageJumpStatementsOrExpressionEval(statement[0]))?[1];
799775

800776
if (!string.IsNullOrEmpty(ifScript))
801777
lastResult = ScriptEvaluate(ifScript, ref isReturn, ref isBreak, ref isContinue);
@@ -897,7 +873,7 @@ void ExecuteIfList()
897873
}
898874
else if (keyword.Equals("while"))
899875
{
900-
while (!isReturn && (bool)AssignationOrExpressionEval(keywordAttributes[0]))
876+
while (!isReturn && (bool)ManageJumpStatementsOrExpressionEval(keywordAttributes[0]))
901877
{
902878
lastResult = ScriptEvaluate(subScript, ref isReturn, ref isBreak, ref isContinue);
903879

@@ -916,9 +892,9 @@ void ExecuteIfList()
916892
else if (keyword.Equals("for"))
917893
{
918894
void forAction(int index)
919-
{ if (keywordAttributes.Count > index && !keywordAttributes[index].Trim().Equals(string.Empty)) AssignationOrExpressionEval(keywordAttributes[index]); }
895+
{ if (keywordAttributes.Count > index && !keywordAttributes[index].Trim().Equals(string.Empty)) ManageJumpStatementsOrExpressionEval(keywordAttributes[index]); }
920896

921-
for (forAction(0); !isReturn && (bool)AssignationOrExpressionEval(keywordAttributes[1]); forAction(2))
897+
for (forAction(0); !isReturn && (bool)ManageJumpStatementsOrExpressionEval(keywordAttributes[1]); forAction(2))
922898
{
923899
lastResult = ScriptEvaluate(subScript, ref isReturn, ref isBreak, ref isContinue);
924900

@@ -1299,12 +1275,57 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
12991275
{
13001276
stack.Push(varValueToPush);
13011277
}
1302-
else if (Variables.TryGetValue(varFuncName, out dynamic cusVarValueToPush)
1278+
else if ((Variables.TryGetValue(varFuncName, out dynamic cusVarValueToPush)
1279+
|| (!varFuncMatch.Groups["inObject"].Success && varFuncMatch.Groups["assignationOperator"].Success))
13031280
&& (cusVarValueToPush == null || !TypesToBlock.Contains(cusVarValueToPush.GetType())))
13041281
{
13051282
stack.Push(cusVarValueToPush);
1306-
if (varFuncMatch.Groups["postfixOperator"].Success)
1307-
Variables[varFuncName] = varFuncMatch.Groups["postfixOperator"].Value.Equals("++") ? cusVarValueToPush + 1 : cusVarValueToPush - 1;
1283+
1284+
if (OptionVariableAssignationActive)
1285+
{
1286+
bool assign = true;
1287+
1288+
if (varFuncMatch.Groups["assignationOperator"].Success)
1289+
{
1290+
if (stack.Count > 1)
1291+
throw new ExpressionEvaluatorSyntaxErrorException("The left part of an assignation must be a variable, a property or an indexer.");
1292+
1293+
string rightExpression = expr.Substring(i);
1294+
i = expr.Length;
1295+
1296+
if (rightExpression.Trim().Equals(string.Empty))
1297+
throw new ExpressionEvaluatorSyntaxErrorException("Right part is missing in assignation");
1298+
1299+
if (varFuncMatch.Groups["assignmentPrefix"].Success)
1300+
{
1301+
if (!Variables.ContainsKey(varFuncName))
1302+
throw new ExpressionEvaluatorSyntaxErrorException($"The variable[{varFuncName}] do not exists.");
1303+
1304+
ExpressionOperator op = operatorsDictionary[varFuncMatch.Groups["assignmentPrefix"].Value];
1305+
1306+
cusVarValueToPush = operatorsEvaluations.Find(dict => dict.ContainsKey(op))[op](cusVarValueToPush, Evaluate(rightExpression));
1307+
}
1308+
else
1309+
{
1310+
cusVarValueToPush = Evaluate(rightExpression);
1311+
}
1312+
1313+
stack.Clear();
1314+
stack.Push(cusVarValueToPush);
1315+
}
1316+
else if (varFuncMatch.Groups["postfixOperator"].Success)
1317+
cusVarValueToPush = varFuncMatch.Groups["postfixOperator"].Value.Equals("++") ? cusVarValueToPush + 1 : cusVarValueToPush - 1;
1318+
else
1319+
assign = false;
1320+
1321+
if (assign)
1322+
Variables[varFuncName] = cusVarValueToPush;
1323+
}
1324+
else if (varFuncMatch.Groups["assignationOperator"].Success)
1325+
i -= varFuncMatch.Groups["assignationOperator"].Length;
1326+
else if (varFuncMatch.Groups["postfixOperator"].Success)
1327+
i -= varFuncMatch.Groups["postfixOperator"].Length;
1328+
13081329
}
13091330
else
13101331
{
@@ -1365,7 +1386,7 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
13651386
if (varFuncMatch.Groups["assignationOperator"].Success)
13661387
{
13671388
if (stack.Count > 1)
1368-
throw new ExpressionEvaluatorSyntaxErrorException();
1389+
throw new ExpressionEvaluatorSyntaxErrorException("The left part of an assignation must be a variable, a property or an indexer.");
13691390

13701391
string rightExpression = expr.Substring(i);
13711392
i = expr.Length;

0 commit comments

Comments
 (0)