Skip to content

Merging internal commits for release/8.0 #116498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,35 @@ public void ActivateClass_IgnoreAppLocalHostFxr()
}
}

[Fact]
public void ActivateClass_IgnoreWorkingDirectory()
{
using (TestArtifact cwd = TestArtifact.Create("cwd"))
{
// Validate that hosting components in the working directory will not be used
File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName));
File.Copy(Binaries.HostFxr.MockPath_5_0, Path.Combine(cwd.Location, Binaries.HostFxr.FileName));
File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName));

string[] args = {
"comhost",
"synchronous",
"1",
sharedState.ComHostPath,
sharedState.ClsidString
};
sharedState.CreateNativeHostCommand(args, sharedState.ComLibraryFixture.BuiltDotnet.BinPath)
.WorkingDirectory(cwd.Location)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("New instance of Server created")
.And.HaveStdOutContaining($"Activation of {sharedState.ClsidString} succeeded.")
.And.ResolveHostFxr(sharedState.ComLibraryFixture.BuiltDotnet)
.And.ResolveHostPolicy(sharedState.ComLibraryFixture.BuiltDotnet)
.And.ResolveCoreClr(sharedState.ComLibraryFixture.BuiltDotnet);
}
}

[Fact]
public void ActivateClass_ValidateIErrorInfoResult()
{
Expand Down
28 changes: 28 additions & 0 deletions src/installer/tests/HostActivation.Tests/NativeHosting/Ijwhost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,34 @@ public void LoadLibrary_ContextConfig(bool load_isolated)
}
}

[Fact]
public void LoadLibrary_IgnoreWorkingDirectory()
{
using (TestArtifact cwd = TestArtifact.Create("cwd"))
{
// Validate that hosting components in the working directory will not be used
File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName));
File.Copy(Binaries.HostFxr.MockPath_5_0, Path.Combine(cwd.Location, Binaries.HostFxr.FileName));
File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName));

string [] args = {
"ijwhost",
sharedState.IjwApp.AppDll,
"NativeEntryPoint"
};
var dotnet = new Microsoft.DotNet.Cli.Build.DotNetCli(sharedState.RepoDirectories.BuiltDotnet);
sharedState.CreateNativeHostCommand(args, sharedState.RepoDirectories.BuiltDotnet)
.WorkingDirectory(cwd.Location)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("[C++/CLI] NativeEntryPoint: calling managed class")
.And.HaveStdOutContaining("[C++/CLI] ManagedClass: AssemblyLoadContext = \"Default\" System.Runtime.Loader.DefaultAssemblyLoadContext")
.And.ResolveHostFxr(dotnet)
.And.ResolveHostPolicy(dotnet)
.And.ResolveCoreClr(dotnet);
}
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,38 @@ public void CallDelegateOnComponentContext_UnhandledException()
.And.ExecuteFunctionPointerWithException(entryPoint, 1);
}

[Fact]
public void CallDelegateOnComponentContext_IgnoreWorkingDirectory()
{
using (TestArtifact cwd = TestArtifact.Create("cwd"))
{
// Validate that hosting components in the working directory will not be used
File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName));
File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName));

var component = sharedState.ComponentWithNoDependenciesFixture.TestProject;
string[] args =
{
ComponentLoadAssemblyAndGetFunctionPointerArg,
sharedState.HostFxrPath,
component.RuntimeConfigJson,
component.AppDll,
sharedState.ComponentTypeName,
sharedState.ComponentEntryPoint1,
};

var dotnet = new Microsoft.DotNet.Cli.Build.DotNetCli(sharedState.DotNetRoot);
sharedState.CreateNativeHostCommand(args, sharedState.DotNetRoot)
.WorkingDirectory(cwd.Location)
.Execute()
.Should().Pass()
.And.InitializeContextForConfig(component.RuntimeConfigJson)
.And.ExecuteFunctionPointer(sharedState.ComponentEntryPoint1, 1, 1)
.And.ResolveHostPolicy(dotnet)
.And.ResolveCoreClr(dotnet);
}
}

public class SharedTestState : SharedTestStateBase
{
public string HostFxrPath { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.IO;

namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting
{
internal static class FunctionPointerResultExtensions
internal static class NativeHostingResultExtensions
{
public static FluentAssertions.AndConstraint<CommandResultAssertions> ExecuteFunctionPointer(this CommandResultAssertions assertion, string methodName, int callCount, int returnValue)
{
Expand Down Expand Up @@ -47,5 +48,21 @@ public static FluentAssertions.AndConstraint<CommandResultAssertions> ExecuteWit
{
return assertion.HaveStdOutContaining($"{assemblyName}: Location = '{location}'");
}

public static FluentAssertions.AndConstraint<CommandResultAssertions> ResolveHostFxr(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet)
{
return assertion.HaveStdErrContaining($"Resolved fxr [{dotnet.GreatestVersionHostFxrFilePath}]");
}

public static FluentAssertions.AndConstraint<CommandResultAssertions> ResolveHostPolicy(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet)
{
return assertion.HaveStdErrContaining($"{Binaries.HostPolicy.FileName} directory is [{dotnet.GreatestVersionSharedFxPath}]");
}

public static FluentAssertions.AndConstraint<CommandResultAssertions> ResolveCoreClr(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet)
{
return assertion.HaveStdErrContaining($"CoreCLR path = '{Path.Combine(dotnet.GreatestVersionSharedFxPath, Binaries.CoreClr.FileName)}'")
.And.HaveStdErrContaining($"CoreCLR dir = '{dotnet.GreatestVersionSharedFxPath}{Path.DirectorySeparatorChar}'");
}
}
}
14 changes: 14 additions & 0 deletions src/installer/tests/TestUtils/TestArtifact.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ protected TestArtifact(TestArtifact source)
source._copies.Add(this);
}

/// <summary>
/// Create a new test artifact.
/// </summary>
/// <param name="name">Name of the test artifact</param>
/// <returns>Test artifact containing no files</returns>
public static TestArtifact Create(string name)
{
var (location, parentPath) = GetNewTestArtifactPath(name);
return new TestArtifact(location)
{
DirectoryToDelete = parentPath
};
}

protected void RegisterCopy(TestArtifact artifact)
{
_copies.Add(artifact);
Expand Down
5 changes: 5 additions & 0 deletions src/native/corehost/apphost/standalone/hostfxr_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ hostfxr_resolver_t::hostfxr_resolver_t(const pal::string_t& app_root)
{
m_status_code = StatusCode::CoreHostLibMissingFailure;
}
else if (!pal::is_path_rooted(m_fxr_path))
{
// We should always be loading hostfxr from an absolute path
m_status_code = StatusCode::CoreHostLibMissingFailure;
}
else if (pal::load_library(&m_fxr_path, &m_hostfxr_dll))
{
m_status_code = StatusCode::Success;
Expand Down
4 changes: 4 additions & 0 deletions src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ int hostpolicy_resolver::load(
return StatusCode::CoreHostLibMissingFailure;
}

// We should always be loading hostpolicy from an absolute path
if (!pal::is_path_rooted(host_path))
return StatusCode::CoreHostLibMissingFailure;

// Load library
// We expect to leak hostpolicy - just as we do not unload coreclr, we do not unload hostpolicy
if (!pal::load_library(&host_path, &g_hostpolicy))
Expand Down
4 changes: 4 additions & 0 deletions src/native/corehost/fxr_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ int load_fxr_and_get_delegate(hostfxr_delegate_type type, THostPathToConfigCallb
return StatusCode::CoreHostLibMissingFailure;
}

// We should always be loading hostfxr from an absolute path
if (!pal::is_path_rooted(fxr_path))
return StatusCode::CoreHostLibMissingFailure;

// Load library
if (!pal::load_library(&fxr_path, &fxr))
{
Expand Down
14 changes: 11 additions & 3 deletions src/native/corehost/hostpolicy/deps_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,13 +830,21 @@ bool deps_resolver_t::resolve_probe_dirs(
}
}

// If the deps file is missing add known locations.
if (!get_app_deps().exists())
// If the deps file is missing for the app, add known locations.
// For libhost scenarios, there is no app or app path
if (m_host_mode != host_mode_t::libhost && !get_app_deps().exists())
{
assert(!m_app_dir.empty());

// App local path
add_unique_path(asset_type, m_app_dir, &items, output, &non_serviced, core_servicing);

(void) library_exists_in_dir(m_app_dir, LIBCORECLR_NAME, &m_coreclr_path);
if (m_coreclr_path.empty())
{
// deps_resolver treats being able to get the coreclr path as optional, so we ignore the return value here.
// The caller is responsible for checking whether coreclr path is set and handling as appropriate.
(void) library_exists_in_dir(m_app_dir, LIBCORECLR_NAME, &m_coreclr_path);
}
}

// Handle any additional deps.json that were specified.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ bool coreclr_resolver_t::resolve_coreclr(const pal::string_t& libcoreclr_path, c
pal::string_t coreclr_dll_path(libcoreclr_path);
append_path(&coreclr_dll_path, LIBCORECLR_NAME);

// We should always be loading coreclr from an absolute path
if (!pal::is_path_rooted(coreclr_dll_path))
return false;

if (!pal::load_library(&coreclr_dll_path, &coreclr_resolver_contract.coreclr))
{
return false;
Expand Down
Loading