Skip to content

Commit 30700fb

Browse files
corngoodjtschuster
andauthored
Fix file size estimation when bundling symlinks (#118732)
FileInfo.Length will return the size of a symlink, rather than the file itself. On a source-built dotnet SDK, a trivial test project will bundle files like: packs/Microsoft.NETCore.App.Runtime.linux-x64/10.0.0-preview.7.25380.108/runtimes/linux-x64/lib/net10.0/Microsoft.CSharp.dll Which is a symlink to: ../../../../../../../shared/Microsoft.NETCore.App/10.0.0-preview.7.25380.108/Microsoft.CSharp.dll This can result in failures when trying to bundle Fixes: b79c4fb Co-authored-by: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
1 parent 638f0a5 commit 30700fb

File tree

6 files changed

+34
-3
lines changed

6 files changed

+34
-3
lines changed

eng/Versions.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
<SystemThreadingAccessControlVersion>7.0.0</SystemThreadingAccessControlVersion>
9898
<!-- Keep toolset versions in sync with dotnet/msbuild and dotnet/sdk -->
9999
<MicrosoftBclAsyncInterfacesToolsetVersion>8.0.0</MicrosoftBclAsyncInterfacesToolsetVersion>
100+
<MicrosoftIoRedistToolsetVersion>6.0.1</MicrosoftIoRedistToolsetVersion>
100101
<SystemBuffersToolsetVersion>4.5.1</SystemBuffersToolsetVersion>
101102
<SystemCollectionsImmutableToolsetVersion>8.0.0</SystemCollectionsImmutableToolsetVersion>
102103
<SystemMemoryToolsetVersion>4.5.5</SystemMemoryToolsetVersion>

src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ void RewriteAppHost(MemoryMappedFile mappedFile, MemoryMappedViewAccessor access
124124
if (File.Exists(appHostDestinationFilePath))
125125
File.Delete(appHostDestinationFilePath);
126126

127-
long appHostSourceLength = new FileInfo(appHostSourceFilePath).Length;
127+
long appHostSourceLength = HostModelUtils.GetFileLength(appHostSourceFilePath);
128128
string destinationFileName = Path.GetFileName(appHostDestinationFilePath);
129129
// Memory-mapped files cannot be resized, so calculate
130130
// the maximum length of the destination file upfront.

src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ public string GenerateBundle(IReadOnlyList<FileSpec> fileSpecs)
293293
// We will memory map a larger file than needed, but we'll take that trade-off.
294294
foreach (var (spec, type) in relativePathToSpec)
295295
{
296-
bundledFilesSize += new FileInfo(spec.SourcePath).Length;
296+
bundledFilesSize += HostModelUtils.GetFileLength(spec.SourcePath);
297297
if (type == FileType.Assembly)
298298
{
299299
// Alignment could be as much as AssemblyAlignment - 1 bytes.
@@ -314,7 +314,7 @@ public string GenerateBundle(IReadOnlyList<FileSpec> fileSpecs)
314314
{
315315
Directory.CreateDirectory(destinationDirectory);
316316
}
317-
var hostLength = new FileInfo(hostSource).Length;
317+
var hostLength = HostModelUtils.GetFileLength(hostSource);
318318
var bundleManifestLength = Manifest.GetManifestLength(BundleManifest.BundleMajorVersion, relativePathToSpec.Select(x => x.Spec.BundleRelativePath));
319319
long bundleTotalSize = hostLength + bundledFilesSize + bundleManifestLength;
320320
if (_target.IsOSX && _macosCodesign)

src/installer/managed/Microsoft.NET.HostModel/HostModelUtils.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5+
#if NETFRAMEWORK
6+
using Microsoft.IO;
7+
#else
58
using System.IO;
9+
#endif
610
using System.Runtime.InteropServices;
711

12+
813
namespace Microsoft.NET.HostModel
914
{
1015
internal static class HostModelUtils
@@ -32,5 +37,11 @@ public static (int ExitCode, string StdErr) RunCodesign(string args, string appH
3237
return (p.ExitCode, p.StandardError.ReadToEnd());
3338
}
3439
}
40+
41+
public static long GetFileLength(string path)
42+
{
43+
var info = new FileInfo(path);
44+
return ((FileInfo)info.ResolveLinkTarget(true) ?? info).Length;
45+
}
3546
}
3647
}

src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<PackageDownloadAndReference Include="System.Memory" Version="$(SystemMemoryToolsetVersion)" Folder="lib/net461" />
2525
<PackageDownloadAndReference Include="System.Text.Json" Version="$(SystemTextJsonToolsetVersion)" Folder="lib/net462" />
2626
<PackageDownloadAndReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataToolsetVersion)" Folder="lib/net462" />
27+
<PackageDownloadAndReference Include="Microsoft.IO.Redist" Version="$(MicrosoftIoRedistToolsetVersion)" Folder="lib/net472" />
2728
</ItemGroup>
2829

2930
<ItemGroup>

src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,24 @@ public void ExactDuplicateEntries()
9898
bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("rel/system.repeat.dll")).Single().Type.Should().Be(FileType.Assembly);
9999
}
100100

101+
[Fact]
102+
public void ResolveLinkTargets()
103+
{
104+
string appPath = Path.Combine(
105+
Path.GetDirectoryName(sharedTestState.App.AppDll),
106+
Path.GetFileNameWithoutExtension(sharedTestState.App.AppDll)
107+
+ ".link" + Path.GetExtension(sharedTestState.App.AppDll));
108+
File.CreateSymbolicLink(appPath, sharedTestState.App.AppDll);
109+
// File specification with duplicate entries with matching source paths
110+
var fileSpecs = new FileSpec[]
111+
{
112+
new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
113+
new FileSpec(appPath, "rel/app.repeat.dll")
114+
};
115+
Bundler bundler = CreateBundlerInstance();
116+
bundler.GenerateBundle(fileSpecs);
117+
}
118+
101119
[Fact]
102120
public void DuplicateBundleRelativePath_Fails()
103121
{

0 commit comments

Comments
 (0)