dotnet / dotnet/msbuild

Unescape Intrinsic Property Function Does Double-Unescaping

Open
#4,086 0 comments 3 reactions 0 assignees View on GitHub
triaged
Dominant language
C#
Stars
5.5k
Forks
1.5k
Avg merge
1d 6h
Merged PRs (30d)
139

Description

By calling the `Unescape` intrinsic property function (as in `$([MSBuild]::Unescape(...))`), I expect it to do one level of unescaping.

But I'm getting double unescaping instead. So turns out I have to do `Escape` twice on the data I'm feeding into the function to get the raw string back. This is not intuitive.

I guess this happens because one level of unescaping is done in ``Microsoft.Build.Evaluation.Expander`2+Function`1::Execute`` when preparing the argument (`args[n] = EscapingUtilities.UnescapeAll(argumentValue);`), and the second level of unescaping happens when the `Unescape` intrinsic function itself gets actually executed. Seems like it should have been a no-op function.

### Steps to reproduce

Suppose we're trying to load a task from a DLL in the folder named `$(The%20Folder)` (literally, with these `$` and `%` characters on disk, why not). You do not need the task DLL, just consider the path and match to the error messages when the task DLL is not found -- we need to get the desired path in the error message.

I've chosen `UsingTask` for this example because it skips unescaping on its path argument and thus avoids an extra level of possible unescaping.

Run the project file:
```xml





```

### Expected behavior

`... task could not be loaded from the assembly C:\$(The%20Folder)\Task.dll …` if the first `UsingTask` unescapes only one level of escaping.

### Actual behavior

`... task could not be loaded from the assembly C:\$(The Folder)\Task.dll …`, as two levels of escaping have been lifted.

If the first `UsingTask` element is commented out to let the second one work (that's doubly-escaped), we see the expected result.

### Environment data
`msbuild /version` output:
```
Microsoft (R) Build Engine version 15.8.169+g1ccb72aefa for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

15.8.169.51996
```
OS info: `Microsoft Windows [Version 10.0.17134.523]`

If applicable, version of the tool that invokes MSBuild (Visual Studio, dotnet CLI, etc):

PS What would be the proper workaround, safest around different MSBuild versions out there starting with v4.0, to emit a project file which would pass the task path correctly?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.