Skip to content

Commit b5ccd89

Browse files
authored
Merge pull request #116499 from vseanreesermsft/internal-merge-9.0-2025-06-10-1320
Merging internal commits for release/9.0
2 parents 15af865 + 2ce8b42 commit b5ccd89

File tree

9 files changed

+133
-6
lines changed

9 files changed

+133
-6
lines changed

src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,35 @@ public void ActivateClass_IgnoreAppLocalHostFxr()
111111
}
112112
}
113113

114+
[Fact]
115+
public void ActivateClass_IgnoreWorkingDirectory()
116+
{
117+
using (TestArtifact cwd = TestArtifact.Create("cwd"))
118+
{
119+
// Validate that hosting components in the working directory will not be used
120+
File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName));
121+
File.Copy(Binaries.HostFxr.MockPath_5_0, Path.Combine(cwd.Location, Binaries.HostFxr.FileName));
122+
File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName));
123+
124+
string[] args = {
125+
"comhost",
126+
"synchronous",
127+
"1",
128+
sharedState.ComHostPath,
129+
sharedState.ClsidString
130+
};
131+
sharedState.CreateNativeHostCommand(args, TestContext.BuiltDotNet.BinPath)
132+
.WorkingDirectory(cwd.Location)
133+
.Execute()
134+
.Should().Pass()
135+
.And.HaveStdOutContaining("New instance of Server created")
136+
.And.HaveStdOutContaining($"Activation of {sharedState.ClsidString} succeeded.")
137+
.And.ResolveHostFxr(TestContext.BuiltDotNet)
138+
.And.ResolveHostPolicy(TestContext.BuiltDotNet)
139+
.And.ResolveCoreClr(TestContext.BuiltDotNet);
140+
}
141+
}
142+
114143
[Fact]
115144
public void ActivateClass_ValidateIErrorInfoResult()
116145
{

src/installer/tests/HostActivation.Tests/NativeHosting/Ijwhost.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,32 @@ public void LoadLibrary_ContextConfig(bool load_isolated)
8989
}
9090
}
9191

92+
[Fact]
93+
public void LoadLibrary_IgnoreWorkingDirectory()
94+
{
95+
using (TestArtifact cwd = TestArtifact.Create("cwd"))
96+
{
97+
// Validate that hosting components in the working directory will not be used
98+
File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName));
99+
File.Copy(Binaries.HostFxr.MockPath_5_0, Path.Combine(cwd.Location, Binaries.HostFxr.FileName));
100+
File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName));
101+
102+
string [] args = {
103+
"ijwhost",
104+
sharedState.IjwApp.AppDll,
105+
"NativeEntryPoint"
106+
};
107+
sharedState.CreateNativeHostCommand(args, TestContext.BuiltDotNet.BinPath)
108+
.WorkingDirectory(cwd.Location)
109+
.Execute()
110+
.Should().Pass()
111+
.And.HaveStdOutContaining("[C++/CLI] NativeEntryPoint: calling managed class")
112+
.And.HaveStdOutContaining("[C++/CLI] ManagedClass: AssemblyLoadContext = \"Default\" System.Runtime.Loader.DefaultAssemblyLoadContext")
113+
.And.ResolveHostFxr(TestContext.BuiltDotNet)
114+
.And.ResolveHostPolicy(TestContext.BuiltDotNet)
115+
.And.ResolveCoreClr(TestContext.BuiltDotNet);
116+
}
117+
}
92118

93119
[Fact]
94120
public void LoadLibraryWithoutRuntimeConfigButActiveRuntime()

src/installer/tests/HostActivation.Tests/NativeHosting/LoadAssemblyAndGetFunctionPointer.cs

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

44
using System.Collections.Generic;
5+
using System.IO;
56
using System.Linq;
67

78
using Microsoft.DotNet.Cli.Build.Framework;
@@ -231,6 +232,37 @@ public void CallDelegateOnComponentContext_UnhandledException()
231232
.And.ExecuteFunctionPointerWithException(entryPoint, 1);
232233
}
233234

235+
[Fact]
236+
public void CallDelegateOnComponentContext_IgnoreWorkingDirectory()
237+
{
238+
using (TestArtifact cwd = TestArtifact.Create("cwd"))
239+
{
240+
// Validate that hosting components in the working directory will not be used
241+
File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName));
242+
File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName));
243+
244+
var component = sharedState.Component;
245+
string[] args =
246+
{
247+
ComponentLoadAssemblyAndGetFunctionPointerArg,
248+
sharedState.HostFxrPath,
249+
component.RuntimeConfigJson,
250+
component.AppDll,
251+
sharedState.ComponentTypeName,
252+
sharedState.ComponentEntryPoint1,
253+
};
254+
255+
sharedState.CreateNativeHostCommand(args, sharedState.DotNetRoot)
256+
.WorkingDirectory(cwd.Location)
257+
.Execute()
258+
.Should().Pass()
259+
.And.InitializeContextForConfig(component.RuntimeConfigJson)
260+
.And.ExecuteFunctionPointer(sharedState.ComponentEntryPoint1, 1, 1)
261+
.And.ResolveHostPolicy(TestContext.BuiltDotNet)
262+
.And.ResolveCoreClr(TestContext.BuiltDotNet);
263+
}
264+
}
265+
234266
public class SharedTestState : SharedTestStateBase
235267
{
236268
public string HostFxrPath { get; }

src/installer/tests/HostActivation.Tests/NativeHosting/FunctionPointerResultExtensions.cs renamed to src/installer/tests/HostActivation.Tests/NativeHosting/NativeHostingResultExtensions.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.IO;
56

67
namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting
78
{
8-
internal static class FunctionPointerResultExtensions
9+
internal static class NativeHostingResultExtensions
910
{
1011
public static FluentAssertions.AndConstraint<CommandResultAssertions> ExecuteFunctionPointer(this CommandResultAssertions assertion, string methodName, int callCount, int returnValue)
1112
{
@@ -47,5 +48,21 @@ public static FluentAssertions.AndConstraint<CommandResultAssertions> ExecuteWit
4748
{
4849
return assertion.HaveStdOutContaining($"{assemblyName}: Location = '{location}'");
4950
}
51+
52+
public static FluentAssertions.AndConstraint<CommandResultAssertions> ResolveHostFxr(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet)
53+
{
54+
return assertion.HaveStdErrContaining($"Resolved fxr [{dotnet.GreatestVersionHostFxrFilePath}]");
55+
}
56+
57+
public static FluentAssertions.AndConstraint<CommandResultAssertions> ResolveHostPolicy(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet)
58+
{
59+
return assertion.HaveStdErrContaining($"{Binaries.HostPolicy.FileName} directory is [{dotnet.GreatestVersionSharedFxPath}]");
60+
}
61+
62+
public static FluentAssertions.AndConstraint<CommandResultAssertions> ResolveCoreClr(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet)
63+
{
64+
return assertion.HaveStdErrContaining($"CoreCLR path = '{Path.Combine(dotnet.GreatestVersionSharedFxPath, Binaries.CoreClr.FileName)}'")
65+
.And.HaveStdErrContaining($"CoreCLR dir = '{dotnet.GreatestVersionSharedFxPath}{Path.DirectorySeparatorChar}'");
66+
}
5067
}
5168
}

src/native/corehost/apphost/standalone/hostfxr_resolver.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ hostfxr_resolver_t::hostfxr_resolver_t(const pal::string_t& app_root)
118118
{
119119
m_status_code = StatusCode::CoreHostLibMissingFailure;
120120
}
121+
else if (!pal::is_path_rooted(m_fxr_path))
122+
{
123+
// We should always be loading hostfxr from an absolute path
124+
m_status_code = StatusCode::CoreHostLibMissingFailure;
125+
}
121126
else if (pal::load_library(&m_fxr_path, &m_hostfxr_dll))
122127
{
123128
m_status_code = StatusCode::Success;

src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ int hostpolicy_resolver::load(
180180
return StatusCode::CoreHostLibMissingFailure;
181181
}
182182

183+
// We should always be loading hostpolicy from an absolute path
184+
if (!pal::is_path_rooted(host_path))
185+
return StatusCode::CoreHostLibMissingFailure;
186+
183187
// Load library
184188
// We expect to leak hostpolicy - just as we do not unload coreclr, we do not unload hostpolicy
185189
if (!pal::load_library(&host_path, &g_hostpolicy))

src/native/corehost/fxr_resolver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ int load_fxr_and_get_delegate(hostfxr_delegate_type type, THostPathToConfigCallb
5555
return StatusCode::CoreHostLibMissingFailure;
5656
}
5757

58+
// We should always be loading hostfxr from an absolute path
59+
if (!pal::is_path_rooted(fxr_path))
60+
return StatusCode::CoreHostLibMissingFailure;
61+
5862
// Load library
5963
if (!pal::load_library(&fxr_path, &fxr))
6064
{

src/native/corehost/hostpolicy/deps_resolver.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -830,15 +830,21 @@ bool deps_resolver_t::resolve_probe_dirs(
830830
}
831831
}
832832

833-
// If the deps file is missing add known locations.
834-
if (!get_app_deps().exists())
833+
// If the deps file is missing for the app, add known locations.
834+
// For libhost scenarios, there is no app or app path
835+
if (m_host_mode != host_mode_t::libhost && !get_app_deps().exists())
835836
{
837+
assert(!m_app_dir.empty());
838+
836839
// App local path
837840
add_unique_path(asset_type, m_app_dir, &items, output, &non_serviced, core_servicing);
838841

839-
// deps_resolver treats being able to get the coreclr path as optional, so we ignore the return value here.
840-
// The caller is responsible for checking whether coreclr path is set and handling as appropriate.
841-
(void) file_exists_in_dir(m_app_dir, LIBCORECLR_NAME, &m_coreclr_path);
842+
if (m_coreclr_path.empty())
843+
{
844+
// deps_resolver treats being able to get the coreclr path as optional, so we ignore the return value here.
845+
// The caller is responsible for checking whether coreclr path is set and handling as appropriate.
846+
(void) file_exists_in_dir(m_app_dir, LIBCORECLR_NAME, &m_coreclr_path);
847+
}
842848
}
843849

844850
// Handle any additional deps.json that were specified.

src/native/corehost/hostpolicy/standalone/coreclr_resolver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ bool coreclr_resolver_t::resolve_coreclr(const pal::string_t& libcoreclr_path, c
1313
pal::string_t coreclr_dll_path(libcoreclr_path);
1414
append_path(&coreclr_dll_path, LIBCORECLR_NAME);
1515

16+
// We should always be loading coreclr from an absolute path
17+
if (!pal::is_path_rooted(coreclr_dll_path))
18+
return false;
19+
1620
if (!pal::load_library(&coreclr_dll_path, &coreclr_resolver_contract.coreclr))
1721
{
1822
return false;

0 commit comments

Comments
 (0)