From 8d2ad3c4609b78acbcc654b5787f6530ed3e4348 Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Thu, 21 Nov 2013 23:17:09 +0900 Subject: [PATCH] Fix bogus expression tokenizer that failed at parenthesized expressions with And/Or. --- .../Microsoft.Build.Internal/ExpressionParser.jay | 3 ++- .../ExpressionParserManual.cs | 13 +++++++------ .../Microsoft.Build.Internal/ExpressionTokenizer.cs | 1 + .../ExpressionParserTest.cs | 4 ++++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParser.jay b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParser.jay index 1b3cd3db18d..d93ecb340e7 100644 --- a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParser.jay +++ b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParser.jay @@ -73,7 +73,7 @@ namespace Microsoft.Build.Internal { class ExpressionParser { - const int yacc_verbose_flag = 0; + static readonly int yacc_verbose_flag = Environment.GetEnvironmentVariable ("MONO_MSBUILD_PARSER_DEBUG") == "1" ? 1 : 0; object debug_obj = yacc_verbose_flag == 0 ? null : new yydebug.yyDebugSimple (); @@ -169,6 +169,7 @@ PrimaryExpression | MetadataAccessExpression | RawStringLiteralOrFunction | ParenthesizedExpression + ; BooleanLiteral : TRUE_LITERAL diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParserManual.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParserManual.cs index 6e5526cef30..83d4e9b1565 100644 --- a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParserManual.cs +++ b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParserManual.cs @@ -105,12 +105,13 @@ namespace Microsoft.Build.Internal goto default; start++; last = FindMatchingCloseParen (start, end); - if (last < 0) - if (validation_type == ExpressionValidationType.StrictBoolean) - throw new InvalidProjectFileException (string.Format ("expression did not have matching ')' since index {0} in \"{1}\"", start, source)); - else { - start--; - goto default; // treat as raw literal to the section end + if (last < 0) { + if (validation_type == ExpressionValidationType.StrictBoolean) + throw new InvalidProjectFileException (string.Format ("expression did not have matching ')' since index {0} in \"{1}\"", start, source)); + else { + start--; + goto default; // treat as raw literal to the section end + } } var contents = Parse (start, last).ToArray (); if (contents.Length > 1) diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionTokenizer.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionTokenizer.cs index a1bb0101dc2..6820cc467d1 100644 --- a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionTokenizer.cs +++ b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionTokenizer.cs @@ -98,6 +98,7 @@ namespace Microsoft.Build.Internal TokenForItemPropertyValue ("]", Token.BRACE_CLOSE); break; case '(': + modes.Push (TokenizerMode.Default); TokenForItemPropertyValue ("(", Token.PAREN_OPEN); break; case ')': diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Internal/ExpressionParserTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Internal/ExpressionParserTest.cs index fbf435c0f15..0f55735aec4 100644 --- a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Internal/ExpressionParserTest.cs +++ b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Internal/ExpressionParserTest.cs @@ -84,6 +84,10 @@ namespace MonoTests.Microsoft.Build.Internal "$([System.String]::Format('True'))", "$([System.String]::Format('True', null))", "False And True == True And True", + "True or True or False", + "(True or True or False)", + "True and False", + "(True) and (False)", }; string [] depends = { // valid only if evaluated to boolean -- 2.25.1