From 61b8ddb162a36f57bbd1cf3246bfa6b5c8f877f7 Mon Sep 17 00:00:00 2001 From: Ladi Prosek Date: Wed, 5 May 2021 22:53:04 +0200 Subject: [PATCH] Fix NullReferenceException when expanding property functions that return null --- .../Evaluation/Expander_Tests.cs | 9 +++++--- src/Build/Evaluation/Expander.cs | 21 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Build.UnitTests/Evaluation/Expander_Tests.cs b/src/Build.UnitTests/Evaluation/Expander_Tests.cs index 76dd7380d59..71d15858f3c 100644 --- a/src/Build.UnitTests/Evaluation/Expander_Tests.cs +++ b/src/Build.UnitTests/Evaluation/Expander_Tests.cs @@ -2010,13 +2010,16 @@ public void PropertyFunctionNullArgument() public void PropertyFunctionNullReturn() { PropertyDictionary pg = new PropertyDictionary(); - pg.Set(ProjectPropertyInstance.Create("SomeStuff", "This IS SOME STUff")); Expander expander = new Expander(pg, FileSystems.Default); - string result = expander.ExpandIntoStringLeaveEscaped("$([System.Convert]::ChangeType(,$(SomeStuff.GetType())))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance); - + // The null-returning function is the only thing in the expression. + string result = expander.ExpandIntoStringLeaveEscaped("$([System.Environment]::GetEnvironmentVariable(`_NonExistentVar`))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance); Assert.Equal("", result); + + // The result of the null-returning function is concatenated with a non-empty string. + result = expander.ExpandIntoStringLeaveEscaped("prefix_$([System.Environment]::GetEnvironmentVariable(`_NonExistentVar`))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance); + Assert.Equal("prefix_", result); } /// diff --git a/src/Build/Evaluation/Expander.cs b/src/Build/Evaluation/Expander.cs index 5fa15be5d91..80ddea0b0c2 100644 --- a/src/Build/Evaluation/Expander.cs +++ b/src/Build/Evaluation/Expander.cs @@ -1200,19 +1200,22 @@ internal static object ExpandPropertiesLeaveTypedAndEscaped( propertyValue = LookupProperty(properties, expression, propertyStartIndex + 2, propertyEndIndex - 1, elementLocation, usedUninitializedProperties); } - if (IsTruncationEnabled(options) && propertyValue != null) + if (propertyValue != null) { - var value = propertyValue.ToString(); - if (value.Length > CharacterLimitPerExpansion) + if (IsTruncationEnabled(options)) { - propertyValue = value.Substring(0, CharacterLimitPerExpansion - 3) + "..."; + var value = propertyValue.ToString(); + if (value.Length > CharacterLimitPerExpansion) + { + propertyValue = value.Substring(0, CharacterLimitPerExpansion - 3) + "..."; + } } - } - // Record our result, and advance - // our sourceIndex pointer to the character just after the closing - // parenthesis. - results.Add(propertyValue); + // Record our result, and advance + // our sourceIndex pointer to the character just after the closing + // parenthesis. + results.Add(propertyValue); + } sourceIndex = propertyEndIndex + 1; }