diff --git a/OpenRA.Game/Support/VariableExpression.cs b/OpenRA.Game/Support/VariableExpression.cs index bd3844dc08..56ee524e2e 100644 --- a/OpenRA.Game/Support/VariableExpression.cs +++ b/OpenRA.Game/Support/VariableExpression.cs @@ -334,6 +334,15 @@ namespace OpenRA.Support return false; } + static TokenType VariableOrKeyword(string expression, int start, ref int i) + { + if (CharClassOf(expression[i - 1]) == CharClass.Mixed) + throw new InvalidDataException("Invalid identifier end character at index {0} for `{1}`".F( + i - 1, expression.Substring(start, i - start))); + + return VariableOrKeyword(expression, start, i - start); + } + static TokenType VariableOrKeyword(string expression, int start, int length) { var i = start; @@ -464,10 +473,10 @@ namespace OpenRA.Support { cc = CharClassOf(expression[i]); if (cc == CharClass.Whitespace || cc == CharClass.Operator) - return VariableOrKeyword(expression, start, i - start); + return VariableOrKeyword(expression, start, ref i); } - return VariableOrKeyword(expression, start, i - start); + return VariableOrKeyword(expression, start, ref i); } public static Token GetNext(string expression, ref int i, TokenType lastType = TokenType.Invalid) diff --git a/OpenRA.Test/OpenRA.Game/VariableExpressionTest.cs b/OpenRA.Test/OpenRA.Game/VariableExpressionTest.cs index 9ed8aae81a..0b9da2243a 100644 --- a/OpenRA.Test/OpenRA.Game/VariableExpressionTest.cs +++ b/OpenRA.Test/OpenRA.Game/VariableExpressionTest.cs @@ -351,13 +351,24 @@ namespace OpenRA.Test public void TestParseHyphenErrors() { AssertParseFailure("-", "Missing value or sub-expression at end for `-` operator"); - AssertParseFailure("t- 1", "Missing binary operation before `1` at index 3"); - AssertParseFailure("t -1", "Missing binary operation before `-1` at index 2"); AssertParseFailure("-1-1", "Missing binary operation before `-1` at index 2"); AssertParseFailure("5-1", "Missing binary operation before `-1` at index 1"); AssertParseFailure("6 -3", "Missing binary operation before `-3` at index 2"); } + [TestCase(TestName = "Test mixed charaters at end of identifier parser errors")] + public void TestParseMixedEndErrors() + { + AssertParseFailure("t- 1", "Invalid identifier end character at index 1 for `t-`"); + AssertParseFailure("t-", "Invalid identifier end character at index 1 for `t-`"); + AssertParseFailure("t. 1", "Invalid identifier end character at index 1 for `t.`"); + AssertParseFailure("t.", "Invalid identifier end character at index 1 for `t.`"); + AssertParseFailure("t@ 1", "Invalid identifier end character at index 1 for `t@`"); + AssertParseFailure("t@", "Invalid identifier end character at index 1 for `t@`"); + AssertParseFailure("t$ 1", "Invalid identifier end character at index 1 for `t$`"); + AssertParseFailure("t$", "Invalid identifier end character at index 1 for `t$`"); + } + [TestCase(TestName = "Undefined symbols are treated as `false` (0) values")] public void TestUndefinedSymbols() {