Skip to content

dotnet-getdocument invocation, improper path handling on Windows in Microsoft.Extensions.ApiDescription.Server.targets breaks build #59749

@dlosch

Description

@dlosch

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

The microsoft.extensions.apidescription.server NuGet in src\Tools\Extensions.ApiDescription.Server\src\build\Microsoft.Extensions.ApiDescription.Server.targets has an improper handling of directory separators when executing the dotnet-getdocument.dll tool on Windows.

This breaks the build on Windows, if the value of OpenApiDocumentsDirectory ends in a Linux-style directory separator (/)

microsoft.extensions.apidescription.server NuGet version: 9.0.0

Thanks.

Expected Behavior

Build should behave the same on Windows and Linux.

Steps To Reproduce

Bug occurs when

  • Build runs on Windows
  • OpenApiDocumentsDirectory has a path ending with a Linux-style directory separator /, for example <OpenApiDocumentsDirectory>../openapi/</OpenApiDocumentsDirectory> in my .csproj

Where and why does the bug occur
File: src\Tools\Extensions.ApiDescription.Server\src\build\Microsoft.Extensions.ApiDescription.Server.targets

    <PropertyGroup>
      <_DotNetGetDocumentOutputPath>$(OpenApiDocumentsDirectory.TrimEnd('\'))</_DotNetGetDocumentOutputPath>
      <_DotNetGetDocumentOutputPath>$([System.IO.Path]::GetFullPath('$(_DotNetGetDocumentOutputPath)'))</_DotNetGetDocumentOutputPath>

This trims the trailing separator if and only the separator already is a Windows-style backslash. If it is a Linux style /, nothing gets trimmed. the Linux style path ../openapi/ gets translated to a Windows style path by $([System.IO.Path]::GetFullPath. This results in _DotNetGetDocumentOutputPath containing a path with a trailing \, which breaks the command line the target generates (because it results in \", escaping the closing ").

Exceptions (if any)

Proposed Fix:
in src\Tools\Extensions.ApiDescription.Server\src\build\Microsoft.Extensions.ApiDescription.Server.targets, the .TrimEnd('\') needs to go after the $([System.IO.Path]::GetFullPath('$(_DotNetGetDocumentOutputPath)')), because the latter translates / to \ on windows. Hence if the initial path ends with /, nothing gets trimmed, then GetFullPath translates the / to \ on windows, and the command line contains an escaped " (\").

.NET Version

9.0.200-preview.0.24575.35

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-commandlinetoolsIncludes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPIfeature-openapi

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions