未验证 提交 21749e86 编写于 作者: D Dustin Campbell 提交者: GitHub

Merge pull request #30560 from DustinCampbell/issue-29494

Ensure that MSBuildWorkspace is resilient against malformed paths
......@@ -408,10 +408,16 @@ private IEnumerable<AnalyzerReference> ResolveAnalyzerReferences(CommandLineArgu
foreach (var path in commandLineArgs.AnalyzerReferences.Select(r => r.FilePath))
{
var fullPath = Path.GetFullPath(path);
if (File.Exists(fullPath))
string fullPath;
if (PathUtilities.IsAbsolute(path))
{
analyzerLoader.AddDependencyLocation(fullPath);
fullPath = FileUtilities.TryNormalizeAbsolutePath(path);
if (fullPath != null && File.Exists(fullPath))
{
analyzerLoader.AddDependencyLocation(fullPath);
}
}
}
......
......@@ -65,7 +65,7 @@ public bool TryGetAbsoluteProjectPath(string path, string baseDirectory, Diagnos
return true;
}
private string GetAbsolutePath(string path, string baseDirectory)
=> Path.GetFullPath(FileUtilities.ResolveRelativePath(path, baseDirectory) ?? path);
private static string GetAbsolutePath(string path, string baseDirectory)
=> FileUtilities.NormalizeAbsolutePath(FileUtilities.ResolveRelativePath(path, baseDirectory) ?? path);
}
}
......@@ -118,8 +118,9 @@ protected string GetDocumentFilePath(MSB.Framework.ITaskItem documentItem)
protected string GetAbsolutePath(string path)
{
var directoryPath = PathUtilities.GetDirectoryName(Project.FullPath);
return Path.GetFullPath(FileUtilities.ResolveRelativePath(path, directoryPath) ?? path);
var baseDirectory = PathUtilities.GetDirectoryName(Project.FullPath);
var absolutePath = FileUtilities.ResolveRelativePath(path, baseDirectory) ?? path;
return FileUtilities.TryNormalizeAbsolutePath(absolutePath) ?? absolutePath;
}
protected void ReadAdditionalFiles()
......
......@@ -199,7 +199,7 @@ private string GetAbsolutePathRelativeToProject(string path)
{
// TODO (tomat): should we report an error when drive-relative path (e.g. "C:goo.cs") is encountered?
var absolutePath = FileUtilities.ResolveRelativePath(path, _projectDirectory) ?? path;
return Path.GetFullPath(absolutePath);
return FileUtilities.TryNormalizeAbsolutePath(absolutePath) ?? absolutePath;
}
private string GetDocumentFilePath(MSB.Framework.ITaskItem documentItem)
......@@ -234,27 +234,31 @@ protected static string GetDocumentLogicalPath(MSB.Framework.ITaskItem documentI
}
else
{
var result = documentItem.ItemSpec;
if (Path.IsPathRooted(result))
var filePath = documentItem.ItemSpec;
if (!PathUtilities.IsAbsolute(filePath))
{
// If we have an absolute path, there are two possibilities:
result = Path.GetFullPath(result);
// If the document is within the current project directory (or subdirectory), then the logical path is the relative path
// from the project's directory.
if (result.StartsWith(projectDirectory, StringComparison.OrdinalIgnoreCase))
{
result = result.Substring(projectDirectory.Length);
}
else
{
// if the document lies outside the project's directory (or subdirectory) then place it logically at the root of the project.
// if more than one document ends up with the same logical name then so be it (the workspace will survive.)
return Path.GetFileName(result);
}
return filePath;
}
return result;
var normalizedPath = FileUtilities.TryNormalizeAbsolutePath(filePath);
if (normalizedPath == null)
{
return filePath;
}
// If the document is within the current project directory (or subdirectory), then the logical path is the relative path
// from the project's directory.
if (normalizedPath.StartsWith(projectDirectory, StringComparison.OrdinalIgnoreCase))
{
return normalizedPath.Substring(projectDirectory.Length);
}
else
{
// if the document lies outside the project's directory (or subdirectory) then place it logically at the root of the project.
// if more than one document ends up with the same logical name then so be it (the workspace will survive.)
return PathUtilities.GetFileName(normalizedPath);
}
}
}
......
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{CE26EDB5-9F46-46D4-8EC0-9BC9293A8BE8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MalformedProject</RootNamespace>
<AssemblyName>MalformedProject</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="ValidAdditionalFile.txt" />
<AdditionalFiles Include="TEST::" />
<AdditionalFiles Include="COM1" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
......@@ -126,6 +126,7 @@ public static class CSharp
public static string ExternAlias2 => GetText("ProjectFiles.CSharp.ExternAlias2.csproj");
public static string ForEmittedOutput => GetText("ProjectFiles.CSharp.ForEmittedOutput.csproj");
public static string MsbuildError => GetText("ProjectFiles.CSharp.MsbuildError.csproj");
public static string MallformedAdditionalFilePath => GetText("ProjectFiles.CSharp.MallformedAdditionalFilePath.csproj");
public static string NetCoreApp2_Project => GetText("NetCoreApp2.Project.csproj");
public static string NetCoreApp2AndLibrary_Project => GetText("NetCoreApp2AndLibrary.Project.csproj");
public static string NetCoreApp2AndLibrary_Library => GetText("NetCoreApp2AndLibrary.Library.csproj");
......@@ -206,6 +207,11 @@ public static class FSharp
public static string NetCoreMultiTFM_ProjectReferenceToFSharp_FSharpLib_Library = GetText("NetCoreMultiTFM_ProjectReferenceToFSharp.fsharplib.Library.fs");
}
public static class Text
{
public static string ValidAdditionalFile => GetText("SourceFiles.Text.ValidAdditionalFile.txt");
}
public static class VisualBasic
{
public static string Application => GetText("SourceFiles.VisualBasic.Application.myapp");
......
......@@ -3579,6 +3579,30 @@ public async Task TestOpenSolution_ProjectReferencesWithUnconventionalOutputPath
}
}
[ConditionalFact(typeof(VisualStudioMSBuildInstalled)), Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)]
[WorkItem(29494, "https://github.com/dotnet/roslyn/issues/29494")]
public async Task TestOpenProjectAsync_MalformedAdditionalFilePath()
{
var files = GetSimpleCSharpSolutionFiles()
.WithFile(@"CSharpProject\CSharpProject.csproj", Resources.ProjectFiles.CSharp.MallformedAdditionalFilePath)
.WithFile(@"CSharpProject\ValidAdditionalFile.txt", Resources.SourceFiles.Text.ValidAdditionalFile);
CreateFiles(files);
var projectFilePath = GetSolutionFileName(@"CSharpProject\CSharpProject.csproj");
using (var workspace = CreateMSBuildWorkspace())
{
var project = await workspace.OpenProjectAsync(projectFilePath);
// Project should open without an exception being thrown.
Assert.NotNull(project);
Assert.Contains(project.AdditionalDocuments, doc => doc.Name == "COM1");
Assert.Contains(project.AdditionalDocuments, doc => doc.Name == "TEST::");
}
}
private class InMemoryAssemblyLoader : IAnalyzerAssemblyLoader
{
public void AddDependencyLocation(string fullPath)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册