Skip to content

Commit 5a1f1d2

Browse files
[release/11.0.1xx-preview1] Source code updates from dotnet/sdk (#4531)
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
1 parent c87e49a commit 5a1f1d2

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

src/sdk/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -834,8 +834,8 @@ Copyright (c) .NET Foundation. All rights reserved.
834834
<!-- Preserve existing TargetPath if already set, otherwise compute it -->
835835
<TargetPath Condition="'%(Content.TargetPath)' != ''">%(Content.TargetPath)</TargetPath>
836836
<TargetPath Condition="'%(Content.TargetPath)' == '' and '%(Content.Link)' != ''">%(Content.Link)</TargetPath>
837-
<TargetPath Condition="'%(Content.TargetPath)' == '' and '%(Content.Link)' == '' and '%(Content.DefiningProjectDirectory)' != '' and '%(Content.DefiningProjectFullPath)' != ''">$([MSBuild]::MakeRelative(%(Content.DefiningProjectDirectory), %(Content.FullPath)))</TargetPath>
838-
<TargetPath Condition="'%(Content.TargetPath)' == '' and '%(Content.Link)' == '' and ('%(Content.DefiningProjectDirectory)' == '' or '%(Content.DefiningProjectFullPath)' == '')">$([MSBuild]::MakeRelative($(MSBuildProjectDirectory), %(Content.FullPath)))</TargetPath>
837+
<!-- Use MSBuildProjectDirectory as the base for relative path computation. DefiningProjectDirectory can point to sdk targets folder and lead to unexpected paths. -->
838+
<TargetPath Condition="'%(Content.TargetPath)' == '' and '%(Content.Link)' == ''">$([MSBuild]::MakeRelative($(MSBuildProjectDirectory), %(Content.FullPath)))</TargetPath>
839839
</_ContentWithPublishMetadata>
840840

841841
<ContentWithTargetPath Include="@(_ContentWithPublishMetadata)" />

src/sdk/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishWithIfDifferent.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,5 +381,79 @@ public void It_handles_IfDifferent_with_self_contained_publish()
381381
publishDirectory.Should().HaveFile("appdata.txt");
382382
File.ReadAllText(Path.Combine(publishDirectory.FullName, "appdata.txt")).Should().Be("Application data");
383383
}
384+
385+
[Fact]
386+
public void It_publishes_content_from_imported_targets_with_correct_path()
387+
{
388+
// This test verifies that Content items introduced from imported .targets files
389+
// (where DefiningProjectDirectory differs from MSBuildProjectDirectory) are
390+
// published with the correct project-relative path and do not escape the publish directory.
391+
//
392+
// The bug scenario: when a .targets file OUTSIDE the project directory adds a Content item,
393+
// using DefiningProjectDirectory to compute the relative path can result in paths with '..'
394+
// segments that escape the publish directory.
395+
396+
var testProject = new TestProject()
397+
{
398+
Name = "PublishImportedContent",
399+
TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
400+
IsExe = true
401+
};
402+
403+
testProject.SourceFiles["Program.cs"] = "class Program { static void Main() { } }";
404+
405+
var testAsset = _testAssetsManager.CreateTestProject(testProject);
406+
407+
var projectDirectory = Path.Combine(testAsset.Path, testProject.Name);
408+
409+
// Create the imported targets file OUTSIDE the project directory (sibling folder)
410+
// This is the key difference - DefiningProjectDirectory will be different from MSBuildProjectDirectory
411+
var externalImportsDir = Path.Combine(testAsset.Path, "ExternalImports");
412+
Directory.CreateDirectory(externalImportsDir);
413+
414+
// Create the content file in the project directory (where we want it to be published from)
415+
var contentFile = Path.Combine(projectDirectory, "project-content.txt");
416+
File.WriteAllText(contentFile, "Content defined by external targets");
417+
418+
// Create an imported .targets file OUTSIDE the project that adds a Content item
419+
// pointing to a file in the project directory. The issue is that DefiningProjectDirectory
420+
// will be ExternalImports/, not the project directory.
421+
var importedTargetsFile = Path.Combine(externalImportsDir, "ImportedContent.targets");
422+
File.WriteAllText(importedTargetsFile, $@"<Project>
423+
<ItemGroup>
424+
<!-- This Content item points to a file in the main project directory, but is defined in external .targets -->
425+
<Content Include=""$(MSBuildProjectDirectory)\project-content.txt"" CopyToPublishDirectory=""IfDifferent"" />
426+
</ItemGroup>
427+
</Project>");
428+
429+
// Update the main project file to import the external targets
430+
var projectFile = Path.Combine(projectDirectory, $"{testProject.Name}.csproj");
431+
var projectContent = File.ReadAllText(projectFile);
432+
projectContent = projectContent.Replace("</Project>", @"
433+
<Import Project=""..\ExternalImports\ImportedContent.targets"" />
434+
</Project>");
435+
File.WriteAllText(projectFile, projectContent);
436+
437+
var publishCommand = new PublishCommand(testAsset);
438+
var publishResult = publishCommand.Execute();
439+
440+
publishResult.Should().Pass();
441+
442+
var publishDirectory = publishCommand.GetOutputDirectory(testProject.TargetFrameworks);
443+
444+
// The content file should be published with a simple filename, not with path segments
445+
// that could escape the publish directory (e.g., "..\PublishImportedContent\project-content.txt")
446+
publishDirectory.Should().HaveFile("project-content.txt");
447+
448+
// Verify the content is correct
449+
var publishedContentPath = Path.Combine(publishDirectory.FullName, "project-content.txt");
450+
File.ReadAllText(publishedContentPath).Should().Be("Content defined by external targets");
451+
452+
// Ensure no files escaped to parent directories
453+
var parentDir = Directory.GetParent(publishDirectory.FullName);
454+
var potentialEscapedFiles = Directory.GetFiles(parentDir.FullName, "project-content.txt", SearchOption.AllDirectories)
455+
.Where(f => !f.StartsWith(publishDirectory.FullName));
456+
potentialEscapedFiles.Should().BeEmpty("Content file should not escape to directories outside publish folder");
457+
}
384458
}
385459
}

src/source-manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@
9191
"commitSha": "2c0dd466fa060a772a87b9c433495ec0c559d19c"
9292
},
9393
{
94-
"barId": 298857,
94+
"barId": 299351,
9595
"path": "sdk",
9696
"remoteUri": "https://github.com/dotnet/sdk",
97-
"commitSha": "94c6e508ea4283e5854811b06b16d5209a092556"
97+
"commitSha": "768aa8ea6c55d78db4df38414e667cad66957a5f"
9898
},
9999
{
100100
"barId": 298520,

0 commit comments

Comments
 (0)