From b5617dd89b259b249b34efa3ce82972f2e5da044 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 29 Jul 2022 16:07:28 -0700 Subject: [PATCH 01/79] Add basic function to call the api later --- src/Tasks/Common/FileUtilities.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index ef6e8355d9f6..423a7d5b3708 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -35,5 +35,13 @@ public static Version TryGetAssemblyVersion(string sourcePath) return s_assemblyExtensions.Contains(extension) ? GetAssemblyVersion(sourcePath) : null; } + public static string CreateTempPath() + { + // TODO: Make this call the API once it is complete. + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + Directory.CreateDirectory(path); + return path; + } + } } From 2403aae1e8e12d0b7222ed8011111e3aeaa8ca72 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 29 Jul 2022 16:43:20 -0700 Subject: [PATCH 02/79] Add call to tool package installer --- .../ToolPackage/ToolPackageInstaller.cs | 28 ++++++++----------- src/Cli/dotnet/dotnet.csproj | 1 + .../ToolPackageInstallerNugetCacheTests.cs | 2 +- .../ToolPackageInstallerTests.cs | 2 +- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 1f3a37d9ee0f..d3a5a4fdbbae 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.EnvironmentAbstractions; using NuGet.ProjectModel; using NuGet.Versioning; +using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.ToolPackage { @@ -53,7 +54,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - var tempProject = CreateTempProject( + Tuple tempProjectDetails = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -65,13 +66,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProjectDetails.Item1.ToString() + tempProjectDetails.Item2), packageLocation, verbosity: verbosity); } finally { - File.Delete(tempProject.Value); + Directory.Delete(tempProjectDetails.Item1.ToString(), recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -131,7 +132,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( Directory.CreateDirectory(tempDirectoryForAssetJson.Value); - var tempProject = CreateTempProject( + var tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -155,7 +156,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( return ToolPackageInstance.CreateFromAssetFile(packageId, tempDirectoryForAssetJson); } - private FilePath CreateTempProject( + private Tuple CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -164,16 +165,9 @@ private FilePath CreateTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - var tempProject = _tempProject ?? new DirectoryPath(Path.GetTempPath()) - .WithSubDirectories(Path.GetRandomFileName()) - .WithFile("restore.csproj"); - - if (Path.GetExtension(tempProject.Value) != "csproj") - { - tempProject = new FilePath(Path.ChangeExtension(tempProject.Value, "csproj")); - } - - Directory.CreateDirectory(tempProject.GetDirectoryPath().Value); + string tempProjectName = "restore.csproj"; + string tempProjectDir = _tempProject.ToString() ?? FileUtilities.CreateTempPath(); + File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), null); var tempProjectContent = new XDocument( new XElement("Project", @@ -203,8 +197,8 @@ private FilePath CreateTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(tempProject.Value, tempProjectContent.ToString()); - return tempProject; + File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), tempProjectContent.ToString()); + return new Tuple(new FilePath(tempProjectDir), tempProjectName); } private string JoinSourceAndOfflineCache(string[] additionalFeeds) diff --git a/src/Cli/dotnet/dotnet.csproj b/src/Cli/dotnet/dotnet.csproj index 9c0dab5d3326..43f86755fd61 100644 --- a/src/Cli/dotnet/dotnet.csproj +++ b/src/Cli/dotnet/dotnet.csproj @@ -19,6 +19,7 @@ + diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs index 87e65c490cab..41e71c959799 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs @@ -167,7 +167,7 @@ private static List GetMockFeedsForConfigFile(FilePath nugetConfig) installer = new ToolPackageInstaller( store: store, projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(testDirectory), + tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(testDirectory), // <-- is this a concern? offlineFeed: offlineFeed ?? new DirectoryPath("does not exist")); } diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs index e2593cc86abb..5b2b70c70647 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs @@ -738,7 +738,7 @@ public void GivenARootWithNonAsciiCharacterInstallSucceeds() var installer = new ToolPackageInstaller( store: store, projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: GetUniqueTempProjectPathEachTest(), + tempProject: GetUniqueTempProjectPathEachTest(), // <-- is this a concern? offlineFeed: new DirectoryPath("does not exist")); var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), From f6d903766800f9615be2b5781c34af796fed68c1 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 29 Jul 2022 16:57:10 -0700 Subject: [PATCH 03/79] Work on ToolPackageInstaller security --- .../ToolPackage/ToolPackageInstaller.cs | 26 +++++++++---------- src/Cli/dotnet/dotnet.csproj | 1 + 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index d3a5a4fdbbae..e67699232a63 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -54,7 +54,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - Tuple tempProjectDetails = CreateDirectoryWithTempProject( + Tuple tempProjectDetails = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -66,13 +66,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - new FilePath(tempProjectDetails.Item1.ToString() + tempProjectDetails.Item2), + new FilePath(tempProjectDetails.Item1 + tempProjectDetails.Item2), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProjectDetails.Item1.ToString(), recursive: true); + Directory.Delete(tempProjectDetails.Item1, recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -127,16 +127,14 @@ public IToolPackage InstallPackageToExternalManagedLocation( string targetFramework = null, string verbosity = null) { - var tempDirectoryForAssetJson = new DirectoryPath(Path.GetTempPath()) - .WithSubDirectories(Path.GetRandomFileName()); + var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); + File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); - Directory.CreateDirectory(tempDirectoryForAssetJson.Value); - - var tempProject = CreateDirectoryWithTempProject( + Tuple tempProjectDetails = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, - assetJsonOutputDirectory: tempDirectoryForAssetJson, + assetJsonOutputDirectory: new DirectoryPath(tempDirectoryForAssetJson), restoreDirectory: null, rootConfigDirectory: packageLocation.RootConfigDirectory, additionalFeeds: packageLocation.AdditionalFeeds); @@ -144,19 +142,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProjectDetails.Item1 + tempProjectDetails.Item2), packageLocation, verbosity: verbosity); } finally { - File.Delete(tempProject.Value); + Directory.Delete(tempProjectDetails.Item1, recursive:true); } - return ToolPackageInstance.CreateFromAssetFile(packageId, tempDirectoryForAssetJson); + return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private Tuple CreateDirectoryWithTempProject( + private Tuple CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -198,7 +196,7 @@ private Tuple CreateDirectoryWithTempProject( new XAttribute("Sdk", "Microsoft.NET.Sdk")))); File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), tempProjectContent.ToString()); - return new Tuple(new FilePath(tempProjectDir), tempProjectName); + return new Tuple(tempProjectDir, tempProjectName); } private string JoinSourceAndOfflineCache(string[] additionalFeeds) diff --git a/src/Cli/dotnet/dotnet.csproj b/src/Cli/dotnet/dotnet.csproj index 43f86755fd61..883ee9000809 100644 --- a/src/Cli/dotnet/dotnet.csproj +++ b/src/Cli/dotnet/dotnet.csproj @@ -20,6 +20,7 @@ + From abdd3e5b552849390be0638585463ae3b87d99db Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 1 Aug 2022 14:45:00 -0700 Subject: [PATCH 04/79] Dont use a tuple and make code less bad --- .../ToolPackage/ToolPackageInstaller.cs | 30 +++++++++---------- src/Tasks/Common/FileUtilities.cs | 7 +++++ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index e67699232a63..6dace3c792a6 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -47,17 +47,18 @@ public IToolPackage InstallPackage( string rollbackDirectory = null; return TransactionalAction.Run( - action: () => { + action: () => + { try { var stageDirectory = _store.GetRandomStagingDirectory(); Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - Tuple tempProjectDetails = CreateDirectoryWithTempProject( + string tempProjectPath = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, - targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, + targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, restoreDirectory: stageDirectory, assetJsonOutputDirectory: stageDirectory, rootConfigDirectory: packageLocation.RootConfigDirectory, @@ -66,13 +67,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - new FilePath(tempProjectDetails.Item1 + tempProjectDetails.Item2), + new FilePath(tempProjectPath), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProjectDetails.Item1, recursive: true); + Directory.Delete(Path.GetDirectoryName(tempProjectPath), recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -105,7 +106,8 @@ public IToolPackage InstallPackage( ex); } }, - rollback: () => { + rollback: () => + { if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory)) { Directory.Delete(rollbackDirectory, true); @@ -130,7 +132,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); - Tuple tempProjectDetails = CreateDirectoryWithTempProject( + string tempProjectDetails = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -142,19 +144,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - new FilePath(tempProjectDetails.Item1 + tempProjectDetails.Item2), + new FilePath(tempProjectDetails + tempProjectDetails), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProjectDetails.Item1, recursive:true); + Directory.Delete(Path.GetDirectoryName(tempProjectDetails), recursive: true); } return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private Tuple CreateDirectoryWithTempProject( + private string CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -163,9 +165,7 @@ private Tuple CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProjectName = "restore.csproj"; - string tempProjectDir = _tempProject.ToString() ?? FileUtilities.CreateTempPath(); - File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), null); + string tempProject = _tempProject.ToString() ?? FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj"); var tempProjectContent = new XDocument( new XElement("Project", @@ -195,8 +195,8 @@ private Tuple CreateDirectoryWithTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), tempProjectContent.ToString()); - return new Tuple(tempProjectDir, tempProjectName); + File.WriteAllText(tempProject, tempProjectContent.ToString()); + return tempProject; } private string JoinSourceAndOfflineCache(string[] additionalFeeds) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 423a7d5b3708..8c984d3a2295 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -43,5 +43,12 @@ public static string CreateTempPath() return path; } + public static string CreateTempFile(string tempDirectory, string extension) + { + string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); + File.Create(fileName); + return fileName; + } + } } From ff4a71ee2020dbdcdcc523fb754346f9a5096200 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 1 Aug 2022 16:25:58 -0700 Subject: [PATCH 05/79] Use filepath instead of str --- .../ToolPackage/ToolPackageInstaller.cs | 23 +++++++++++-------- src/Tasks/Common/FileUtilities.cs | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 6dace3c792a6..fec1bb34f600 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -55,7 +55,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - string tempProjectPath = CreateDirectoryWithTempProject( + FilePath tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -67,13 +67,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - new FilePath(tempProjectPath), + tempProject, packageLocation, verbosity: verbosity); } finally { - Directory.Delete(Path.GetDirectoryName(tempProjectPath), recursive: true); + Directory.Delete(tempProject.GetDirectoryPath().ToString(), recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -132,7 +132,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); - string tempProjectDetails = CreateDirectoryWithTempProject( + FilePath tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -144,19 +144,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - new FilePath(tempProjectDetails + tempProjectDetails), + tempProject, packageLocation, verbosity: verbosity); } finally { - Directory.Delete(Path.GetDirectoryName(tempProjectDetails), recursive: true); + Directory.Delete(tempProject.GetDirectoryPath().ToString(), recursive: true); } return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private string CreateDirectoryWithTempProject( + private FilePath CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -165,7 +165,12 @@ private string CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProject = _tempProject.ToString() ?? FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj"); + FilePath tempProject = _tempProject ?? new FilePath(FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); + if (_tempProject != null) + { + tempProject = new FilePath(Path.ChangeExtension(tempProject.Value, "csproj")); + Directory.CreateDirectory(tempProject.GetDirectoryPath().Value); + } var tempProjectContent = new XDocument( new XElement("Project", @@ -195,7 +200,7 @@ private string CreateDirectoryWithTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(tempProject, tempProjectContent.ToString()); + File.WriteAllText(tempProject.ToString(), tempProjectContent.ToString()); return tempProject; } diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 8c984d3a2295..e6c607d3444c 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -46,7 +46,7 @@ public static string CreateTempPath() public static string CreateTempFile(string tempDirectory, string extension) { string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); - File.Create(fileName); + File.Create(fileName.ToString()); return fileName; } From 1ce5b84578176f71215f843d1f029b6e86820a5f Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 2 Aug 2022 11:30:29 -0700 Subject: [PATCH 06/79] Fix bug/misleading code in FilePath with string --- .../FilePath.cs | 2 +- .../ToolPackage/ToolPackageInstaller.cs | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs index 06ed28ab76d7..3532e058decf 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs @@ -30,7 +30,7 @@ public string ToQuotedString() public override string ToString() { - return ToQuotedString(); + return $"{Value}"; } public DirectoryPath GetDirectoryPath() diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index fec1bb34f600..d2ec50c5dcf9 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -55,7 +55,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - FilePath tempProject = CreateDirectoryWithTempProject( + string tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -67,13 +67,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProject), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProject.GetDirectoryPath().ToString(), recursive: true); + Directory.Delete(Path.GetDirectoryName(tempProject), recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -132,7 +132,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); - FilePath tempProject = CreateDirectoryWithTempProject( + string tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -144,19 +144,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProject), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProject.GetDirectoryPath().ToString(), recursive: true); + Directory.Delete(Path.GetDirectoryName(tempProject), recursive: true); } return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private FilePath CreateDirectoryWithTempProject( + private string CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -165,11 +165,11 @@ private FilePath CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - FilePath tempProject = _tempProject ?? new FilePath(FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); + string tempProject = _tempProject.ToString() ?? (FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); if (_tempProject != null) { - tempProject = new FilePath(Path.ChangeExtension(tempProject.Value, "csproj")); - Directory.CreateDirectory(tempProject.GetDirectoryPath().Value); + tempProject = Path.ChangeExtension(tempProject, "csproj"); + Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); } var tempProjectContent = new XDocument( @@ -200,7 +200,7 @@ private FilePath CreateDirectoryWithTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(tempProject.ToString(), tempProjectContent.ToString()); + File.WriteAllText(tempProject, tempProjectContent.ToString()); return tempProject; } From 63eb2f5c962ee6d053248ce31c0c79472a7bb322 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 3 Aug 2022 11:38:35 -0700 Subject: [PATCH 07/79] Fix biggest vulnerability. NEED TO TEST ON MAC --- .../SudoEnvironmentDirectoryOverride.cs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 799c99fbec39..3e4072bd2842 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -8,6 +8,7 @@ using System.Linq; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; +using Microsoft.NET.Build.Tasks; using NuGet.Common; using NuGet.Configuration; @@ -18,8 +19,6 @@ namespace Microsoft.DotNet.Cli /// public static class SudoEnvironmentDirectoryOverride { - private const string SudoHomeDirectory = "/tmp/dotnet_sudo_home/"; - /// /// Not for security use. Detect if command is running under sudo /// via if SUDO_UID being set. @@ -38,22 +37,10 @@ public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { - if (!TempHomeIsOnlyRootWritable(SudoHomeDirectory)) - { - try - { - Directory.Delete(SudoHomeDirectory, recursive: true); - } - catch (DirectoryNotFoundException) - { - // Avoid read after write race condition - } - } - - Directory.CreateDirectory(SudoHomeDirectory); + string newProcessHomeDirectory = FileUtilities.CreateTempPath(); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); - Environment.SetEnvironmentVariable("HOME", SudoHomeDirectory); + Environment.SetEnvironmentVariable("HOME", newProcessHomeDirectory); CopyUserNuGetConfigToOverriddenHome(homeBeforeOverride); } From 9576b8138002e80742b797def6795cdefdcd278f Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 3 Aug 2022 15:03:50 -0700 Subject: [PATCH 08/79] Watchlist uses temp folder, need to verify .txt extension is OK --- .../dotnet-watch/Internal/MsBuildFileSetFactory.cs | 3 ++- src/BuiltInTools/dotnet-watch/dotnet-watch.csproj | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 77e0a621cdce..98ce0345592a 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; using Microsoft.DotNet.Watcher.Tools; using Microsoft.Extensions.Tools.Internal; +using Microsoft.NET.Build.Tasks; using IReporter = Microsoft.Extensions.Tools.Internal.IReporter; namespace Microsoft.DotNet.Watcher.Internal @@ -63,7 +64,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var watchList = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), ".txt"); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj index 636f43d119b4..c3746d05d6c6 100644 --- a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj +++ b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj @@ -23,6 +23,8 @@ + + From 4ee8f19a3e2d4a65cdae107445e84579845c5cd9 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 10 Aug 2022 16:06:50 -0700 Subject: [PATCH 09/79] use temp path for nupkg. audited all of the varialbes relying on tempdir and seems fine --- .../install/ToolInstallGlobalOrToolPathCommand.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 7e06aae182b1..987fc0a16d00 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -19,6 +19,7 @@ using NuGet.Common; using NuGet.Frameworks; using NuGet.Versioning; +using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.Tools.Tool.Install { @@ -72,7 +73,7 @@ public ToolInstallGlobalOrToolPathCommand( _environmentPathInstruction = environmentPathInstruction ?? EnvironmentPathFactory.CreateEnvironmentPathInstruction(); _createShellShimRepository = createShellShimRepository ?? ShellShimRepositoryFactory.CreateShellShimRepository; - var tempDir = new DirectoryPath(Path.Combine(Path.GetTempPath(), "dotnet-tool-install")); + var tempDir = new DirectoryPath(FileUtilities.CreateTempPath()); var configOption = parseResult.GetValueForOption(ToolInstallCommandParser.ConfigOption); var sourceOption = parseResult.GetValueForOption(ToolInstallCommandParser.AddSourceOption); var packageSourceLocation = new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), additionalSourceFeeds: sourceOption); @@ -143,7 +144,7 @@ public override int Execute() } else { - framework = string.IsNullOrEmpty(_framework) ? + framework = string.IsNullOrEmpty(_framework) ? null : NuGetFramework.Parse(_framework); } From 14491d5ea79a493e40391d40397560c67eefa3c8 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 10 Aug 2022 16:32:05 -0700 Subject: [PATCH 10/79] Apply change to shellshimremover --- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 4dee9748d079..6a653eee5887 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -9,6 +9,7 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.ShellShim { @@ -85,7 +86,8 @@ public void CreateShim(FilePath targetExecutablePath, ToolCommandName commandNam ex); } }, - rollback: () => { + rollback: () => + { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { File.Delete(file.Value); @@ -97,12 +99,13 @@ public void RemoveShim(ToolCommandName commandName) { var files = new Dictionary(); TransactionalAction.Run( - action: () => { + action: () => + { try { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - var tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var tempPath = FileUtilities.CreateTempPath(); FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); files[file.Value] = tempPath; } @@ -118,13 +121,15 @@ public void RemoveShim(ToolCommandName commandName) ex); } }, - commit: () => { + commit: () => + { foreach (var value in files.Values) { _fileSystem.File.Delete(value); } }, - rollback: () => { + rollback: () => + { foreach (var kvp in files) { FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(kvp.Value, kvp.Key)); From 35cf02496b139e052a0648661217f81866ae556e Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 11 Aug 2022 09:27:27 -0700 Subject: [PATCH 11/79] Catch race condition on file set factory delete --- .../dotnet-watch/Internal/MsBuildFileSetFactory.cs | 9 ++++++++- .../dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 98ce0345592a..809d39b9c58f 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -196,7 +196,14 @@ public async Task CreateAsync(CancellationToken cancellationToken) { if (File.Exists(watchList)) { - File.Delete(watchList); + try + { + File.Delete(watchList); + } + catch(System.IO.IOException) + { + // Catch file locking problems on deletion. + } } } } diff --git a/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs b/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs index 00f749ca9d66..b8728a654057 100644 --- a/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs +++ b/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs @@ -308,7 +308,7 @@ public async Task TransitiveProjectReferences_TwoLevels() Assert.All(fileset, f => Assert.False(f.IsStaticFile, $"File {f.FilePath} should not be a static file.")); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/29213")] + [Fact] public async Task ProjectReferences_Graph() { // A->B,F,W(Watch=False) From 00d4028a555dcee4c7151614ad22f4ebedd2b94c Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 11 Aug 2022 17:00:51 -0700 Subject: [PATCH 12/79] Security check on workload command base --- .../dotnet/commands/dotnet-workload/WorkloadCommandBase.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs index 55bd273ae1c2..83c092b16672 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs @@ -8,6 +8,7 @@ using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; using NuGet.Common; namespace Microsoft.DotNet.Workloads.Workload @@ -104,9 +105,10 @@ public WorkloadCommandBase(ParseResult parseResult, ? tempDirPath : !string.IsNullOrWhiteSpace(parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption)) ? parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption) - : Path.GetTempPath(); + : ""; - TempPackagesDirectory = new DirectoryPath(Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); + // The security owness on a custom tempDir is on the user according to docs. + TempPackagesDirectory = new DirectoryPath(TempDirectoryPath == "" ? FileUtilities.CreateTempPath() : Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); PackageDownloader = nugetPackageDownloader ?? new NuGetPackageDownloader(TempPackagesDirectory, filePermissionSetter: null, From fdb7f1b1238339cc12f1ea743ed163e91851703e Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 12 Aug 2022 14:28:44 -0700 Subject: [PATCH 13/79] Dispose file and fix problem in shellshimrepo. We dont use move anymore because we need someone to make a file with secure permissions and gettempfilename does that but getrandomfilename does not. Moving a file would override the permissions so we copy file contents over. --- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 12 +++++++++--- src/Tasks/Common/FileUtilities.cs | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 6a653eee5887..79c02050afe3 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -105,9 +105,15 @@ public void RemoveShim(ToolCommandName commandName) { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - var tempPath = FileUtilities.CreateTempPath(); - FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); - files[file.Value] = tempPath; + using (var tempPath = File.OpenWrite(FileUtilities.CreateTempFile())) + { + Stream oldFile = _fileSystem.File.OpenRead(file.Value); + oldFile.Seek(0, SeekOrigin.Begin); + oldFile.CopyTo(tempPath); + oldFile.Dispose(); + File.Delete(file.Value); + files[file.Value] = tempPath.Name; + } } } catch (Exception ex) when (ex is UnauthorizedAccessException || ex is IOException) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index e6c607d3444c..0ef0f61acfb6 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -43,12 +43,25 @@ public static string CreateTempPath() return path; } - public static string CreateTempFile(string tempDirectory, string extension) + public static string CreateTempFile(string tempDirectory, string extension="") { + if(extension == "") + { + extension = Path.GetExtension(Path.GetRandomFileName()); + } string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); File.Create(fileName.ToString()); return fileName; } + /// + /// + /// + /// The full path of a newly created temp file with OK permissions. + public static string CreateTempFile() + { + return Path.GetTempFileName(); + } + } } From 9f4ac8a9197900ef1c92cc736ad8b100c8f746ec Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 12 Aug 2022 15:34:08 -0700 Subject: [PATCH 14/79] [wip] add some code to try to fix directory bug. Not sure how to use this new lib, need to ask some people --- src/Tasks/Common/FileUtilities.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 0ef0f61acfb6..199c8eda7200 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -7,6 +7,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli; namespace Microsoft.NET.Build.Tasks { @@ -35,11 +37,19 @@ public static Version TryGetAssemblyVersion(string sourcePath) return s_assemblyExtensions.Contains(extension) ? GetAssemblyVersion(sourcePath) : null; } + [DllImport("libc", SetLastError = true)] + public static extern int mkdir(string pathname, UnixFileMode mode); public static string CreateTempPath() { - // TODO: Make this call the API once it is complete. string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(path); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + mkdir(path, StatInterop.Permissions.S_IRWXU) + } + else + { + Directory.CreateDirectory(path, StatInterop.Permissions.S_IRWXU); + } return path; } From 9ef2facd1bd9fc2c9f936991c6907ac268c5c6f3 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 10:14:30 -0700 Subject: [PATCH 15/79] Do the secure thing for temp files in fileutilities --- src/Tasks/Common/FileUtilities.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 199c8eda7200..ef205fb3f32c 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -38,24 +38,28 @@ public static Version TryGetAssemblyVersion(string sourcePath) } [DllImport("libc", SetLastError = true)] - public static extern int mkdir(string pathname, UnixFileMode mode); + public static extern int mkdir(string pathname, uint mode); public static string CreateTempPath() { string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - mkdir(path, StatInterop.Permissions.S_IRWXU) + int dotnet_version = 7; // Changed in backported code. This can be out of date for .NET 8+ and still be fine. + if (dotnet_version < 7) + mkdir(path, 007000); + else + Directory.CreateDirectory(path, UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.UserRead); } else { - Directory.CreateDirectory(path, StatInterop.Permissions.S_IRWXU); + Directory.CreateDirectory(path); } return path; } - public static string CreateTempFile(string tempDirectory, string extension="") + public static string CreateTempFile(string tempDirectory, string extension = "") { - if(extension == "") + if (extension == "") { extension = Path.GetExtension(Path.GetRandomFileName()); } From faea41cd3f3e9addcee6f78c807f600c3e4d0bfe Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:15:36 -0700 Subject: [PATCH 16/79] Fix security bug in file based installer --- src/Cli/dotnet/commands/InstallingWorkloadCommand.cs | 3 ++- .../commands/dotnet-workload/install/FileBasedInstaller.cs | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index 6253cb93224a..98690dfea13e 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -19,6 +19,7 @@ using Microsoft.DotNet.Workloads.Workload.Install; using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Versioning; using Command = System.CommandLine.Command; @@ -87,7 +88,7 @@ protected async Task> GetDownloads(IEnumerable workloadIds, SdkFeatureBand Directory.Delete(dir, true); } } - }); + }); } } From 85afebd66740b41e94912c352141bdc93976e34e Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:19:16 -0700 Subject: [PATCH 17/79] Apply change to workloadmanifestupdater --- .../install/WorkloadManifestUpdater.cs | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index 6fe1fb375903..5e44216a4e66 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -17,6 +17,7 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Common; using NuGet.Versioning; @@ -68,7 +69,7 @@ private static WorkloadManifestUpdater GetInstance(string userProfileDir) var sdkVersion = Product.Version; var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, sdkVersion, userProfileDir); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, dotnetPath, sdkVersion, userProfileDir); - var tempPackagesDir = new DirectoryPath(Path.Combine(Path.GetTempPath(), "dotnet-sdk-advertising-temp")); + var tempPackagesDir = new DirectoryPath(FileUtilities.CreateTempPath()); var nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(), @@ -188,9 +189,9 @@ Dictionary Workloads } if (advertisingManifestVersionAndWorkloads != null && - ((advertisingManifestVersionAndWorkloads.Value.ManifestVersion.CompareTo(currentManifestVersion.manifestVersion) > 0 + ((advertisingManifestVersionAndWorkloads.Value.ManifestVersion.CompareTo(currentManifestVersion.manifestVersion) > 0 && advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.Equals(currentManifestVersion.sdkFeatureBand)) || - advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.CompareTo(currentManifestVersion.sdkFeatureBand) > 0)) + advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.CompareTo(currentManifestVersion.sdkFeatureBand) > 0)) { manifestUpdates.Add((new ManifestVersionUpdate(manifestId, currentManifestVersion.manifestVersion, currentManifestVersion.sdkFeatureBand.ToString(), advertisingManifestVersionAndWorkloads.Value.ManifestVersion, advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.ToString()), @@ -275,7 +276,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, try { var adManifestPath = GetAdvertisingManifestPath(_sdkFeatureBand, manifestId); - + bool success; (success, packagePath) = await GetManifestPackageUpdate(_sdkFeatureBand, manifestId, includePreviews, offlineCache); if (!success) @@ -291,7 +292,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestPackageDoesNotExist, manifestId)); return; } - + await _workloadManifestInstaller.ExtractManifestAsync(packagePath, adManifestPath); // add file that contains the advertisted manifest feature band so GetAdvertisingManifestVersionAndWorkloads will use correct feature band, regardless of if rollback occurred or not @@ -352,7 +353,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, { adManifestFeatureBand = new SdkFeatureBand(File.ReadAllText(adManifestFeatureBandPath)); } - + return (new ManifestVersion(manifest.Version), adManifestFeatureBand, manifest.Workloads.Values.OfType().ToDictionary(w => w.Id)); } @@ -438,12 +439,12 @@ private async Task NewerManifestPackageExists(ManifestId manifest) ManifestVersion manifestVersion; SdkFeatureBand manifestFeatureBand; var parts = manifest.Value.Split('/'); - + string manifestVersionString = (parts[0]); if (!FXVersion.TryParse(manifestVersionString, out FXVersion version)) { throw new FormatException(String.Format(LocalizableStrings.InvalidVersionForWorkload, manifest.Key, manifestVersionString)); - } + } manifestVersion = new ManifestVersion(parts[0]); if (parts.Length == 1) @@ -467,15 +468,15 @@ private bool BackgroundUpdatesAreDisabled() => private static string GetAdvertisingWorkloadsFilePath(string userProfileDir, SdkFeatureBand featureBand) => Path.Combine(userProfileDir, $".workloadAdvertisingUpdates{featureBand}"); - private async Task GetOnlinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, bool includePreviews) - { - string packagePath = await _nugetPackageDownloader.DownloadPackageAsync( - _workloadManifestInstaller.GetManifestPackageId(manifestId, sdkFeatureBand), - packageSourceLocation: _packageSourceLocation, - includePreview: includePreviews); - - return packagePath; - } + private async Task GetOnlinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, bool includePreviews) + { + string packagePath = await _nugetPackageDownloader.DownloadPackageAsync( + _workloadManifestInstaller.GetManifestPackageId(manifestId, sdkFeatureBand), + packageSourceLocation: _packageSourceLocation, + includePreview: includePreviews); + + return packagePath; + } private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, DirectoryPath? offlineCache = null) { @@ -495,7 +496,7 @@ private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId m { if (offlineCache == null || !offlineCache.HasValue) { - try + try { string packagePath = await GetOnlinePackagePath(sdkFeatureBand, manifestId, includePreviews); return (true, packagePath); From aa5cdc7e0fdc5e41fcd1ee5a9845af8e949f4d70 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:31:16 -0700 Subject: [PATCH 18/79] Fix uint perm --- src/Tasks/Common/FileUtilities.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index ef205fb3f32c..0de7f99b8c28 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -8,7 +8,6 @@ using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using Microsoft.DotNet.Cli; namespace Microsoft.NET.Build.Tasks { @@ -46,7 +45,7 @@ public static string CreateTempPath() { int dotnet_version = 7; // Changed in backported code. This can be out of date for .NET 8+ and still be fine. if (dotnet_version < 7) - mkdir(path, 007000); + mkdir(path, 0000700); else Directory.CreateDirectory(path, UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.UserRead); } From e22b6e22ea13245a1c946a66a12c6b2c8a341087 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:32:31 -0700 Subject: [PATCH 19/79] Ditch unix file mode --- src/Tasks/Common/FileUtilities.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 0de7f99b8c28..b93077d34602 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -43,11 +43,7 @@ public static string CreateTempPath() string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - int dotnet_version = 7; // Changed in backported code. This can be out of date for .NET 8+ and still be fine. - if (dotnet_version < 7) - mkdir(path, 0000700); - else - Directory.CreateDirectory(path, UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.UserRead); + mkdir(path, 0000700); } else { From 903da3fa5521ba93d14c7b1050d69e7087f83423 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:58:42 -0700 Subject: [PATCH 20/79] Fix silly bug with temp path. --- src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs index 83c092b16672..33c6eed92276 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs @@ -105,7 +105,7 @@ public WorkloadCommandBase(ParseResult parseResult, ? tempDirPath : !string.IsNullOrWhiteSpace(parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption)) ? parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption) - : ""; + : FileUtilities.CreateTempPath(); // The security owness on a custom tempDir is on the user according to docs. TempPackagesDirectory = new DirectoryPath(TempDirectoryPath == "" ? FileUtilities.CreateTempPath() : Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); From f5f250b6c1daf0e39fbde6d759cd39a7b4a923ce Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 15:18:25 -0700 Subject: [PATCH 21/79] Override chown and chmod use to give user perm instead of sudo perm --- .../SudoEnvironmentDirectoryOverride.cs | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 3e4072bd2842..9071e4c4c68f 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -6,6 +6,7 @@ using System.CommandLine.Parsing; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; using Microsoft.NET.Build.Tasks; @@ -33,12 +34,26 @@ public static bool IsRunningUnderSudo() return false; } + + [DllImport("libc", SetLastError = true)] + public static extern int chown(string username, string path); + [DllImport("libc", SetLastError = true)] + private static extern int chmod(string pathname, uint mode); + private static void OverridePathFromSudoPermToSudoUserPerm(string path) + { + if (!OperatingSystem.IsWindows() && IsRunningUnderSudo()) + { + chown(Environment.GetEnvironmentVariable("SUDO_USER"), path); + chmod(path, 0000700); + } + } + public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { string newProcessHomeDirectory = FileUtilities.CreateTempPath(); - + OverridePathFromSudoPermToSudoUserPerm(newProcessHomeDirectory); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); Environment.SetEnvironmentVariable("HOME", newProcessHomeDirectory); @@ -108,12 +123,12 @@ private static bool TempHomeIsOnlyRootWritable(string path) private static bool OtherUserCannotWrite(StatInterop.FileStatus fileStat) { - return (fileStat.Mode & (int) StatInterop.Permissions.S_IWOTH) == 0; + return (fileStat.Mode & (int)StatInterop.Permissions.S_IWOTH) == 0; } private static bool GroupCannotWrite(StatInterop.FileStatus fileStat) { - return (fileStat.Mode & (int) StatInterop.Permissions.S_IWGRP) == 0; + return (fileStat.Mode & (int)StatInterop.Permissions.S_IWGRP) == 0; } private static bool IsOwnedByRoot(StatInterop.FileStatus fileStat) From 7eb80e5266ae64ab802375ce74edc2f5da1dfa2a Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 18 Aug 2022 11:19:17 -0700 Subject: [PATCH 22/79] Drop lock on file --- .../dotnet-watch/Internal/MsBuildFileSetFactory.cs | 2 +- src/Tasks/Common/FileUtilities.cs | 3 ++- src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 809d39b9c58f..2b0751881b3a 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -64,7 +64,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), ".txt"); + var watchList = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath()); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index b93077d34602..aeeb1c4c1437 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -59,7 +59,8 @@ public static string CreateTempFile(string tempDirectory, string extension = "") extension = Path.GetExtension(Path.GetRandomFileName()); } string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); - File.Create(fileName.ToString()); + var fstream = File.Create(fileName.ToString()); + fstream.Close(); return fileName; } diff --git a/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs b/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs index b8728a654057..00f749ca9d66 100644 --- a/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs +++ b/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs @@ -308,7 +308,7 @@ public async Task TransitiveProjectReferences_TwoLevels() Assert.All(fileset, f => Assert.False(f.IsStaticFile, $"File {f.FilePath} should not be a static file.")); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/29213")] public async Task ProjectReferences_Graph() { // A->B,F,W(Watch=False) From 67a96ba67d3f4eb6788821f4931f49ec8fb1baf0 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 18 Aug 2022 11:30:55 -0700 Subject: [PATCH 23/79] Use my createtempfile function in toolcmd --- src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index d2ec50c5dcf9..4b86af94aa59 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -130,7 +130,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( string verbosity = null) { var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); - File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); + FileUtilities.CreateTempFile(tempDirectoryForAssetJson); string tempProject = CreateDirectoryWithTempProject( packageId: packageId, From 1b6f325e16c2f0f3cc4617fba2d0621a1456558b Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 19 Aug 2022 14:27:54 -0700 Subject: [PATCH 24/79] make changes to lock file --- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 79c02050afe3..9913180f14ba 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -107,7 +107,9 @@ public void RemoveShim(ToolCommandName commandName) { using (var tempPath = File.OpenWrite(FileUtilities.CreateTempFile())) { - Stream oldFile = _fileSystem.File.OpenRead(file.Value); + if (!File.Exists(file.Value)) + continue; + Stream oldFile = new FileStream(file.Value, FileMode.Open, FileAccess.ReadWrite, FileShare.None); oldFile.Seek(0, SeekOrigin.Begin); oldFile.CopyTo(tempPath); oldFile.Dispose(); From 7e54ad4107cdaee776762741d5c82b5c85cbcfee Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 23 Aug 2022 14:06:01 -0700 Subject: [PATCH 25/79] catch trying to del non existent file --- .../dotnet/ShellShim/ShellShimRepository.cs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 79c02050afe3..34f9eed4900c 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -105,14 +105,24 @@ public void RemoveShim(ToolCommandName commandName) { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - using (var tempPath = File.OpenWrite(FileUtilities.CreateTempFile())) + if (File.Exists(file.ToString())) { - Stream oldFile = _fileSystem.File.OpenRead(file.Value); - oldFile.Seek(0, SeekOrigin.Begin); - oldFile.CopyTo(tempPath); - oldFile.Dispose(); - File.Delete(file.Value); - files[file.Value] = tempPath.Name; + try + { + Stream oldFile = _fileSystem.File.OpenRead(file.Value); + using (var tempPath = File.OpenWrite(FileUtilities.CreateTempFile())) + { + oldFile.Seek(0, SeekOrigin.Begin); + oldFile.CopyTo(tempPath); + oldFile.Dispose(); + File.Delete(file.Value); + files[file.Value] = tempPath.Name; + } + } + catch (Exception ex) when (ex is System.IO.FileNotFoundException || ex is System.IO.IOException) // catch race condition on file lock + { + continue; + } } } } From 2a5f1d548b0be87dda31534047ddf2355e1396b3 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 23 Aug 2022 14:24:18 -0700 Subject: [PATCH 26/79] Fix bug with secure file moving --- .../dotnet/ShellShim/ShellShimRepository.cs | 24 ++++--------------- .../SudoEnvironmentDirectoryOverride.cs | 4 +--- src/Tasks/Common/FileUtilities.cs | 11 +++++++++ 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 34f9eed4900c..515033241bf1 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -105,25 +105,11 @@ public void RemoveShim(ToolCommandName commandName) { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - if (File.Exists(file.ToString())) - { - try - { - Stream oldFile = _fileSystem.File.OpenRead(file.Value); - using (var tempPath = File.OpenWrite(FileUtilities.CreateTempFile())) - { - oldFile.Seek(0, SeekOrigin.Begin); - oldFile.CopyTo(tempPath); - oldFile.Dispose(); - File.Delete(file.Value); - files[file.Value] = tempPath.Name; - } - } - catch (Exception ex) when (ex is System.IO.FileNotFoundException || ex is System.IO.IOException) // catch race condition on file lock - { - continue; - } - } + string tempPath = FileUtilities.CreateTempFile(); + File.Delete(tempPath); + FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); + FileUtilities.ResetTempFilePermissions(tempPath); + files[file.Value] = tempPath; } } catch (Exception ex) when (ex is UnauthorizedAccessException || ex is IOException) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 9071e4c4c68f..be1e5e83f402 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -37,14 +37,12 @@ public static bool IsRunningUnderSudo() [DllImport("libc", SetLastError = true)] public static extern int chown(string username, string path); - [DllImport("libc", SetLastError = true)] - private static extern int chmod(string pathname, uint mode); private static void OverridePathFromSudoPermToSudoUserPerm(string path) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo()) { chown(Environment.GetEnvironmentVariable("SUDO_USER"), path); - chmod(path, 0000700); + FileUtilities.ResetTempFilePermissions(path); } } diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index aeeb1c4c1437..1c73015c7c3f 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -73,5 +73,16 @@ public static string CreateTempFile() return Path.GetTempFileName(); } + + [DllImport("libc", SetLastError = true)] + private static extern int chmod(string pathname, uint mode); + public static void ResetTempFilePermissions(string path) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + chmod(path, 0000700); + } + } + } } From 9ff44314325047aa052fde8dcaa58260e40a555a Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 23 Aug 2022 14:55:17 -0700 Subject: [PATCH 27/79] Fix it runs with specified verbosity --- src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 4b86af94aa59..8bbc9d182689 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -14,6 +14,7 @@ using NuGet.ProjectModel; using NuGet.Versioning; using Microsoft.NET.Build.Tasks; +using System.Diagnostics; namespace Microsoft.DotNet.ToolPackage { @@ -165,7 +166,7 @@ private string CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProject = _tempProject.ToString() ?? (FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); + string tempProject = _tempProject != null ? _tempProject.ToString() : (FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); if (_tempProject != null) { tempProject = Path.ChangeExtension(tempProject, "csproj"); From 633c9ba497cf053c51184bbdc827537af5f8a810 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 22 Aug 2022 11:23:32 -0400 Subject: [PATCH 28/79] Work around analyzer bug --- src/Microsoft.Win32.Msi/NativeMethods.cs | 3 +++ src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/Microsoft.Win32.Msi/NativeMethods.cs b/src/Microsoft.Win32.Msi/NativeMethods.cs index eb60d99ac393..52936f2346b0 100644 --- a/src/Microsoft.Win32.Msi/NativeMethods.cs +++ b/src/Microsoft.Win32.Msi/NativeMethods.cs @@ -5,6 +5,9 @@ using System.Runtime.InteropServices; using System.Text; +// Work around https://github.com/dotnet/roslyn-analyzers/issues/6094 +#pragma warning disable CA1420 + namespace Microsoft.Win32.Msi { /// diff --git a/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs b/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs index a407c81d0f5c..fb0329d275c4 100644 --- a/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs +++ b/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs @@ -8,6 +8,9 @@ #nullable disable +// Work around https://github.com/dotnet/roslyn-analyzers/issues/6094 +#pragma warning disable CA1420 + namespace Microsoft.DotNet.NativeWrapper { public static partial class Interop From ded6ab0bcf6e51f246b22d489417bbdbd1151853 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 25 Aug 2022 12:34:51 -0700 Subject: [PATCH 29/79] Try using chown in other places where sudo might be used in a workload install --- .../SudoEnvironmentDirectoryOverride.cs | 4 --- src/Tasks/Common/FileUtilities.cs | 26 ++++++++++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index be1e5e83f402..7e1861d100e7 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -34,14 +34,10 @@ public static bool IsRunningUnderSudo() return false; } - - [DllImport("libc", SetLastError = true)] - public static extern int chown(string username, string path); private static void OverridePathFromSudoPermToSudoUserPerm(string path) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo()) { - chown(Environment.GetEnvironmentVariable("SUDO_USER"), path); FileUtilities.ResetTempFilePermissions(path); } } diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 1c73015c7c3f..075ea805975a 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -37,13 +37,18 @@ public static Version TryGetAssemblyVersion(string sourcePath) } [DllImport("libc", SetLastError = true)] - public static extern int mkdir(string pathname, uint mode); + public static extern int mkdir(string pathname, int mode); public static string CreateTempPath() { string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - mkdir(path, 0000700); + const int S_IRUSR = 256; + const int S_IWUSR = 128; + const int S_IXUSR = 64; + int _700 = S_IRUSR | S_IWUSR | S_IXUSR; + mkdir(path, _700); + ResetTempFilePermissions(path); } else { @@ -61,6 +66,7 @@ public static string CreateTempFile(string tempDirectory, string extension = "") string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); var fstream = File.Create(fileName.ToString()); fstream.Close(); + ResetTempFilePermissions(fileName); return fileName; } @@ -75,12 +81,24 @@ public static string CreateTempFile() [DllImport("libc", SetLastError = true)] - private static extern int chmod(string pathname, uint mode); + private static extern int chmod(string pathname, int mode); + [DllImport("libc", SetLastError = true)] + public static extern int chown(string path, int owner, int group); public static void ResetTempFilePermissions(string path) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - chmod(path, 0000700); + if(Environment.GetEnvironmentVariable("SUDO_USER") != null) + { + string UID = Environment.GetEnvironmentVariable("SUDO_UID"); + string GID = Environment.GetEnvironmentVariable("SUDO_GID"); + chown(path, Int32.Parse(UID), Int32.Parse(GID)); + } + const int S_IRUSR = 256; + const int S_IWUSR = 128; + const int S_IXUSR = 64; + int _700 = S_IRUSR | S_IWUSR | S_IXUSR; + chmod(path, _700); } } From 3403cb93f0e381922d1948e2395a6ad7dfadc74a Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 25 Aug 2022 17:02:42 -0700 Subject: [PATCH 30/79] try not calling chown --- src/Tasks/Common/FileUtilities.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 075ea805975a..f29507f9abe3 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -92,7 +92,7 @@ public static void ResetTempFilePermissions(string path) { string UID = Environment.GetEnvironmentVariable("SUDO_UID"); string GID = Environment.GetEnvironmentVariable("SUDO_GID"); - chown(path, Int32.Parse(UID), Int32.Parse(GID)); + //chown(path, Int32.Parse(UID), Int32.Parse(GID)); } const int S_IRUSR = 256; const int S_IWUSR = 128; From 75b221bedde4724debfa31b9a4bf8211b7b1fb35 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 26 Aug 2022 11:55:48 -0700 Subject: [PATCH 31/79] Fix ugly things I did in toolpackageinstaller --- src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 8bbc9d182689..324897160085 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -131,7 +131,6 @@ public IToolPackage InstallPackageToExternalManagedLocation( string verbosity = null) { var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); - FileUtilities.CreateTempFile(tempDirectoryForAssetJson); string tempProject = CreateDirectoryWithTempProject( packageId: packageId, @@ -166,13 +165,9 @@ private string CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProject = _tempProject != null ? _tempProject.ToString() : (FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); - if (_tempProject != null) - { - tempProject = Path.ChangeExtension(tempProject, "csproj"); - Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); - } + string tempProject = _tempProject != null && _tempProject.HasValue ? _tempProject.Value.Value : FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj"); + Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); var tempProjectContent = new XDocument( new XElement("Project", new XElement("PropertyGroup", From 327dc013c034d5c85ea663ef4c7bf26f38d78c9f Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 29 Aug 2022 21:41:38 +0000 Subject: [PATCH 32/79] Make output very verbose --- src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs b/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs index 4e954d6cd20e..769aee9afbc5 100644 --- a/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs +++ b/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs @@ -91,6 +91,9 @@ public void ItListsAutoReferencedPackages() .WithProjectChanges(ChangeTargetFrameworkTo2_1); var projectDirectory = testAsset.Path; + var debugCmd = new DotnetCommand(Log); + debugCmd.Execute($"dotnet", "msbuild", "--pp", $"{projectDirectory + "\\TestAppSimple.csproj"}"); + new RestoreCommand(testAsset) .Execute() .Should() From a7eee337035f0145d0ec6e139620dc2eeb86a41a Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 29 Jul 2022 16:07:28 -0700 Subject: [PATCH 33/79] Add basic function to call the api later --- src/Tasks/Common/FileUtilities.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index ef6e8355d9f6..423a7d5b3708 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -35,5 +35,13 @@ public static Version TryGetAssemblyVersion(string sourcePath) return s_assemblyExtensions.Contains(extension) ? GetAssemblyVersion(sourcePath) : null; } + public static string CreateTempPath() + { + // TODO: Make this call the API once it is complete. + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + Directory.CreateDirectory(path); + return path; + } + } } From e1a7cce0d5dc3a127277d3b00a0159772f0af6b2 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 29 Jul 2022 16:43:20 -0700 Subject: [PATCH 34/79] Add call to tool package installer --- .../ToolPackage/ToolPackageInstaller.cs | 28 ++++++++----------- src/Cli/dotnet/dotnet.csproj | 1 + .../ToolPackageInstallerNugetCacheTests.cs | 2 +- .../ToolPackageInstallerTests.cs | 2 +- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 1f3a37d9ee0f..d3a5a4fdbbae 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.EnvironmentAbstractions; using NuGet.ProjectModel; using NuGet.Versioning; +using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.ToolPackage { @@ -53,7 +54,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - var tempProject = CreateTempProject( + Tuple tempProjectDetails = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -65,13 +66,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProjectDetails.Item1.ToString() + tempProjectDetails.Item2), packageLocation, verbosity: verbosity); } finally { - File.Delete(tempProject.Value); + Directory.Delete(tempProjectDetails.Item1.ToString(), recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -131,7 +132,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( Directory.CreateDirectory(tempDirectoryForAssetJson.Value); - var tempProject = CreateTempProject( + var tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -155,7 +156,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( return ToolPackageInstance.CreateFromAssetFile(packageId, tempDirectoryForAssetJson); } - private FilePath CreateTempProject( + private Tuple CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -164,16 +165,9 @@ private FilePath CreateTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - var tempProject = _tempProject ?? new DirectoryPath(Path.GetTempPath()) - .WithSubDirectories(Path.GetRandomFileName()) - .WithFile("restore.csproj"); - - if (Path.GetExtension(tempProject.Value) != "csproj") - { - tempProject = new FilePath(Path.ChangeExtension(tempProject.Value, "csproj")); - } - - Directory.CreateDirectory(tempProject.GetDirectoryPath().Value); + string tempProjectName = "restore.csproj"; + string tempProjectDir = _tempProject.ToString() ?? FileUtilities.CreateTempPath(); + File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), null); var tempProjectContent = new XDocument( new XElement("Project", @@ -203,8 +197,8 @@ private FilePath CreateTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(tempProject.Value, tempProjectContent.ToString()); - return tempProject; + File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), tempProjectContent.ToString()); + return new Tuple(new FilePath(tempProjectDir), tempProjectName); } private string JoinSourceAndOfflineCache(string[] additionalFeeds) diff --git a/src/Cli/dotnet/dotnet.csproj b/src/Cli/dotnet/dotnet.csproj index bb202db43721..b799e224f712 100644 --- a/src/Cli/dotnet/dotnet.csproj +++ b/src/Cli/dotnet/dotnet.csproj @@ -20,6 +20,7 @@ + diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs index 87e65c490cab..41e71c959799 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs @@ -167,7 +167,7 @@ private static List GetMockFeedsForConfigFile(FilePath nugetConfig) installer = new ToolPackageInstaller( store: store, projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(testDirectory), + tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(testDirectory), // <-- is this a concern? offlineFeed: offlineFeed ?? new DirectoryPath("does not exist")); } diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs index e8dc0fb3e36c..0c1d2a0b434c 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs @@ -738,7 +738,7 @@ public void GivenARootWithNonAsciiCharacterInstallSucceeds() var installer = new ToolPackageInstaller( store: store, projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: GetUniqueTempProjectPathEachTest(), + tempProject: GetUniqueTempProjectPathEachTest(), // <-- is this a concern? offlineFeed: new DirectoryPath("does not exist")); var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), From e8407bf75881f95580d1e4218cd5ff4874d5b0d6 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 29 Jul 2022 16:57:10 -0700 Subject: [PATCH 35/79] Work on ToolPackageInstaller security --- .../ToolPackage/ToolPackageInstaller.cs | 26 +++++++++---------- src/Cli/dotnet/dotnet.csproj | 1 + 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index d3a5a4fdbbae..e67699232a63 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -54,7 +54,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - Tuple tempProjectDetails = CreateDirectoryWithTempProject( + Tuple tempProjectDetails = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -66,13 +66,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - new FilePath(tempProjectDetails.Item1.ToString() + tempProjectDetails.Item2), + new FilePath(tempProjectDetails.Item1 + tempProjectDetails.Item2), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProjectDetails.Item1.ToString(), recursive: true); + Directory.Delete(tempProjectDetails.Item1, recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -127,16 +127,14 @@ public IToolPackage InstallPackageToExternalManagedLocation( string targetFramework = null, string verbosity = null) { - var tempDirectoryForAssetJson = new DirectoryPath(Path.GetTempPath()) - .WithSubDirectories(Path.GetRandomFileName()); + var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); + File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); - Directory.CreateDirectory(tempDirectoryForAssetJson.Value); - - var tempProject = CreateDirectoryWithTempProject( + Tuple tempProjectDetails = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, - assetJsonOutputDirectory: tempDirectoryForAssetJson, + assetJsonOutputDirectory: new DirectoryPath(tempDirectoryForAssetJson), restoreDirectory: null, rootConfigDirectory: packageLocation.RootConfigDirectory, additionalFeeds: packageLocation.AdditionalFeeds); @@ -144,19 +142,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProjectDetails.Item1 + tempProjectDetails.Item2), packageLocation, verbosity: verbosity); } finally { - File.Delete(tempProject.Value); + Directory.Delete(tempProjectDetails.Item1, recursive:true); } - return ToolPackageInstance.CreateFromAssetFile(packageId, tempDirectoryForAssetJson); + return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private Tuple CreateDirectoryWithTempProject( + private Tuple CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -198,7 +196,7 @@ private Tuple CreateDirectoryWithTempProject( new XAttribute("Sdk", "Microsoft.NET.Sdk")))); File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), tempProjectContent.ToString()); - return new Tuple(new FilePath(tempProjectDir), tempProjectName); + return new Tuple(tempProjectDir, tempProjectName); } private string JoinSourceAndOfflineCache(string[] additionalFeeds) diff --git a/src/Cli/dotnet/dotnet.csproj b/src/Cli/dotnet/dotnet.csproj index b799e224f712..1004b10a6322 100644 --- a/src/Cli/dotnet/dotnet.csproj +++ b/src/Cli/dotnet/dotnet.csproj @@ -21,6 +21,7 @@ + From 45e4705fdb6efb58f574c328d3643398c233990f Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 1 Aug 2022 14:45:00 -0700 Subject: [PATCH 36/79] Dont use a tuple and make code less bad --- .../ToolPackage/ToolPackageInstaller.cs | 30 +++++++++---------- src/Tasks/Common/FileUtilities.cs | 7 +++++ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index e67699232a63..6dace3c792a6 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -47,17 +47,18 @@ public IToolPackage InstallPackage( string rollbackDirectory = null; return TransactionalAction.Run( - action: () => { + action: () => + { try { var stageDirectory = _store.GetRandomStagingDirectory(); Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - Tuple tempProjectDetails = CreateDirectoryWithTempProject( + string tempProjectPath = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, - targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, + targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, restoreDirectory: stageDirectory, assetJsonOutputDirectory: stageDirectory, rootConfigDirectory: packageLocation.RootConfigDirectory, @@ -66,13 +67,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - new FilePath(tempProjectDetails.Item1 + tempProjectDetails.Item2), + new FilePath(tempProjectPath), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProjectDetails.Item1, recursive: true); + Directory.Delete(Path.GetDirectoryName(tempProjectPath), recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -105,7 +106,8 @@ public IToolPackage InstallPackage( ex); } }, - rollback: () => { + rollback: () => + { if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory)) { Directory.Delete(rollbackDirectory, true); @@ -130,7 +132,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); - Tuple tempProjectDetails = CreateDirectoryWithTempProject( + string tempProjectDetails = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -142,19 +144,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - new FilePath(tempProjectDetails.Item1 + tempProjectDetails.Item2), + new FilePath(tempProjectDetails + tempProjectDetails), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProjectDetails.Item1, recursive:true); + Directory.Delete(Path.GetDirectoryName(tempProjectDetails), recursive: true); } return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private Tuple CreateDirectoryWithTempProject( + private string CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -163,9 +165,7 @@ private Tuple CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProjectName = "restore.csproj"; - string tempProjectDir = _tempProject.ToString() ?? FileUtilities.CreateTempPath(); - File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), null); + string tempProject = _tempProject.ToString() ?? FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj"); var tempProjectContent = new XDocument( new XElement("Project", @@ -195,8 +195,8 @@ private Tuple CreateDirectoryWithTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(Path.Combine(tempProjectDir, tempProjectName), tempProjectContent.ToString()); - return new Tuple(tempProjectDir, tempProjectName); + File.WriteAllText(tempProject, tempProjectContent.ToString()); + return tempProject; } private string JoinSourceAndOfflineCache(string[] additionalFeeds) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 423a7d5b3708..8c984d3a2295 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -43,5 +43,12 @@ public static string CreateTempPath() return path; } + public static string CreateTempFile(string tempDirectory, string extension) + { + string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); + File.Create(fileName); + return fileName; + } + } } From 6f91bbc855d6ef809ca4dc243f97002eb4307f63 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 1 Aug 2022 16:25:58 -0700 Subject: [PATCH 37/79] Use filepath instead of str --- .../ToolPackage/ToolPackageInstaller.cs | 23 +++++++++++-------- src/Tasks/Common/FileUtilities.cs | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 6dace3c792a6..fec1bb34f600 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -55,7 +55,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - string tempProjectPath = CreateDirectoryWithTempProject( + FilePath tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -67,13 +67,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - new FilePath(tempProjectPath), + tempProject, packageLocation, verbosity: verbosity); } finally { - Directory.Delete(Path.GetDirectoryName(tempProjectPath), recursive: true); + Directory.Delete(tempProject.GetDirectoryPath().ToString(), recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -132,7 +132,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); - string tempProjectDetails = CreateDirectoryWithTempProject( + FilePath tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -144,19 +144,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - new FilePath(tempProjectDetails + tempProjectDetails), + tempProject, packageLocation, verbosity: verbosity); } finally { - Directory.Delete(Path.GetDirectoryName(tempProjectDetails), recursive: true); + Directory.Delete(tempProject.GetDirectoryPath().ToString(), recursive: true); } return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private string CreateDirectoryWithTempProject( + private FilePath CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -165,7 +165,12 @@ private string CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProject = _tempProject.ToString() ?? FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj"); + FilePath tempProject = _tempProject ?? new FilePath(FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); + if (_tempProject != null) + { + tempProject = new FilePath(Path.ChangeExtension(tempProject.Value, "csproj")); + Directory.CreateDirectory(tempProject.GetDirectoryPath().Value); + } var tempProjectContent = new XDocument( new XElement("Project", @@ -195,7 +200,7 @@ private string CreateDirectoryWithTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(tempProject, tempProjectContent.ToString()); + File.WriteAllText(tempProject.ToString(), tempProjectContent.ToString()); return tempProject; } diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 8c984d3a2295..e6c607d3444c 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -46,7 +46,7 @@ public static string CreateTempPath() public static string CreateTempFile(string tempDirectory, string extension) { string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); - File.Create(fileName); + File.Create(fileName.ToString()); return fileName; } From 0f90f807d44d2399bb81b406a668bae3943f09f6 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 2 Aug 2022 11:30:29 -0700 Subject: [PATCH 38/79] Fix bug/misleading code in FilePath with string --- .../FilePath.cs | 2 +- .../ToolPackage/ToolPackageInstaller.cs | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs index 06ed28ab76d7..3532e058decf 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs @@ -30,7 +30,7 @@ public string ToQuotedString() public override string ToString() { - return ToQuotedString(); + return $"{Value}"; } public DirectoryPath GetDirectoryPath() diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index fec1bb34f600..d2ec50c5dcf9 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -55,7 +55,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; - FilePath tempProject = CreateDirectoryWithTempProject( + string tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -67,13 +67,13 @@ public IToolPackage InstallPackage( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProject), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProject.GetDirectoryPath().ToString(), recursive: true); + Directory.Delete(Path.GetDirectoryName(tempProject), recursive: true); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); @@ -132,7 +132,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); - FilePath tempProject = CreateDirectoryWithTempProject( + string tempProject = CreateDirectoryWithTempProject( packageId: packageId, versionRange: versionRange, targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, @@ -144,19 +144,19 @@ public IToolPackage InstallPackageToExternalManagedLocation( try { _projectRestorer.Restore( - tempProject, + new FilePath(tempProject), packageLocation, verbosity: verbosity); } finally { - Directory.Delete(tempProject.GetDirectoryPath().ToString(), recursive: true); + Directory.Delete(Path.GetDirectoryName(tempProject), recursive: true); } return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); } - private FilePath CreateDirectoryWithTempProject( + private string CreateDirectoryWithTempProject( PackageId packageId, VersionRange versionRange, string targetFramework, @@ -165,11 +165,11 @@ private FilePath CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - FilePath tempProject = _tempProject ?? new FilePath(FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); + string tempProject = _tempProject.ToString() ?? (FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); if (_tempProject != null) { - tempProject = new FilePath(Path.ChangeExtension(tempProject.Value, "csproj")); - Directory.CreateDirectory(tempProject.GetDirectoryPath().Value); + tempProject = Path.ChangeExtension(tempProject, "csproj"); + Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); } var tempProjectContent = new XDocument( @@ -200,7 +200,7 @@ private FilePath CreateDirectoryWithTempProject( new XAttribute("Project", "Sdk.targets"), new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - File.WriteAllText(tempProject.ToString(), tempProjectContent.ToString()); + File.WriteAllText(tempProject, tempProjectContent.ToString()); return tempProject; } From ca4facd0618a87ebe13e562c366ff02ee588f335 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 3 Aug 2022 11:38:35 -0700 Subject: [PATCH 39/79] Fix biggest vulnerability. NEED TO TEST ON MAC --- .../SudoEnvironmentDirectoryOverride.cs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 799c99fbec39..3e4072bd2842 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -8,6 +8,7 @@ using System.Linq; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; +using Microsoft.NET.Build.Tasks; using NuGet.Common; using NuGet.Configuration; @@ -18,8 +19,6 @@ namespace Microsoft.DotNet.Cli /// public static class SudoEnvironmentDirectoryOverride { - private const string SudoHomeDirectory = "/tmp/dotnet_sudo_home/"; - /// /// Not for security use. Detect if command is running under sudo /// via if SUDO_UID being set. @@ -38,22 +37,10 @@ public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { - if (!TempHomeIsOnlyRootWritable(SudoHomeDirectory)) - { - try - { - Directory.Delete(SudoHomeDirectory, recursive: true); - } - catch (DirectoryNotFoundException) - { - // Avoid read after write race condition - } - } - - Directory.CreateDirectory(SudoHomeDirectory); + string newProcessHomeDirectory = FileUtilities.CreateTempPath(); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); - Environment.SetEnvironmentVariable("HOME", SudoHomeDirectory); + Environment.SetEnvironmentVariable("HOME", newProcessHomeDirectory); CopyUserNuGetConfigToOverriddenHome(homeBeforeOverride); } From 9caaaeed8c50b400ea1a57415604ef787fdcedfb Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 3 Aug 2022 15:03:50 -0700 Subject: [PATCH 40/79] Watchlist uses temp folder, need to verify .txt extension is OK --- .../dotnet-watch/Internal/MsBuildFileSetFactory.cs | 3 ++- src/BuiltInTools/dotnet-watch/dotnet-watch.csproj | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 77e0a621cdce..98ce0345592a 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; using Microsoft.DotNet.Watcher.Tools; using Microsoft.Extensions.Tools.Internal; +using Microsoft.NET.Build.Tasks; using IReporter = Microsoft.Extensions.Tools.Internal.IReporter; namespace Microsoft.DotNet.Watcher.Internal @@ -63,7 +64,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var watchList = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), ".txt"); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj index 636f43d119b4..c3746d05d6c6 100644 --- a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj +++ b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj @@ -23,6 +23,8 @@ + + From 8a42338d39524a91d4b929d8ced8fd97d5aab791 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 11 Aug 2022 09:27:27 -0700 Subject: [PATCH 41/79] Catch race condition on file set factory delete --- .../dotnet-watch/Internal/MsBuildFileSetFactory.cs | 9 ++++++++- .../dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 98ce0345592a..809d39b9c58f 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -196,7 +196,14 @@ public async Task CreateAsync(CancellationToken cancellationToken) { if (File.Exists(watchList)) { - File.Delete(watchList); + try + { + File.Delete(watchList); + } + catch(System.IO.IOException) + { + // Catch file locking problems on deletion. + } } } } diff --git a/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs b/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs index 00f749ca9d66..b8728a654057 100644 --- a/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs +++ b/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs @@ -308,7 +308,7 @@ public async Task TransitiveProjectReferences_TwoLevels() Assert.All(fileset, f => Assert.False(f.IsStaticFile, $"File {f.FilePath} should not be a static file.")); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/29213")] + [Fact] public async Task ProjectReferences_Graph() { // A->B,F,W(Watch=False) From f8e33070e4a0c8cdd04aabc7ab6b9eab49167e75 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 10 Aug 2022 16:06:50 -0700 Subject: [PATCH 42/79] use temp path for nupkg. audited all of the varialbes relying on tempdir and seems fine --- .../install/ToolInstallGlobalOrToolPathCommand.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 7e06aae182b1..987fc0a16d00 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -19,6 +19,7 @@ using NuGet.Common; using NuGet.Frameworks; using NuGet.Versioning; +using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.Tools.Tool.Install { @@ -72,7 +73,7 @@ public ToolInstallGlobalOrToolPathCommand( _environmentPathInstruction = environmentPathInstruction ?? EnvironmentPathFactory.CreateEnvironmentPathInstruction(); _createShellShimRepository = createShellShimRepository ?? ShellShimRepositoryFactory.CreateShellShimRepository; - var tempDir = new DirectoryPath(Path.Combine(Path.GetTempPath(), "dotnet-tool-install")); + var tempDir = new DirectoryPath(FileUtilities.CreateTempPath()); var configOption = parseResult.GetValueForOption(ToolInstallCommandParser.ConfigOption); var sourceOption = parseResult.GetValueForOption(ToolInstallCommandParser.AddSourceOption); var packageSourceLocation = new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), additionalSourceFeeds: sourceOption); @@ -143,7 +144,7 @@ public override int Execute() } else { - framework = string.IsNullOrEmpty(_framework) ? + framework = string.IsNullOrEmpty(_framework) ? null : NuGetFramework.Parse(_framework); } From 116ff9429788e7bbabe020b5b180d734bb9d59fc Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 10 Aug 2022 16:32:05 -0700 Subject: [PATCH 43/79] Apply change to shellshimremover --- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 4dee9748d079..6a653eee5887 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -9,6 +9,7 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.ShellShim { @@ -85,7 +86,8 @@ public void CreateShim(FilePath targetExecutablePath, ToolCommandName commandNam ex); } }, - rollback: () => { + rollback: () => + { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { File.Delete(file.Value); @@ -97,12 +99,13 @@ public void RemoveShim(ToolCommandName commandName) { var files = new Dictionary(); TransactionalAction.Run( - action: () => { + action: () => + { try { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - var tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var tempPath = FileUtilities.CreateTempPath(); FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); files[file.Value] = tempPath; } @@ -118,13 +121,15 @@ public void RemoveShim(ToolCommandName commandName) ex); } }, - commit: () => { + commit: () => + { foreach (var value in files.Values) { _fileSystem.File.Delete(value); } }, - rollback: () => { + rollback: () => + { foreach (var kvp in files) { FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(kvp.Value, kvp.Key)); From 067b636f6a486dff6e693d4a91cc9f87fed5331e Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 11 Aug 2022 17:00:51 -0700 Subject: [PATCH 44/79] Security check on workload command base --- .../dotnet/commands/dotnet-workload/WorkloadCommandBase.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs index 55bd273ae1c2..83c092b16672 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs @@ -8,6 +8,7 @@ using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; using NuGet.Common; namespace Microsoft.DotNet.Workloads.Workload @@ -104,9 +105,10 @@ public WorkloadCommandBase(ParseResult parseResult, ? tempDirPath : !string.IsNullOrWhiteSpace(parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption)) ? parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption) - : Path.GetTempPath(); + : ""; - TempPackagesDirectory = new DirectoryPath(Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); + // The security owness on a custom tempDir is on the user according to docs. + TempPackagesDirectory = new DirectoryPath(TempDirectoryPath == "" ? FileUtilities.CreateTempPath() : Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); PackageDownloader = nugetPackageDownloader ?? new NuGetPackageDownloader(TempPackagesDirectory, filePermissionSetter: null, From 5c4e65a2ad1375931dd46f7648ad4c8e263ba607 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 12 Aug 2022 14:28:44 -0700 Subject: [PATCH 45/79] Dispose file and fix problem in shellshimrepo. We dont use move anymore because we need someone to make a file with secure permissions and gettempfilename does that but getrandomfilename does not. Moving a file would override the permissions so we copy file contents over. --- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 12 +++++++++--- src/Tasks/Common/FileUtilities.cs | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 6a653eee5887..79c02050afe3 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -105,9 +105,15 @@ public void RemoveShim(ToolCommandName commandName) { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - var tempPath = FileUtilities.CreateTempPath(); - FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); - files[file.Value] = tempPath; + using (var tempPath = File.OpenWrite(FileUtilities.CreateTempFile())) + { + Stream oldFile = _fileSystem.File.OpenRead(file.Value); + oldFile.Seek(0, SeekOrigin.Begin); + oldFile.CopyTo(tempPath); + oldFile.Dispose(); + File.Delete(file.Value); + files[file.Value] = tempPath.Name; + } } } catch (Exception ex) when (ex is UnauthorizedAccessException || ex is IOException) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index e6c607d3444c..0ef0f61acfb6 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -43,12 +43,25 @@ public static string CreateTempPath() return path; } - public static string CreateTempFile(string tempDirectory, string extension) + public static string CreateTempFile(string tempDirectory, string extension="") { + if(extension == "") + { + extension = Path.GetExtension(Path.GetRandomFileName()); + } string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); File.Create(fileName.ToString()); return fileName; } + /// + /// + /// + /// The full path of a newly created temp file with OK permissions. + public static string CreateTempFile() + { + return Path.GetTempFileName(); + } + } } From 1a29f9e1d9a2c4f5fbaf1b7b98c15593806fe78b Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 12 Aug 2022 15:34:08 -0700 Subject: [PATCH 46/79] [wip] add some code to try to fix directory bug. Not sure how to use this new lib, need to ask some people --- src/Tasks/Common/FileUtilities.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 0ef0f61acfb6..199c8eda7200 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -7,6 +7,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli; namespace Microsoft.NET.Build.Tasks { @@ -35,11 +37,19 @@ public static Version TryGetAssemblyVersion(string sourcePath) return s_assemblyExtensions.Contains(extension) ? GetAssemblyVersion(sourcePath) : null; } + [DllImport("libc", SetLastError = true)] + public static extern int mkdir(string pathname, UnixFileMode mode); public static string CreateTempPath() { - // TODO: Make this call the API once it is complete. string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(path); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + mkdir(path, StatInterop.Permissions.S_IRWXU) + } + else + { + Directory.CreateDirectory(path, StatInterop.Permissions.S_IRWXU); + } return path; } From 8d01c5beed8714fc293b30ee1fd7f8f289ac3b9c Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 10:14:30 -0700 Subject: [PATCH 47/79] Do the secure thing for temp files in fileutilities --- src/Tasks/Common/FileUtilities.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 199c8eda7200..ef205fb3f32c 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -38,24 +38,28 @@ public static Version TryGetAssemblyVersion(string sourcePath) } [DllImport("libc", SetLastError = true)] - public static extern int mkdir(string pathname, UnixFileMode mode); + public static extern int mkdir(string pathname, uint mode); public static string CreateTempPath() { string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - mkdir(path, StatInterop.Permissions.S_IRWXU) + int dotnet_version = 7; // Changed in backported code. This can be out of date for .NET 8+ and still be fine. + if (dotnet_version < 7) + mkdir(path, 007000); + else + Directory.CreateDirectory(path, UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.UserRead); } else { - Directory.CreateDirectory(path, StatInterop.Permissions.S_IRWXU); + Directory.CreateDirectory(path); } return path; } - public static string CreateTempFile(string tempDirectory, string extension="") + public static string CreateTempFile(string tempDirectory, string extension = "") { - if(extension == "") + if (extension == "") { extension = Path.GetExtension(Path.GetRandomFileName()); } From d86cf02f544ee6ba53154b0fa721cd3bfcabe55c Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:15:36 -0700 Subject: [PATCH 48/79] Fix security bug in file based installer --- src/Cli/dotnet/commands/InstallingWorkloadCommand.cs | 3 ++- .../commands/dotnet-workload/install/FileBasedInstaller.cs | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index d8df4fb955aa..17c7fd0c0253 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -19,6 +19,7 @@ using Microsoft.DotNet.Workloads.Workload.Install; using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Versioning; using Command = System.CommandLine.Command; @@ -98,7 +99,7 @@ protected async Task> GetDownloads(IEnumerable workloadIds, SdkFeatureBand Directory.Delete(dir, true); } } - }); + }); } } From f227ba9a134c94c4e40a3008a0b5436d0cafb74f Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:19:16 -0700 Subject: [PATCH 49/79] Apply change to workloadmanifestupdater --- .../install/WorkloadManifestUpdater.cs | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index 048d3dc22889..58829d383218 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -17,6 +17,7 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Common; using NuGet.Versioning; @@ -69,7 +70,7 @@ private static WorkloadManifestUpdater GetInstance(string userProfileDir) var sdkVersion = Product.Version; var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, sdkVersion, userProfileDir); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, dotnetPath, sdkVersion, userProfileDir); - var tempPackagesDir = new DirectoryPath(Path.Combine(Path.GetTempPath(), "dotnet-sdk-advertising-temp")); + var tempPackagesDir = new DirectoryPath(FileUtilities.CreateTempPath()); var nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(), @@ -189,9 +190,9 @@ Dictionary Workloads } if (advertisingManifestVersionAndWorkloads != null && - ((advertisingManifestVersionAndWorkloads.Value.ManifestVersion.CompareTo(currentManifestVersion.manifestVersion) > 0 + ((advertisingManifestVersionAndWorkloads.Value.ManifestVersion.CompareTo(currentManifestVersion.manifestVersion) > 0 && advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.Equals(currentManifestVersion.sdkFeatureBand)) || - advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.CompareTo(currentManifestVersion.sdkFeatureBand) > 0)) + advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.CompareTo(currentManifestVersion.sdkFeatureBand) > 0)) { manifestUpdates.Add((new ManifestVersionUpdate(manifestId, currentManifestVersion.manifestVersion, currentManifestVersion.sdkFeatureBand.ToString(), advertisingManifestVersionAndWorkloads.Value.ManifestVersion, advertisingManifestVersionAndWorkloads.Value.ManifestFeatureBand.ToString()), @@ -307,7 +308,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, try { var adManifestPath = GetAdvertisingManifestPath(_sdkFeatureBand, manifestId); - + bool success; (success, packagePath) = await GetManifestPackageUpdate(_sdkFeatureBand, manifestId, includePreviews, offlineCache); if (!success) @@ -323,7 +324,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestPackageDoesNotExist, manifestId)); return; } - + await _workloadManifestInstaller.ExtractManifestAsync(packagePath, adManifestPath); // add file that contains the advertisted manifest feature band so GetAdvertisingManifestVersionAndWorkloads will use correct feature band, regardless of if rollback occurred or not @@ -384,7 +385,7 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, { adManifestFeatureBand = new SdkFeatureBand(File.ReadAllText(adManifestFeatureBandPath)); } - + return (new ManifestVersion(manifest.Version), adManifestFeatureBand, manifest.Workloads.Values.OfType().ToDictionary(w => w.Id)); } @@ -470,12 +471,12 @@ private async Task NewerManifestPackageExists(ManifestId manifest) ManifestVersion manifestVersion; SdkFeatureBand manifestFeatureBand; var parts = manifest.Value.Split('/'); - + string manifestVersionString = (parts[0]); if (!FXVersion.TryParse(manifestVersionString, out FXVersion version)) { throw new FormatException(String.Format(LocalizableStrings.InvalidVersionForWorkload, manifest.Key, manifestVersionString)); - } + } manifestVersion = new ManifestVersion(parts[0]); if (parts.Length == 1) @@ -499,15 +500,15 @@ private bool BackgroundUpdatesAreDisabled() => private static string GetAdvertisingWorkloadsFilePath(string userProfileDir, SdkFeatureBand featureBand) => Path.Combine(userProfileDir, $".workloadAdvertisingUpdates{featureBand}"); - private async Task GetOnlinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, bool includePreviews) - { - string packagePath = await _nugetPackageDownloader.DownloadPackageAsync( - _workloadManifestInstaller.GetManifestPackageId(manifestId, sdkFeatureBand), - packageSourceLocation: _packageSourceLocation, - includePreview: includePreviews); - - return packagePath; - } + private async Task GetOnlinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, bool includePreviews) + { + string packagePath = await _nugetPackageDownloader.DownloadPackageAsync( + _workloadManifestInstaller.GetManifestPackageId(manifestId, sdkFeatureBand), + packageSourceLocation: _packageSourceLocation, + includePreview: includePreviews); + + return packagePath; + } private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, DirectoryPath? offlineCache = null) { @@ -527,7 +528,7 @@ private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId m { if (offlineCache == null || !offlineCache.HasValue) { - try + try { string packagePath = await GetOnlinePackagePath(sdkFeatureBand, manifestId, includePreviews); return (true, packagePath); From cf0fc8da908334cab52aeae00f86c7f9000ec742 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:31:16 -0700 Subject: [PATCH 50/79] Fix uint perm --- src/Tasks/Common/FileUtilities.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index ef205fb3f32c..0de7f99b8c28 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -8,7 +8,6 @@ using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using Microsoft.DotNet.Cli; namespace Microsoft.NET.Build.Tasks { @@ -46,7 +45,7 @@ public static string CreateTempPath() { int dotnet_version = 7; // Changed in backported code. This can be out of date for .NET 8+ and still be fine. if (dotnet_version < 7) - mkdir(path, 007000); + mkdir(path, 0000700); else Directory.CreateDirectory(path, UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.UserRead); } From 2f1160940f344e6f8b7025e06dccd0aae40f8e68 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:32:31 -0700 Subject: [PATCH 51/79] Ditch unix file mode --- src/Tasks/Common/FileUtilities.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 0de7f99b8c28..b93077d34602 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -43,11 +43,7 @@ public static string CreateTempPath() string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - int dotnet_version = 7; // Changed in backported code. This can be out of date for .NET 8+ and still be fine. - if (dotnet_version < 7) - mkdir(path, 0000700); - else - Directory.CreateDirectory(path, UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.UserRead); + mkdir(path, 0000700); } else { From 3bc1080761baf86c883aa3cce80fc7c0d4b3ca7d Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 11:58:42 -0700 Subject: [PATCH 52/79] Fix silly bug with temp path. --- src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs index 83c092b16672..33c6eed92276 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs @@ -105,7 +105,7 @@ public WorkloadCommandBase(ParseResult parseResult, ? tempDirPath : !string.IsNullOrWhiteSpace(parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption)) ? parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption) - : ""; + : FileUtilities.CreateTempPath(); // The security owness on a custom tempDir is on the user according to docs. TempPackagesDirectory = new DirectoryPath(TempDirectoryPath == "" ? FileUtilities.CreateTempPath() : Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); From cbc8f4024136896df2a740468af06beb9ee983a7 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 17 Aug 2022 15:18:25 -0700 Subject: [PATCH 53/79] Override chown and chmod use to give user perm instead of sudo perm --- .../SudoEnvironmentDirectoryOverride.cs | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 3e4072bd2842..9071e4c4c68f 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -6,6 +6,7 @@ using System.CommandLine.Parsing; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; using Microsoft.NET.Build.Tasks; @@ -33,12 +34,26 @@ public static bool IsRunningUnderSudo() return false; } + + [DllImport("libc", SetLastError = true)] + public static extern int chown(string username, string path); + [DllImport("libc", SetLastError = true)] + private static extern int chmod(string pathname, uint mode); + private static void OverridePathFromSudoPermToSudoUserPerm(string path) + { + if (!OperatingSystem.IsWindows() && IsRunningUnderSudo()) + { + chown(Environment.GetEnvironmentVariable("SUDO_USER"), path); + chmod(path, 0000700); + } + } + public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { string newProcessHomeDirectory = FileUtilities.CreateTempPath(); - + OverridePathFromSudoPermToSudoUserPerm(newProcessHomeDirectory); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); Environment.SetEnvironmentVariable("HOME", newProcessHomeDirectory); @@ -108,12 +123,12 @@ private static bool TempHomeIsOnlyRootWritable(string path) private static bool OtherUserCannotWrite(StatInterop.FileStatus fileStat) { - return (fileStat.Mode & (int) StatInterop.Permissions.S_IWOTH) == 0; + return (fileStat.Mode & (int)StatInterop.Permissions.S_IWOTH) == 0; } private static bool GroupCannotWrite(StatInterop.FileStatus fileStat) { - return (fileStat.Mode & (int) StatInterop.Permissions.S_IWGRP) == 0; + return (fileStat.Mode & (int)StatInterop.Permissions.S_IWGRP) == 0; } private static bool IsOwnedByRoot(StatInterop.FileStatus fileStat) From 237f5adcac11561a3abbf783b61335f4c1dbfad9 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 18 Aug 2022 11:19:17 -0700 Subject: [PATCH 54/79] Drop lock on file --- .../dotnet-watch/Internal/MsBuildFileSetFactory.cs | 2 +- src/Tasks/Common/FileUtilities.cs | 3 ++- src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 809d39b9c58f..2b0751881b3a 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -64,7 +64,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), ".txt"); + var watchList = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath()); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index b93077d34602..aeeb1c4c1437 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -59,7 +59,8 @@ public static string CreateTempFile(string tempDirectory, string extension = "") extension = Path.GetExtension(Path.GetRandomFileName()); } string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); - File.Create(fileName.ToString()); + var fstream = File.Create(fileName.ToString()); + fstream.Close(); return fileName; } diff --git a/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs b/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs index b8728a654057..00f749ca9d66 100644 --- a/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs +++ b/src/Tests/dotnet-watch.Tests/MsBuildFileSetFactoryTest.cs @@ -308,7 +308,7 @@ public async Task TransitiveProjectReferences_TwoLevels() Assert.All(fileset, f => Assert.False(f.IsStaticFile, $"File {f.FilePath} should not be a static file.")); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/29213")] public async Task ProjectReferences_Graph() { // A->B,F,W(Watch=False) From 1c888f37021d36548258975edddd550ac21bdb60 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 18 Aug 2022 11:30:55 -0700 Subject: [PATCH 55/79] Use my createtempfile function in toolcmd --- src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index d2ec50c5dcf9..4b86af94aa59 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -130,7 +130,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( string verbosity = null) { var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); - File.WriteAllText(Path.Combine(tempDirectoryForAssetJson, "file1.txt"), null); + FileUtilities.CreateTempFile(tempDirectoryForAssetJson); string tempProject = CreateDirectoryWithTempProject( packageId: packageId, From d2cc1dd9955122a66e81847f1540794283ce2340 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 19 Aug 2022 14:27:54 -0700 Subject: [PATCH 56/79] make changes to lock file --- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 79c02050afe3..9913180f14ba 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -107,7 +107,9 @@ public void RemoveShim(ToolCommandName commandName) { using (var tempPath = File.OpenWrite(FileUtilities.CreateTempFile())) { - Stream oldFile = _fileSystem.File.OpenRead(file.Value); + if (!File.Exists(file.Value)) + continue; + Stream oldFile = new FileStream(file.Value, FileMode.Open, FileAccess.ReadWrite, FileShare.None); oldFile.Seek(0, SeekOrigin.Begin); oldFile.CopyTo(tempPath); oldFile.Dispose(); From 59228ce6c1bc40d51549e87d8bcc293075bab8f1 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 23 Aug 2022 14:24:18 -0700 Subject: [PATCH 57/79] Fix bug with secure file moving --- src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs | 4 +--- src/Tasks/Common/FileUtilities.cs | 11 +++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 9071e4c4c68f..be1e5e83f402 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -37,14 +37,12 @@ public static bool IsRunningUnderSudo() [DllImport("libc", SetLastError = true)] public static extern int chown(string username, string path); - [DllImport("libc", SetLastError = true)] - private static extern int chmod(string pathname, uint mode); private static void OverridePathFromSudoPermToSudoUserPerm(string path) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo()) { chown(Environment.GetEnvironmentVariable("SUDO_USER"), path); - chmod(path, 0000700); + FileUtilities.ResetTempFilePermissions(path); } } diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index aeeb1c4c1437..1c73015c7c3f 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -73,5 +73,16 @@ public static string CreateTempFile() return Path.GetTempFileName(); } + + [DllImport("libc", SetLastError = true)] + private static extern int chmod(string pathname, uint mode); + public static void ResetTempFilePermissions(string path) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + chmod(path, 0000700); + } + } + } } From 6e8962624ee92f1539782e6214001ca0f9daa776 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 23 Aug 2022 14:55:17 -0700 Subject: [PATCH 58/79] Fix it runs with specified verbosity --- src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 4b86af94aa59..8bbc9d182689 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -14,6 +14,7 @@ using NuGet.ProjectModel; using NuGet.Versioning; using Microsoft.NET.Build.Tasks; +using System.Diagnostics; namespace Microsoft.DotNet.ToolPackage { @@ -165,7 +166,7 @@ private string CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProject = _tempProject.ToString() ?? (FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); + string tempProject = _tempProject != null ? _tempProject.ToString() : (FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); if (_tempProject != null) { tempProject = Path.ChangeExtension(tempProject, "csproj"); From 754a199d98d254e722be70c7b736e3379da464ec Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 22 Aug 2022 11:23:32 -0400 Subject: [PATCH 59/79] Work around analyzer bug --- src/Microsoft.Win32.Msi/NativeMethods.cs | 3 +++ src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/Microsoft.Win32.Msi/NativeMethods.cs b/src/Microsoft.Win32.Msi/NativeMethods.cs index eb60d99ac393..52936f2346b0 100644 --- a/src/Microsoft.Win32.Msi/NativeMethods.cs +++ b/src/Microsoft.Win32.Msi/NativeMethods.cs @@ -5,6 +5,9 @@ using System.Runtime.InteropServices; using System.Text; +// Work around https://github.com/dotnet/roslyn-analyzers/issues/6094 +#pragma warning disable CA1420 + namespace Microsoft.Win32.Msi { /// diff --git a/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs b/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs index a407c81d0f5c..fb0329d275c4 100644 --- a/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs +++ b/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs @@ -8,6 +8,9 @@ #nullable disable +// Work around https://github.com/dotnet/roslyn-analyzers/issues/6094 +#pragma warning disable CA1420 + namespace Microsoft.DotNet.NativeWrapper { public static partial class Interop From d5aed40959511a8fff0f5fd430cc70730959177e Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 25 Aug 2022 12:34:51 -0700 Subject: [PATCH 60/79] Try using chown in other places where sudo might be used in a workload install --- .../SudoEnvironmentDirectoryOverride.cs | 4 --- src/Tasks/Common/FileUtilities.cs | 26 ++++++++++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index be1e5e83f402..7e1861d100e7 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -34,14 +34,10 @@ public static bool IsRunningUnderSudo() return false; } - - [DllImport("libc", SetLastError = true)] - public static extern int chown(string username, string path); private static void OverridePathFromSudoPermToSudoUserPerm(string path) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo()) { - chown(Environment.GetEnvironmentVariable("SUDO_USER"), path); FileUtilities.ResetTempFilePermissions(path); } } diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 1c73015c7c3f..075ea805975a 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -37,13 +37,18 @@ public static Version TryGetAssemblyVersion(string sourcePath) } [DllImport("libc", SetLastError = true)] - public static extern int mkdir(string pathname, uint mode); + public static extern int mkdir(string pathname, int mode); public static string CreateTempPath() { string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - mkdir(path, 0000700); + const int S_IRUSR = 256; + const int S_IWUSR = 128; + const int S_IXUSR = 64; + int _700 = S_IRUSR | S_IWUSR | S_IXUSR; + mkdir(path, _700); + ResetTempFilePermissions(path); } else { @@ -61,6 +66,7 @@ public static string CreateTempFile(string tempDirectory, string extension = "") string fileName = Path.ChangeExtension(Path.Combine(tempDirectory, Path.GetTempFileName()), extension); var fstream = File.Create(fileName.ToString()); fstream.Close(); + ResetTempFilePermissions(fileName); return fileName; } @@ -75,12 +81,24 @@ public static string CreateTempFile() [DllImport("libc", SetLastError = true)] - private static extern int chmod(string pathname, uint mode); + private static extern int chmod(string pathname, int mode); + [DllImport("libc", SetLastError = true)] + public static extern int chown(string path, int owner, int group); public static void ResetTempFilePermissions(string path) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - chmod(path, 0000700); + if(Environment.GetEnvironmentVariable("SUDO_USER") != null) + { + string UID = Environment.GetEnvironmentVariable("SUDO_UID"); + string GID = Environment.GetEnvironmentVariable("SUDO_GID"); + chown(path, Int32.Parse(UID), Int32.Parse(GID)); + } + const int S_IRUSR = 256; + const int S_IWUSR = 128; + const int S_IXUSR = 64; + int _700 = S_IRUSR | S_IWUSR | S_IXUSR; + chmod(path, _700); } } From 72072e7656faa5e9617af6910abe91fedce8a31a Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 25 Aug 2022 17:02:42 -0700 Subject: [PATCH 61/79] try not calling chown --- src/Tasks/Common/FileUtilities.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 075ea805975a..f29507f9abe3 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -92,7 +92,7 @@ public static void ResetTempFilePermissions(string path) { string UID = Environment.GetEnvironmentVariable("SUDO_UID"); string GID = Environment.GetEnvironmentVariable("SUDO_GID"); - chown(path, Int32.Parse(UID), Int32.Parse(GID)); + //chown(path, Int32.Parse(UID), Int32.Parse(GID)); } const int S_IRUSR = 256; const int S_IWUSR = 128; From 2b24acb53c030a36c30edb1dc57c29b068a84754 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 26 Aug 2022 11:55:48 -0700 Subject: [PATCH 62/79] Fix ugly things I did in toolpackageinstaller --- src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 8bbc9d182689..324897160085 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -131,7 +131,6 @@ public IToolPackage InstallPackageToExternalManagedLocation( string verbosity = null) { var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); - FileUtilities.CreateTempFile(tempDirectoryForAssetJson); string tempProject = CreateDirectoryWithTempProject( packageId: packageId, @@ -166,13 +165,9 @@ private string CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProject = _tempProject != null ? _tempProject.ToString() : (FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj")); - if (_tempProject != null) - { - tempProject = Path.ChangeExtension(tempProject, "csproj"); - Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); - } + string tempProject = _tempProject != null && _tempProject.HasValue ? _tempProject.Value.Value : FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj"); + Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); var tempProjectContent = new XDocument( new XElement("Project", new XElement("PropertyGroup", From 759d99122e783cee6701408dac4febd0ec3e24ca Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 29 Aug 2022 21:41:38 +0000 Subject: [PATCH 63/79] Make output very verbose --- src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs b/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs index 4e954d6cd20e..769aee9afbc5 100644 --- a/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs +++ b/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs @@ -91,6 +91,9 @@ public void ItListsAutoReferencedPackages() .WithProjectChanges(ChangeTargetFrameworkTo2_1); var projectDirectory = testAsset.Path; + var debugCmd = new DotnetCommand(Log); + debugCmd.Execute($"dotnet", "msbuild", "--pp", $"{projectDirectory + "\\TestAppSimple.csproj"}"); + new RestoreCommand(testAsset) .Execute() .Should() From d333650ffe759d28b9b1d32f4e70e795e939d3e5 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 30 Aug 2022 15:06:23 -0700 Subject: [PATCH 64/79] Create tempfile instead of just doing path combine. --- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index f31427e80062..90d0fe0617f6 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -105,7 +105,7 @@ public void RemoveShim(ToolCommandName commandName) { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - var tempPath = Path.Combine(FileUtilities.CreateTempPath(), Path.GetRandomFileName()); + var tempPath = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath()); FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); FileUtilities.ResetTempFilePermissions(tempPath); files[file.Value] = tempPath; From e95bb26528dda306e1162a3caedcaab044dbcf0b Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 30 Aug 2022 16:08:07 -0700 Subject: [PATCH 65/79] SDK Manifest changes for MSRC --- .../install/NetSdkMsiInstallerClient.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index ed04a4548648..96d05df1cbd1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -17,6 +17,7 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.Build.Tasks; using Microsoft.NET.Sdk.WorkloadManifestReader; using Microsoft.Win32.Msi; using NuGet.Common; @@ -116,7 +117,7 @@ public void GarbageCollectInstalledWorkloadPacks(DirectoryPath? offlineCache = n Log?.LogMessage("Starting garbage collection."); IEnumerable installedFeatureBands = GetInstalledFeatureBands(); IEnumerable installedWorkloads = RecordRepository.GetInstalledWorkloads(_sdkFeatureBand); - Dictionary<(WorkloadPackId id, string version),PackInfo> expectedWorkloadPacks = installedWorkloads + Dictionary<(WorkloadPackId id, string version), PackInfo> expectedWorkloadPacks = installedWorkloads .SelectMany(workload => _workloadResolver.GetPacksInWorkload(workload)) .Distinct() .Select(pack => _workloadResolver.TryGetPackInfo(pack)) @@ -415,9 +416,9 @@ public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand RollBackMsiInstall(msiToInstall); } }); - + } - + } void RollBackMsiInstall(WorkloadDownload msiToRollback, DirectoryPath? offlineCache = null) @@ -493,7 +494,7 @@ public async Task ExtractManifestAsync(string nupkgPath, string targetPath) { Log?.LogMessage($"ExtractManifestAsync: Extracting '{nupkgPath}' to '{targetPath}'"); - string extractionPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + string extractionPath = FileUtilities.CreateTempPath(); if (Directory.Exists(extractionPath)) { Directory.Delete(extractionPath, true); @@ -502,7 +503,7 @@ public async Task ExtractManifestAsync(string nupkgPath, string targetPath) try { Directory.CreateDirectory(extractionPath); - + FileUtilities.ResetTempFilePermissions(extractionPath); Log?.LogMessage($"ExtractManifestAsync: Temporary extraction path: '{extractionPath}'"); await _nugetPackageDownloader.ExtractPackageAsync(nupkgPath, new DirectoryPath(extractionPath)); if (Directory.Exists(targetPath)) @@ -959,7 +960,7 @@ public static NetSdkMsiInstallerClient Create( if (nugetPackageDownloader == null) { - DirectoryPath tempPackagesDir = new(string.IsNullOrWhiteSpace(tempDirPath) ? Path.GetTempPath() : tempDirPath); + DirectoryPath tempPackagesDir = new(string.IsNullOrWhiteSpace(tempDirPath) ? FileUtilities.CreateTempPath() : tempDirPath); nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(), From 89f9e6698868c1630c7e8072576600370db107ae Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 31 Aug 2022 11:33:55 -0700 Subject: [PATCH 66/79] Fix directory paths to be correct --- .../DirectoryWrapper.cs | 7 ++++++- .../IDirectory.cs | 4 ++++ ...Microsoft.DotNet.InternalAbstractions.csproj | 5 +++++ .../TemporaryDirectory.cs | 3 ++- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 6 +++--- src/Cli/dotnet/dotnet.csproj | 2 -- .../GivenAFirstTimeUseNoticeSentinel.cs | 7 ++++++- ...venAFunctionReturnStringAndFakeFileSystem.cs | 5 +++++ .../Mock/FileSystemMockBuilder.cs | 17 +++++++++++------ 9 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs index 312d6fecd7d4..81b16d48858e 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs @@ -7,7 +7,7 @@ namespace Microsoft.Extensions.EnvironmentAbstractions { - internal class DirectoryWrapper: IDirectory + internal class DirectoryWrapper : IDirectory { public bool Exists(string path) { @@ -19,6 +19,11 @@ public ITemporaryDirectory CreateTemporaryDirectory() return new TemporaryDirectory(); } + public string CreateTempPath() + { + return CreateTemporaryDirectory().DirectoryPath; + } + public IEnumerable EnumerateDirectories(string path) { return Directory.EnumerateDirectories(path); diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs index 983bba34afc3..3dde961ebbe0 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs @@ -24,5 +24,9 @@ internal interface IDirectory void Delete(string path, bool recursive); void Move(string source, string destination); + + + /// Returns a new directory created under the temp folder. Can be on the mock under test or the real temp file folder. + string CreateTempPath(); } } diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj index 041ba1315c78..18944f8aad34 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj @@ -12,4 +12,9 @@ true + + + + + diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs index d43683e156f5..5ae92f86fe89 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.EnvironmentAbstractions; using System.IO; +using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.InternalAbstractions { @@ -12,7 +13,7 @@ internal class TemporaryDirectory : ITemporaryDirectory public TemporaryDirectory() { - DirectoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + DirectoryPath = Path.Combine(FileUtilities.CreateTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(DirectoryPath); } diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 90d0fe0617f6..974835928e4f 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -105,10 +105,10 @@ public void RemoveShim(ToolCommandName commandName) { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - var tempPath = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath()); + // v This should call FileUtilities for a secure directory, or call the mock temp path creator. + var tempPath = Path.Combine(_fileSystem.Directory.CreateTempPath(), Path.GetRandomFileName()); FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); - FileUtilities.ResetTempFilePermissions(tempPath); - files[file.Value] = tempPath; + files[file.Value] = tempPath; } } catch (Exception ex) when (ex is UnauthorizedAccessException || ex is IOException) diff --git a/src/Cli/dotnet/dotnet.csproj b/src/Cli/dotnet/dotnet.csproj index 1004b10a6322..bb202db43721 100644 --- a/src/Cli/dotnet/dotnet.csproj +++ b/src/Cli/dotnet/dotnet.csproj @@ -20,8 +20,6 @@ - - diff --git a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs index 843f882ffdb6..4bc243afc46e 100644 --- a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs +++ b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs @@ -26,7 +26,7 @@ public GivenAFirstTimeUseNoticeSentinel() _fileSystemMockBuilder = FileSystemMockBuilder.Create(); } - [Fact(Skip ="Product.Version not set correctly when running tests")] + [Fact(Skip = "Product.Version not set correctly when running tests")] public void TheSentinelHasTheCurrentVersionInItsName() { FirstTimeUseNoticeSentinel.SENTINEL.Should().Contain($"{Product.Version}"); @@ -174,6 +174,11 @@ public ITemporaryDirectory CreateTemporaryDirectory() throw new NotImplementedException(); } + public string CreateTempPath() + { + throw new NotImplementedException(); + } + public IEnumerable EnumerateDirectories(string path) { throw new NotImplementedException(); diff --git a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs index 10e3f1930814..f2248dbf1253 100644 --- a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs +++ b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs @@ -173,6 +173,11 @@ public IEnumerable EnumerateFileSystemEntries(string path) throw new UnauthorizedAccessException(); } + public string CreateTempPath() + { + throw new NotImplementedException(); + } + public string GetCurrentDirectory() { throw new NotImplementedException(); diff --git a/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs b/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs index 7eb9e5381989..5531cf6a76f2 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs @@ -154,7 +154,7 @@ public void CreateDirectory(string path) else { DirectoryNode directoryNode = new DirectoryNode(); - directoryNode = (DirectoryNode) current.Subs.GetOrAdd(p , directoryNode); + directoryNode = (DirectoryNode)current.Subs.GetOrAdd(p, directoryNode); current = directoryNode; } } @@ -237,7 +237,7 @@ public DirectoryNode GetParentOfDirectoryNode(string path) } PathModel pathModel = CreateFullPathModel(path); - if (current.Subs.TryGetValue(pathModel.FileOrDirectoryName(), out var node) ) + if (current.Subs.TryGetValue(pathModel.FileOrDirectoryName(), out var node)) { if (node is FileNode) { @@ -283,7 +283,7 @@ public PathModel(string path) } string[] pathArray = path.Split( - new[] {directorySeparatorChar, altDirectorySeparatorChar}, + new[] { directorySeparatorChar, altDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); Volume = volume; PathArray = pathArray; @@ -451,7 +451,7 @@ public void Move(string source, string destination) if (_files.TryGetNodeParent(destination, out DirectoryNode current) && current != null) { - sourceFileNode = (FileNode) current.Subs.GetOrAdd(new PathModel(destination).FileOrDirectoryName(), sourceFileNode); + sourceFileNode = (FileNode)current.Subs.GetOrAdd(new PathModel(destination).FileOrDirectoryName(), sourceFileNode); sourceParent.Subs.TryRemove(new PathModel(source).FileOrDirectoryName(), out _); } else @@ -525,9 +525,9 @@ public bool Exists(string path) if (_files.TryGetNodeParent(path, out DirectoryNode current)) { - PathModel pathModel = new PathModel(path); + PathModel pathModel = new PathModel(path); - return current.Subs.TryGetValue(pathModel.FileOrDirectoryName(), out var node) + return current.Subs.TryGetValue(pathModel.FileOrDirectoryName(), out var node) && node is DirectoryNode; } @@ -579,6 +579,11 @@ public void CreateDirectory(string path) _files.CreateDirectory(path); } + public string CreateTempPath() + { + return CreateTemporaryDirectory().DirectoryPath; + } + public void Delete(string path, bool recursive) { if (path == null) throw new ArgumentNullException(nameof(path)); From dc71c6ffbe189e13c167408447bbaee8a1bc4527 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 31 Aug 2022 16:09:00 -0700 Subject: [PATCH 67/79] Remove unneeded sudo directory code --- src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 7e1861d100e7..cf52e67baeb0 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -34,20 +34,11 @@ public static bool IsRunningUnderSudo() return false; } - private static void OverridePathFromSudoPermToSudoUserPerm(string path) - { - if (!OperatingSystem.IsWindows() && IsRunningUnderSudo()) - { - FileUtilities.ResetTempFilePermissions(path); - } - } - public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { string newProcessHomeDirectory = FileUtilities.CreateTempPath(); - OverridePathFromSudoPermToSudoUserPerm(newProcessHomeDirectory); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); Environment.SetEnvironmentVariable("HOME", newProcessHomeDirectory); From 95f089ef40e6689c012d8ef45ff8a4bf81137cb1 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 31 Aug 2022 16:16:11 -0700 Subject: [PATCH 68/79] Clean up code in NETSDKManifestInstaller --- .../dotnet-workload/install/NetSdkMsiInstallerClient.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 96d05df1cbd1..eeb6a6d48c77 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -493,17 +493,10 @@ public PackageId GetManifestPackageId(ManifestId manifestId, SdkFeatureBand feat public async Task ExtractManifestAsync(string nupkgPath, string targetPath) { Log?.LogMessage($"ExtractManifestAsync: Extracting '{nupkgPath}' to '{targetPath}'"); - string extractionPath = FileUtilities.CreateTempPath(); - if (Directory.Exists(extractionPath)) - { - Directory.Delete(extractionPath, true); - } try { - Directory.CreateDirectory(extractionPath); - FileUtilities.ResetTempFilePermissions(extractionPath); Log?.LogMessage($"ExtractManifestAsync: Temporary extraction path: '{extractionPath}'"); await _nugetPackageDownloader.ExtractPackageAsync(nupkgPath, new DirectoryPath(extractionPath)); if (Directory.Exists(targetPath)) From 0a2e0d32b55e821011842aac4b8fc027ada92f5c Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 31 Aug 2022 16:25:49 -0700 Subject: [PATCH 69/79] Port daniel's reviewed changes into new code --- .../dotnet-watch/Internal/MsBuildFileSetFactory.cs | 2 +- src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs | 4 ++-- src/Tasks/Common/FileUtilities.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 375cc2f50ee4..03d5f53bccf3 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -64,7 +64,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = FileUtilities.CreateTempFile(FileUtilities.CreateTempPath()); + var watchList = Path.Combine(FileUtilities.CreateTempPath(), Path.GetRandomFileName()); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index cf52e67baeb0..513a867e9704 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -38,9 +38,9 @@ public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { - string newProcessHomeDirectory = FileUtilities.CreateTempPath(); + string sudoHome = FileUtilities.CreateTempPath(); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); - Environment.SetEnvironmentVariable("HOME", newProcessHomeDirectory); + Environment.SetEnvironmentVariable("HOME", sudoHome); CopyUserNuGetConfigToOverriddenHome(homeBeforeOverride); } diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 306c11f85522..6141ea652cfd 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -82,7 +82,7 @@ public static string CreateTempFile() [DllImport("libc", SetLastError = true)] private static extern int chmod(string pathname, int mode); - public static void ResetTempFilePermissions(string path) + private static void ResetTempFilePermissions(string path) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { From 9fba57be04a1c6482548cbb0190d2528789cd1ba Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 1 Sep 2022 09:11:04 -0700 Subject: [PATCH 70/79] Remove msbuild debug code --- src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs b/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs index 769aee9afbc5..4e954d6cd20e 100644 --- a/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs +++ b/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs @@ -91,9 +91,6 @@ public void ItListsAutoReferencedPackages() .WithProjectChanges(ChangeTargetFrameworkTo2_1); var projectDirectory = testAsset.Path; - var debugCmd = new DotnetCommand(Log); - debugCmd.Execute($"dotnet", "msbuild", "--pp", $"{projectDirectory + "\\TestAppSimple.csproj"}"); - new RestoreCommand(testAsset) .Execute() .Should() From c21d76edae0d08b04ae2ba1383cab61c8ce263e1 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 6 Sep 2022 09:36:55 -0700 Subject: [PATCH 71/79] Respond to daniel's PR feedback --- .../FilePath.cs | 2 +- .../TemporaryDirectory.cs | 3 +- .../dotnet/ShellShim/ShellShimRepository.cs | 1 - .../SudoEnvironmentDirectoryOverride.cs | 26 ------------- .../ToolPackage/ToolPackageInstaller.cs | 10 ++++- .../commands/InstallingWorkloadCommand.cs | 1 - .../dotnet-workload/WorkloadCommandBase.cs | 1 - .../install/FileBasedInstaller.cs | 1 - src/Tasks/Common/FileUtilities.cs | 38 +------------------ .../ToolPackageInstallerNugetCacheTests.cs | 2 +- .../ToolPackageInstallerTests.cs | 4 +- 11 files changed, 15 insertions(+), 74 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs index 3532e058decf..0bb2e793b247 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs @@ -25,7 +25,7 @@ public FilePath(string value) public string ToQuotedString() { - return $"\"{Value}\""; + return Value; } public override string ToString() diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs index 5ae92f86fe89..e6d33775e515 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs @@ -13,8 +13,7 @@ internal class TemporaryDirectory : ITemporaryDirectory public TemporaryDirectory() { - DirectoryPath = Path.Combine(FileUtilities.CreateTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(DirectoryPath); + DirectoryPath = Path.Combine(FileUtilities.CreateTempPath()); } public void Dispose() diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 974835928e4f..453beb34550b 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -105,7 +105,6 @@ public void RemoveShim(ToolCommandName commandName) { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - // v This should call FileUtilities for a secure directory, or call the mock temp path creator. var tempPath = Path.Combine(_fileSystem.Directory.CreateTempPath(), Path.GetRandomFileName()); FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); files[file.Value] = tempPath; diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 513a867e9704..479618e4b819 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -94,31 +94,5 @@ private static void CopyUserNuGetConfigToOverriddenHome(string homeBeforeOverrid private static bool IsRunningWorkloadCommand(ParseResult parseResult) => parseResult.RootSubCommandResult() == (WorkloadCommandParser.GetCommand().Name); - - private static bool TempHomeIsOnlyRootWritable(string path) - { - if (StatInterop.LStat(path, out StatInterop.FileStatus fileStat) != 0) - { - return false; - } - - return IsOwnedByRoot(fileStat) && GroupCannotWrite(fileStat) && - OtherUserCannotWrite(fileStat); - } - - private static bool OtherUserCannotWrite(StatInterop.FileStatus fileStat) - { - return (fileStat.Mode & (int)StatInterop.Permissions.S_IWOTH) == 0; - } - - private static bool GroupCannotWrite(StatInterop.FileStatus fileStat) - { - return (fileStat.Mode & (int)StatInterop.Permissions.S_IWGRP) == 0; - } - - private static bool IsOwnedByRoot(StatInterop.FileStatus fileStat) - { - return fileStat.Uid == 0; - } } } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index d76bb51298f7..c998e5773b3b 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -165,9 +165,15 @@ private string CreateDirectoryWithTempProject( DirectoryPath? rootConfigDirectory, string[] additionalFeeds) { - string tempProject = _tempProject != null && _tempProject.HasValue ? _tempProject.Value.Value : FileUtilities.CreateTempFile(FileUtilities.CreateTempPath(), "csproj"); + string tempProject; + if (_tempProject != null && _tempProject.HasValue) + { + tempProject = _tempProject.Value.Value; + Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); + } + else + tempProject = Path.Combine(FileUtilities.CreateTempPath(), "restore.csproj"); - Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); var tempProjectContent = new XDocument( new XElement("Project", new XElement("PropertyGroup", diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index a39aa1d95485..ea8d000e0e20 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -99,7 +99,6 @@ protected async Task> GetDownloads(IEnumerable - /// - /// - /// The full path of a newly created temp file with OK permissions. - public static string CreateTempFile() - { - return Path.GetTempFileName(); - } - - - [DllImport("libc", SetLastError = true)] - private static extern int chmod(string pathname, int mode); - private static void ResetTempFilePermissions(string path) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - chmod(path, PERMISSIONS_OCTAL_700); - } - } - } } diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs index 41e71c959799..87e65c490cab 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs @@ -167,7 +167,7 @@ private static List GetMockFeedsForConfigFile(FilePath nugetConfig) installer = new ToolPackageInstaller( store: store, projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(testDirectory), // <-- is this a concern? + tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(testDirectory), offlineFeed: offlineFeed ?? new DirectoryPath("does not exist")); } diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs index 0c1d2a0b434c..5582afd6de04 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs @@ -738,7 +738,7 @@ public void GivenARootWithNonAsciiCharacterInstallSucceeds() var installer = new ToolPackageInstaller( store: store, projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: GetUniqueTempProjectPathEachTest(), // <-- is this a concern? + tempProject: GetUniqueTempProjectPathEachTest(), offlineFeed: new DirectoryPath("does not exist")); var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), @@ -1059,7 +1059,7 @@ private static string GetTestLocalFeedPath() => private readonly string _testTargetframework = BundledTargetFramework.GetTargetFrameworkMoniker(); private const string TestPackageVersion = "1.0.4"; private static readonly PackageId TestPackageId = new PackageId("global.tool.console.demo"); - private static readonly IEnumerable TestFrameworks = new NuGetFramework[] { NuGetFramework.Parse("netcoreapp2.1")}; + private static readonly IEnumerable TestFrameworks = new NuGetFramework[] { NuGetFramework.Parse("netcoreapp2.1") }; public ToolPackageInstallerTests(ITestOutputHelper log) : base(log) { From f98a3bee32c18f4b4592f705af806aa02307cb3b Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 6 Sep 2022 09:53:12 -0700 Subject: [PATCH 72/79] Rename createtemppath --- .../dotnet-watch/Internal/MsBuildFileSetFactory.cs | 2 +- src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs | 4 ++-- .../TemporaryDirectory.cs | 2 +- src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs | 2 +- src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs | 4 ++-- .../dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs | 2 +- .../dotnet/commands/dotnet-workload/WorkloadCommandBase.cs | 2 +- .../commands/dotnet-workload/install/FileBasedInstaller.cs | 2 +- .../dotnet-workload/install/NetSdkMsiInstallerClient.cs | 4 ++-- .../dotnet-workload/install/WorkloadManifestUpdater.cs | 2 +- src/Tasks/Common/FileUtilities.cs | 4 ++-- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 03d5f53bccf3..5a4dd5874e22 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -64,7 +64,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = Path.Combine(FileUtilities.CreateTempPath(), Path.GetRandomFileName()); + var watchList = Path.Combine(FileUtilities.CreateTempSubdirectory(), Path.GetRandomFileName()); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs index 0bb2e793b247..cf69976a0844 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs @@ -25,12 +25,12 @@ public FilePath(string value) public string ToQuotedString() { - return Value; + return $"\"{Value}\""; } public override string ToString() { - return $"{Value}"; + return Value; } public DirectoryPath GetDirectoryPath() diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs index e6d33775e515..d1b703277fb7 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs @@ -13,7 +13,7 @@ internal class TemporaryDirectory : ITemporaryDirectory public TemporaryDirectory() { - DirectoryPath = Path.Combine(FileUtilities.CreateTempPath()); + DirectoryPath = Path.Combine(FileUtilities.CreateTempSubdirectory()); } public void Dispose() diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 479618e4b819..24d118013443 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -38,7 +38,7 @@ public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { - string sudoHome = FileUtilities.CreateTempPath(); + string sudoHome = FileUtilities.CreateTempSubdirectory(); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); Environment.SetEnvironmentVariable("HOME", sudoHome); diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index c998e5773b3b..0925d89d09ad 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -130,7 +130,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( string targetFramework = null, string verbosity = null) { - var tempDirectoryForAssetJson = FileUtilities.CreateTempPath(); + var tempDirectoryForAssetJson = FileUtilities.CreateTempSubdirectory(); string tempProject = CreateDirectoryWithTempProject( packageId: packageId, @@ -172,7 +172,7 @@ private string CreateDirectoryWithTempProject( Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); } else - tempProject = Path.Combine(FileUtilities.CreateTempPath(), "restore.csproj"); + tempProject = Path.Combine(FileUtilities.CreateTempSubdirectory(), "restore.csproj"); var tempProjectContent = new XDocument( new XElement("Project", diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 987fc0a16d00..a941d249e941 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -73,7 +73,7 @@ public ToolInstallGlobalOrToolPathCommand( _environmentPathInstruction = environmentPathInstruction ?? EnvironmentPathFactory.CreateEnvironmentPathInstruction(); _createShellShimRepository = createShellShimRepository ?? ShellShimRepositoryFactory.CreateShellShimRepository; - var tempDir = new DirectoryPath(FileUtilities.CreateTempPath()); + var tempDir = new DirectoryPath(FileUtilities.CreateTempSubdirectory()); var configOption = parseResult.GetValueForOption(ToolInstallCommandParser.ConfigOption); var sourceOption = parseResult.GetValueForOption(ToolInstallCommandParser.AddSourceOption); var packageSourceLocation = new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), additionalSourceFeeds: sourceOption); diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs index 0a4c73e933c8..b0bd8ddb3eeb 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs @@ -105,7 +105,7 @@ public WorkloadCommandBase(ParseResult parseResult, ? tempDirPath : !string.IsNullOrWhiteSpace(parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption)) ? parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption) - : FileUtilities.CreateTempPath(); + : FileUtilities.CreateTempSubdirectory(); TempPackagesDirectory = new DirectoryPath(Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index f5f3370f1381..c501530abef9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -52,7 +52,7 @@ public FileBasedInstaller(IReporter reporter, { _userProfileDir = userProfileDir; _dotnetDir = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); - _tempPackagesDir = new DirectoryPath(tempDirPath ?? FileUtilities.CreateTempPath()); + _tempPackagesDir = new DirectoryPath(tempDirPath ?? FileUtilities.CreateTempSubdirectory()); ILogger logger = verbosity.VerbosityIsDetailedOrDiagnostic() ? new NuGetConsoleLogger() : new NullLogger(); _restoreActionConfig = restoreActionConfig; _nugetPackageDownloader = nugetPackageDownloader ?? diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index eeb6a6d48c77..97f1d2fc9044 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -493,7 +493,7 @@ public PackageId GetManifestPackageId(ManifestId manifestId, SdkFeatureBand feat public async Task ExtractManifestAsync(string nupkgPath, string targetPath) { Log?.LogMessage($"ExtractManifestAsync: Extracting '{nupkgPath}' to '{targetPath}'"); - string extractionPath = FileUtilities.CreateTempPath(); + string extractionPath = FileUtilities.CreateTempSubdirectory(); try { @@ -953,7 +953,7 @@ public static NetSdkMsiInstallerClient Create( if (nugetPackageDownloader == null) { - DirectoryPath tempPackagesDir = new(string.IsNullOrWhiteSpace(tempDirPath) ? FileUtilities.CreateTempPath() : tempDirPath); + DirectoryPath tempPackagesDir = new(string.IsNullOrWhiteSpace(tempDirPath) ? FileUtilities.CreateTempSubdirectory() : tempDirPath); nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(), diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index 58829d383218..4c0abf35173d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -70,7 +70,7 @@ private static WorkloadManifestUpdater GetInstance(string userProfileDir) var sdkVersion = Product.Version; var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, sdkVersion, userProfileDir); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, dotnetPath, sdkVersion, userProfileDir); - var tempPackagesDir = new DirectoryPath(FileUtilities.CreateTempPath()); + var tempPackagesDir = new DirectoryPath(FileUtilities.CreateTempSubdirectory()); var nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(), diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 840d43ff5aef..2f3c01d53b1d 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -42,8 +42,8 @@ public static Version TryGetAssemblyVersion(string sourcePath) } [DllImport("libc", SetLastError = true)] - public static extern int mkdir(string pathname, int mode); - public static string CreateTempPath() + private static extern int mkdir(string pathname, int mode); + public static string CreateTempSubdirectory() { string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) From a2a123948db05732d259990dd8d03d8f9b531595 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 6 Sep 2022 13:11:16 -0700 Subject: [PATCH 73/79] Move FileUtilities to PathUtilities in src/common, add consts --- .../Internal/MsBuildFileSetFactory.cs | 3 +- .../dotnet-watch/dotnet-watch.csproj | 3 +- ...crosoft.DotNet.InternalAbstractions.csproj | 4 +-- .../TemporaryDirectory.cs | 6 ++-- .../dotnet/ShellShim/ShellShimRepository.cs | 1 - .../SudoEnvironmentDirectoryOverride.cs | 6 +--- .../ToolPackage/ToolPackageInstaller.cs | 7 ++-- .../commands/InstallingWorkloadCommand.cs | 4 --- .../ToolInstallGlobalOrToolPathCommand.cs | 4 +-- .../dotnet-workload/WorkloadCommandBase.cs | 4 +-- .../install/FileBasedInstaller.cs | 10 +++--- .../install/NetSdkMsiInstallerClient.cs | 6 ++-- .../install/WorkloadManifestUpdater.cs | 12 +++---- src/Cli/dotnet/dotnet.csproj | 3 +- src/Common/PathUtilities.cs | 33 +++++++++++++++++++ src/Tasks/Common/FileUtilities.cs | 22 ------------- 16 files changed, 56 insertions(+), 72 deletions(-) create mode 100644 src/Common/PathUtilities.cs diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 5a4dd5874e22..792d8623c49a 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -11,7 +11,6 @@ using System.Threading.Tasks; using Microsoft.DotNet.Watcher.Tools; using Microsoft.Extensions.Tools.Internal; -using Microsoft.NET.Build.Tasks; using IReporter = Microsoft.Extensions.Tools.Internal.IReporter; namespace Microsoft.DotNet.Watcher.Internal @@ -64,7 +63,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = Path.Combine(FileUtilities.CreateTempSubdirectory(), Path.GetRandomFileName()); + var watchList = Path.Combine(PathUtilities.CreateTempSubdirectory(), Path.GetRandomFileName()); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj index c3746d05d6c6..065f750f7200 100644 --- a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj +++ b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj @@ -23,8 +23,7 @@ - - + diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj index 18944f8aad34..6260c984866d 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj @@ -13,8 +13,6 @@ - - - + diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs index d1b703277fb7..9ce8241c8967 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/TemporaryDirectory.cs @@ -1,9 +1,9 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.Extensions.EnvironmentAbstractions; using System.IO; -using Microsoft.NET.Build.Tasks; +using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.DotNet; namespace Microsoft.DotNet.InternalAbstractions { @@ -13,7 +13,7 @@ internal class TemporaryDirectory : ITemporaryDirectory public TemporaryDirectory() { - DirectoryPath = Path.Combine(FileUtilities.CreateTempSubdirectory()); + DirectoryPath = Path.Combine(PathUtilities.CreateTempSubdirectory()); } public void Dispose() diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index 453beb34550b..c46e44cf9de2 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -9,7 +9,6 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools; using Microsoft.Extensions.EnvironmentAbstractions; -using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.ShellShim { diff --git a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs index 24d118013443..8b04671a631b 100644 --- a/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs +++ b/src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs @@ -3,13 +3,9 @@ using System; using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Tools.Common; -using Microsoft.NET.Build.Tasks; using NuGet.Common; using NuGet.Configuration; @@ -38,7 +34,7 @@ public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { - string sudoHome = FileUtilities.CreateTempSubdirectory(); + string sudoHome = PathUtilities.CreateTempSubdirectory(); var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME")); Environment.SetEnvironmentVariable("HOME", sudoHome); diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 0925d89d09ad..f9d20bf96648 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -11,10 +11,7 @@ using Microsoft.DotNet.Configurer; using Microsoft.DotNet.Tools; using Microsoft.Extensions.EnvironmentAbstractions; -using NuGet.ProjectModel; using NuGet.Versioning; -using Microsoft.NET.Build.Tasks; -using System.Diagnostics; namespace Microsoft.DotNet.ToolPackage { @@ -130,7 +127,7 @@ public IToolPackage InstallPackageToExternalManagedLocation( string targetFramework = null, string verbosity = null) { - var tempDirectoryForAssetJson = FileUtilities.CreateTempSubdirectory(); + var tempDirectoryForAssetJson = PathUtilities.CreateTempSubdirectory(); string tempProject = CreateDirectoryWithTempProject( packageId: packageId, @@ -172,7 +169,7 @@ private string CreateDirectoryWithTempProject( Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); } else - tempProject = Path.Combine(FileUtilities.CreateTempSubdirectory(), "restore.csproj"); + tempProject = Path.Combine(PathUtilities.CreateTempSubdirectory(), "restore.csproj"); var tempProjectContent = new XDocument( new XElement("Project", diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index ea8d000e0e20..52c7432fb321 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -5,10 +5,8 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using System.Linq; -using System.Text; using System.Threading.Tasks; using Microsoft.Deployment.DotNet.Releases; using Microsoft.DotNet.Cli; @@ -17,9 +15,7 @@ using Microsoft.DotNet.Configurer; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install; -using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; -using Microsoft.NET.Build.Tasks; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Versioning; using Command = System.CommandLine.Command; diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index a941d249e941..0b4c199f1b3e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -19,7 +18,6 @@ using NuGet.Common; using NuGet.Frameworks; using NuGet.Versioning; -using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.Tools.Tool.Install { @@ -73,7 +71,7 @@ public ToolInstallGlobalOrToolPathCommand( _environmentPathInstruction = environmentPathInstruction ?? EnvironmentPathFactory.CreateEnvironmentPathInstruction(); _createShellShimRepository = createShellShimRepository ?? ShellShimRepositoryFactory.CreateShellShimRepository; - var tempDir = new DirectoryPath(FileUtilities.CreateTempSubdirectory()); + var tempDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); var configOption = parseResult.GetValueForOption(ToolInstallCommandParser.ConfigOption); var sourceOption = parseResult.GetValueForOption(ToolInstallCommandParser.AddSourceOption); var packageSourceLocation = new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), additionalSourceFeeds: sourceOption); diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs index b0bd8ddb3eeb..c4ea1b781620 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs @@ -2,13 +2,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.EnvironmentAbstractions; -using Microsoft.NET.Build.Tasks; using NuGet.Common; namespace Microsoft.DotNet.Workloads.Workload @@ -105,7 +103,7 @@ public WorkloadCommandBase(ParseResult parseResult, ? tempDirPath : !string.IsNullOrWhiteSpace(parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption)) ? parseResult.GetValueForOption(WorkloadInstallCommandParser.TempDirOption) - : FileUtilities.CreateTempSubdirectory(); + : PathUtilities.CreateTempSubdirectory(); TempPackagesDirectory = new DirectoryPath(Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp")); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index c501530abef9..2f8a7e8ae8bc 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -5,20 +5,18 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Configurer; using Microsoft.DotNet.ToolPackage; +using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Common; using NuGet.Versioning; using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; -using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.NET.Build.Tasks; namespace Microsoft.DotNet.Workloads.Workload.Install { @@ -52,7 +50,7 @@ public FileBasedInstaller(IReporter reporter, { _userProfileDir = userProfileDir; _dotnetDir = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); - _tempPackagesDir = new DirectoryPath(tempDirPath ?? FileUtilities.CreateTempSubdirectory()); + _tempPackagesDir = new DirectoryPath(tempDirPath ?? PathUtilities.CreateTempSubdirectory()); ILogger logger = verbosity.VerbosityIsDetailedOrDiagnostic() ? new NuGetConsoleLogger() : new NullLogger(); _restoreActionConfig = restoreActionConfig; _nugetPackageDownloader = nugetPackageDownloader ?? diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 97f1d2fc9044..368d4716b184 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -17,7 +16,6 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; -using Microsoft.NET.Build.Tasks; using Microsoft.NET.Sdk.WorkloadManifestReader; using Microsoft.Win32.Msi; using NuGet.Common; @@ -493,7 +491,7 @@ public PackageId GetManifestPackageId(ManifestId manifestId, SdkFeatureBand feat public async Task ExtractManifestAsync(string nupkgPath, string targetPath) { Log?.LogMessage($"ExtractManifestAsync: Extracting '{nupkgPath}' to '{targetPath}'"); - string extractionPath = FileUtilities.CreateTempSubdirectory(); + string extractionPath = PathUtilities.CreateTempSubdirectory(); try { @@ -953,7 +951,7 @@ public static NetSdkMsiInstallerClient Create( if (nugetPackageDownloader == null) { - DirectoryPath tempPackagesDir = new(string.IsNullOrWhiteSpace(tempDirPath) ? FileUtilities.CreateTempSubdirectory() : tempDirPath); + DirectoryPath tempPackagesDir = new(string.IsNullOrWhiteSpace(tempDirPath) ? PathUtilities.CreateTempSubdirectory() : tempDirPath); nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(), diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index 4c0abf35173d..36c42b47cee4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -6,7 +6,6 @@ using System.IO; using System.Linq; using System.Net.Http; -using System.Runtime.InteropServices; using System.Text.Json; using System.Threading.Tasks; using Microsoft.DotNet.Cli; @@ -17,7 +16,6 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; -using Microsoft.NET.Build.Tasks; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Common; using NuGet.Versioning; @@ -70,7 +68,7 @@ private static WorkloadManifestUpdater GetInstance(string userProfileDir) var sdkVersion = Product.Version; var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, sdkVersion, userProfileDir); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, dotnetPath, sdkVersion, userProfileDir); - var tempPackagesDir = new DirectoryPath(FileUtilities.CreateTempSubdirectory()); + var tempPackagesDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); var nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(), @@ -263,7 +261,7 @@ public async Task> GetManifestPackageDownloadsAsyn var newPackageId = _workloadManifestInstaller.GetManifestPackageId(new ManifestId(manifest.Id), installedSdkFeatureBand); (success, latestVersion) = await GetPackageVersion(newPackageId, packageSourceLocation: _packageSourceLocation, includePreview: includePreviews); - + if (success) { downloads.Add(new WorkloadDownload(manifest.Id, newPackageId.ToString(), latestVersion.ToString())); @@ -558,9 +556,9 @@ private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId m } } - -private string GetAdvertisingManifestPath(SdkFeatureBand featureBand, ManifestId manifestId) => - Path.Combine(_userProfileDir, "sdk-advertising", featureBand.ToString(), manifestId.ToString()); + + private string GetAdvertisingManifestPath(SdkFeatureBand featureBand, ManifestId manifestId) => + Path.Combine(_userProfileDir, "sdk-advertising", featureBand.ToString(), manifestId.ToString()); } } diff --git a/src/Cli/dotnet/dotnet.csproj b/src/Cli/dotnet/dotnet.csproj index bb202db43721..53d06c8b46b2 100644 --- a/src/Cli/dotnet/dotnet.csproj +++ b/src/Cli/dotnet/dotnet.csproj @@ -94,8 +94,7 @@ - + diff --git a/src/Common/PathUtilities.cs b/src/Common/PathUtilities.cs new file mode 100644 index 000000000000..fdd9d7120ff6 --- /dev/null +++ b/src/Common/PathUtilities.cs @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#nullable disable + +using System.IO; +using System.Runtime.InteropServices; + +namespace Microsoft.DotNet; + +static class PathUtilities +{ + const int S_IRUSR = 256; + const int S_IWUSR = 128; + const int S_IXUSR = 64; + const int S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR; // 700 (octal) Permissions + + [DllImport("libc", SetLastError = true)] + private static extern int mkdir(string pathname, int mode); + public static string CreateTempSubdirectory() + { + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + mkdir(path, S_IRWXU); + } + else + { + Directory.CreateDirectory(path); + } + return path; + } +} diff --git a/src/Tasks/Common/FileUtilities.cs b/src/Tasks/Common/FileUtilities.cs index 2f3c01d53b1d..bc9edfa59669 100644 --- a/src/Tasks/Common/FileUtilities.cs +++ b/src/Tasks/Common/FileUtilities.cs @@ -7,17 +7,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Runtime.InteropServices; namespace Microsoft.NET.Build.Tasks { static partial class FileUtilities { - static int S_IRUSR = 256; - static int S_IWUSR = 128; - static int S_IXUSR = 64; - static int S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR; // 700 (octal) Permissions - public static Version GetFileVersion(string sourcePath) { if (sourcePath != null) @@ -40,21 +34,5 @@ public static Version TryGetAssemblyVersion(string sourcePath) return s_assemblyExtensions.Contains(extension) ? GetAssemblyVersion(sourcePath) : null; } - - [DllImport("libc", SetLastError = true)] - private static extern int mkdir(string pathname, int mode); - public static string CreateTempSubdirectory() - { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - mkdir(path, S_IRWXU); - } - else - { - Directory.CreateDirectory(path); - } - return path; - } } } From 9410d2d5ccf5d277ed7c4075a4935527be2702c6 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 6 Sep 2022 13:17:09 -0700 Subject: [PATCH 74/79] Apply Eric's requested changes, except checking the ret val on mkdir. --- src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs | 2 +- .../Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs | 2 +- src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs | 2 +- src/Cli/dotnet/ShellShim/ShellShimRepository.cs | 2 +- .../GivenAFirstTimeUseNoticeSentinel.cs | 2 +- .../GivenAFunctionReturnStringAndFakeFileSystem.cs | 2 +- .../Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs index 792d8623c49a..454534779a5d 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/MsBuildFileSetFactory.cs @@ -63,7 +63,7 @@ internal MsBuildFileSetFactory( public async Task CreateAsync(CancellationToken cancellationToken) { - var watchList = Path.Combine(PathUtilities.CreateTempSubdirectory(), Path.GetRandomFileName()); + var watchList = Path.GetTempFileName(); try { var projectDir = Path.GetDirectoryName(_projectFile); diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs index 81b16d48858e..b063b9fc4a08 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs @@ -19,7 +19,7 @@ public ITemporaryDirectory CreateTemporaryDirectory() return new TemporaryDirectory(); } - public string CreateTempPath() + public string CreateTemporarySubdirectory() { return CreateTemporaryDirectory().DirectoryPath; } diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs b/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs index 3dde961ebbe0..0a2e4e31e09f 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs @@ -27,6 +27,6 @@ internal interface IDirectory /// Returns a new directory created under the temp folder. Can be on the mock under test or the real temp file folder. - string CreateTempPath(); + string CreateTemporarySubdirectory(); } } diff --git a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs index c46e44cf9de2..68390f1f2ce2 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimRepository.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimRepository.cs @@ -104,7 +104,7 @@ public void RemoveShim(ToolCommandName commandName) { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { - var tempPath = Path.Combine(_fileSystem.Directory.CreateTempPath(), Path.GetRandomFileName()); + var tempPath = Path.Combine(_fileSystem.Directory.CreateTemporarySubdirectory(), Path.GetRandomFileName()); FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); files[file.Value] = tempPath; } diff --git a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs index 4bc243afc46e..31cbcfe77881 100644 --- a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs +++ b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFirstTimeUseNoticeSentinel.cs @@ -174,7 +174,7 @@ public ITemporaryDirectory CreateTemporaryDirectory() throw new NotImplementedException(); } - public string CreateTempPath() + public string CreateTemporarySubdirectory() { throw new NotImplementedException(); } diff --git a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs index f2248dbf1253..6802977214b2 100644 --- a/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs +++ b/src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenAFunctionReturnStringAndFakeFileSystem.cs @@ -173,7 +173,7 @@ public IEnumerable EnumerateFileSystemEntries(string path) throw new UnauthorizedAccessException(); } - public string CreateTempPath() + public string CreateTemporarySubdirectory() { throw new NotImplementedException(); } diff --git a/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs b/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs index 5531cf6a76f2..0c47207c56f5 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Mock/FileSystemMockBuilder.cs @@ -579,7 +579,7 @@ public void CreateDirectory(string path) _files.CreateDirectory(path); } - public string CreateTempPath() + public string CreateTemporarySubdirectory() { return CreateTemporaryDirectory().DirectoryPath; } From 798774257f409fec02a2f42bd0bf252bbdc844f5 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 6 Sep 2022 16:27:03 -0700 Subject: [PATCH 75/79] Add dotnet common localizable strings --- .../dotnet-watch/dotnet-watch.csproj | 1 + ...crosoft.DotNet.InternalAbstractions.csproj | 1 + src/Common/DotnetCommonLocalizableStrings.cs | 20 ++++++ .../DotnetCommonLocalizableStrings.resx | 63 +++++++++++++++++++ src/Common/PathUtilities.cs | 28 ++++++++- 5 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 src/Common/DotnetCommonLocalizableStrings.cs create mode 100644 src/Common/DotnetCommonLocalizableStrings.resx diff --git a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj index 065f750f7200..bc8d4d4c237b 100644 --- a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj +++ b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj @@ -24,6 +24,7 @@ + diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj index 6260c984866d..f41a0cfee156 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj @@ -14,5 +14,6 @@ + diff --git a/src/Common/DotnetCommonLocalizableStrings.cs b/src/Common/DotnetCommonLocalizableStrings.cs new file mode 100644 index 000000000000..e393030c6522 --- /dev/null +++ b/src/Common/DotnetCommonLocalizableStrings.cs @@ -0,0 +1,20 @@ +// +using System.Reflection; + + +namespace Microsoft.DotNet +{ + internal static partial class DotnetCommonLocalizableStrings + { + private static global::System.Resources.ResourceManager s_resourceManager; + internal static global::System.Resources.ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new global::System.Resources.ResourceManager(typeof(DotnetCommonLocalizableStrings))); + internal static global::System.Globalization.CultureInfo Culture { get; set; } +#if !NET20 + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] +#endif + internal static string GetResourceString(string resourceKey, string defaultValue = null) => ResourceManager.GetString(resourceKey, Culture); + /// MSBuild server + internal static string @PathUtilitiesMkdirFailure => GetResourceString("PathUtilitiesMkdirFailure"); + + } +} diff --git a/src/Common/DotnetCommonLocalizableStrings.resx b/src/Common/DotnetCommonLocalizableStrings.resx new file mode 100644 index 000000000000..e24e18f0f14e --- /dev/null +++ b/src/Common/DotnetCommonLocalizableStrings.resx @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Failed to create a temporary sub-directory '{0}' with mkdir, error code: '{1}'. + \ No newline at end of file diff --git a/src/Common/PathUtilities.cs b/src/Common/PathUtilities.cs index fdd9d7120ff6..deda76886365 100644 --- a/src/Common/PathUtilities.cs +++ b/src/Common/PathUtilities.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using System.IO; using System.Runtime.InteropServices; @@ -15,14 +16,35 @@ static class PathUtilities const int S_IXUSR = 64; const int S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR; // 700 (octal) Permissions + const int MAX_NUM_DIRECTORY_CREATE_RETRIES = 2; + + public static string CreateTempSubdirectory() + { + return CreateTempSubdirectoryRetry(0); + } + [DllImport("libc", SetLastError = true)] private static extern int mkdir(string pathname, int mode); - public static string CreateTempSubdirectory() + private static string CreateTempSubdirectoryRetry(int attemptNo) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + int s = 2; + if (1 <= s) + throw new IOException(String.Format(DotnetCommonLocalizableStrings.PathUtilitiesMkdirFailure)); + + string path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - mkdir(path, S_IRWXU); + int mkdirStatusCode = mkdir(path, S_IRWXU); + if (mkdirStatusCode != 0) + { + int errno = Marshal.GetLastWin32Error(); + if (Directory.Exists(path) && attemptNo < MAX_NUM_DIRECTORY_CREATE_RETRIES) + { + return CreateTempSubdirectoryRetry(attemptNo + 1); + } + else + throw new IOException(String.Format(DotnetCommonLocalizableStrings.PathUtilitiesMkdirFailure, path, errno)); + } } else { From e57638891bc2337b40766dd5098b9aea14f8eb32 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 6 Sep 2022 16:34:50 -0700 Subject: [PATCH 76/79] Remove new localizablestrings because its a pain. Retry once on mkdir failure --- .../dotnet-watch/dotnet-watch.csproj | 1 - ...crosoft.DotNet.InternalAbstractions.csproj | 1 - src/Common/DotnetCommonLocalizableStrings.cs | 20 ------------------- src/Common/PathUtilities.cs | 6 +----- 4 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 src/Common/DotnetCommonLocalizableStrings.cs diff --git a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj index bc8d4d4c237b..065f750f7200 100644 --- a/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj +++ b/src/BuiltInTools/dotnet-watch/dotnet-watch.csproj @@ -24,7 +24,6 @@ - diff --git a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj index f41a0cfee156..6260c984866d 100644 --- a/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj +++ b/src/Cli/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj @@ -14,6 +14,5 @@ - diff --git a/src/Common/DotnetCommonLocalizableStrings.cs b/src/Common/DotnetCommonLocalizableStrings.cs deleted file mode 100644 index e393030c6522..000000000000 --- a/src/Common/DotnetCommonLocalizableStrings.cs +++ /dev/null @@ -1,20 +0,0 @@ -// -using System.Reflection; - - -namespace Microsoft.DotNet -{ - internal static partial class DotnetCommonLocalizableStrings - { - private static global::System.Resources.ResourceManager s_resourceManager; - internal static global::System.Resources.ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new global::System.Resources.ResourceManager(typeof(DotnetCommonLocalizableStrings))); - internal static global::System.Globalization.CultureInfo Culture { get; set; } -#if !NET20 - [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] -#endif - internal static string GetResourceString(string resourceKey, string defaultValue = null) => ResourceManager.GetString(resourceKey, Culture); - /// MSBuild server - internal static string @PathUtilitiesMkdirFailure => GetResourceString("PathUtilitiesMkdirFailure"); - - } -} diff --git a/src/Common/PathUtilities.cs b/src/Common/PathUtilities.cs index deda76886365..3dd303a6c4ec 100644 --- a/src/Common/PathUtilities.cs +++ b/src/Common/PathUtilities.cs @@ -27,10 +27,6 @@ public static string CreateTempSubdirectory() private static extern int mkdir(string pathname, int mode); private static string CreateTempSubdirectoryRetry(int attemptNo) { - int s = 2; - if (1 <= s) - throw new IOException(String.Format(DotnetCommonLocalizableStrings.PathUtilitiesMkdirFailure)); - string path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -43,7 +39,7 @@ private static string CreateTempSubdirectoryRetry(int attemptNo) return CreateTempSubdirectoryRetry(attemptNo + 1); } else - throw new IOException(String.Format(DotnetCommonLocalizableStrings.PathUtilitiesMkdirFailure, path, errno)); + throw new IOException($"Failed to create a temporary subdirectory {path} with mkdir, error code: {errno}"); } } else From e5a403484c7e6779129b144bab97fe52bf507688 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 12 Sep 2022 15:39:38 -0700 Subject: [PATCH 77/79] Remove dotnet localize strs --- .../DotnetCommonLocalizableStrings.resx | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 src/Common/DotnetCommonLocalizableStrings.resx diff --git a/src/Common/DotnetCommonLocalizableStrings.resx b/src/Common/DotnetCommonLocalizableStrings.resx deleted file mode 100644 index e24e18f0f14e..000000000000 --- a/src/Common/DotnetCommonLocalizableStrings.resx +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Failed to create a temporary sub-directory '{0}' with mkdir, error code: '{1}'. - \ No newline at end of file From c61f7af24c3ddc4b01e2ce85d69620635a6d26f7 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 12 Sep 2022 16:25:19 -0700 Subject: [PATCH 78/79] remove nullable directive as its suddenly mad about that --- src/Common/PathUtilities.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Common/PathUtilities.cs b/src/Common/PathUtilities.cs index 3dd303a6c4ec..dad9351b1ede 100644 --- a/src/Common/PathUtilities.cs +++ b/src/Common/PathUtilities.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -#nullable disable - using System; using System.IO; using System.Runtime.InteropServices; From 8da5a645d40558128017049423c09b7f47d96200 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 12 Sep 2022 16:35:51 -0700 Subject: [PATCH 79/79] Merge manually, azdo did not merge with correct branch --- .../dotnet-workload/install/FileBasedInstaller.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 2f8a7e8ae8bc..245c526076f6 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -5,18 +5,20 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.Json; -using System.Threading.Tasks; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Configurer; using Microsoft.DotNet.ToolPackage; -using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Common; using NuGet.Versioning; using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; +using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; +using System.Text.Json; +using System.Threading.Tasks; + namespace Microsoft.DotNet.Workloads.Workload.Install { @@ -51,7 +53,7 @@ public FileBasedInstaller(IReporter reporter, _userProfileDir = userProfileDir; _dotnetDir = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); _tempPackagesDir = new DirectoryPath(tempDirPath ?? PathUtilities.CreateTempSubdirectory()); - ILogger logger = verbosity.VerbosityIsDetailedOrDiagnostic() ? new NuGetConsoleLogger() : new NullLogger(); + ILogger logger = verbosity.IsDetailedOrDiagnostic() ? new NuGetConsoleLogger() : new NullLogger(); _restoreActionConfig = restoreActionConfig; _nugetPackageDownloader = nugetPackageDownloader ?? new NuGetPackageDownloader(_tempPackagesDir, filePermissionSetter: null,