From 111b089775820886b01607f4c7d0f6a2e7b81226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Fri, 20 Oct 2023 11:28:14 +0200 Subject: [PATCH] Don't use File.OpenWrite when trying to overwrite a file (#93744) File.OpenWrite will open an existing file which means if you write data that is shorter than the existing data the file will be corrupt. This is documented on https://learn.microsoft.com/en-us/dotnet/api/system.io.file.openwrite > The OpenWrite method opens a file if one already exists for the file path, or creates a new file if one does not exist. For an existing file, it does not append the new text to the existing text. Instead, it overwrites the existing characters with the new characters. If you overwrite a longer string (such as "This is a test of the OpenWrite method") with a shorter string (such as "Second run"), the file will contain a mix of the strings ("Second runtest of the OpenWrite method"). The fix is to use the `FileMode.Create` option in cases where the intention is to create a new file or overwrite an existing one. I noticed this recently when using the illink feature to dump a dependency analysis xml, the next time I ran the build after making a change that'd reduce dependencies the xml would get corrupted since it wrote less data than the existing file had. There were a couple instances across the codebase, this fixes them. --- .../Compiler/ILAssemblyGeneratingMethodDebugInfoProvider.cs | 2 +- .../MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs | 2 +- src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs | 2 +- src/tasks/WasmBuildTasks/GetChromeVersions.cs | 2 +- src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs | 2 +- src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILAssemblyGeneratingMethodDebugInfoProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILAssemblyGeneratingMethodDebugInfoProvider.cs index 99fdafcd936b8..9261a98a8ae38 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILAssemblyGeneratingMethodDebugInfoProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILAssemblyGeneratingMethodDebugInfoProvider.cs @@ -28,7 +28,7 @@ public ILAssemblyGeneratingMethodDebugInfoProvider(string fileName, DebugInforma { _wrappedProvider = wrappedProvider; _fileName = fileName; - _tw = new StreamWriter(File.OpenWrite(fileName)); + _tw = new StreamWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)); } public override MethodDebugInformation GetDebugInfo(MethodIL methodIL) diff --git a/src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs b/src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs index 3430fb09f72b2..8a047ecc6205c 100644 --- a/src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs +++ b/src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs @@ -71,7 +71,7 @@ public override bool Execute() ConvertDictionaryToBlob(configProperties, blobBuilder); Directory.CreateDirectory(Path.GetDirectoryName(OutputFile!)!); - using var stream = File.OpenWrite(OutputFile); + using var stream = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None); blobBuilder.WriteContentTo(stream); return !Log.HasLoggedErrors; diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs index b5a6539e2cb87..c533e404c4173 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs @@ -152,7 +152,7 @@ protected virtual void UpdateRuntimeConfigJson() AddToRuntimeConfig(wasmHostProperties: wasmHostProperties, runtimeArgsArray: runtimeArgsArray, perHostConfigs: perHostConfigs); string dstPath = Path.Combine(AppDir!, Path.GetFileName(runtimeConfigPath)); - using FileStream? fs = File.OpenWrite(dstPath); + using FileStream? fs = new FileStream(dstPath, FileMode.Create, FileAccess.Write, FileShare.None); using var writer = new Utf8JsonWriter(fs, new JsonWriterOptions { Indented = true }); rootObject.WriteTo(writer); _fileWrites.Add(dstPath); diff --git a/src/tasks/WasmBuildTasks/GetChromeVersions.cs b/src/tasks/WasmBuildTasks/GetChromeVersions.cs index 3f29c0d99a8e1..4d0e1632348f0 100644 --- a/src/tasks/WasmBuildTasks/GetChromeVersions.cs +++ b/src/tasks/WasmBuildTasks/GetChromeVersions.cs @@ -292,7 +292,7 @@ private async Task GetDownloadFileStreamAsync(string filename, string ur { Log.LogMessage(MessageImportance.Low, $"Downloading {url} ..."); using Stream stream = await s_httpClient.GetStreamAsync(url).ConfigureAwait(false); - using FileStream fs = File.OpenWrite(filePath); + using FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None); await stream.CopyToAsync(fs).ConfigureAwait(false); } catch (HttpRequestException hre) diff --git a/src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs b/src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs index eed05fc710848..0e862b62b73cd 100644 --- a/src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs +++ b/src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs @@ -38,7 +38,7 @@ public DgmlDependencyRecorder (LinkContext context, string? fileName = null) Directory.CreateDirectory (context.OutputDirectory); } - var depsFile = File.OpenWrite (fileName); + var depsFile = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None); stream = depsFile; writer = XmlWriter.Create (stream, settings); diff --git a/src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs b/src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs index 6c386ac367c9b..189e6fa274efa 100644 --- a/src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs +++ b/src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs @@ -61,7 +61,7 @@ public XmlDependencyRecorder (LinkContext context, string? fileName = null) Directory.CreateDirectory (context.OutputDirectory); } - var depsFile = File.OpenWrite (fileName); + var depsFile = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None); stream = depsFile; writer = XmlWriter.Create (stream, settings);