From 1a61004ef050681addeae2ecb994291e7e3e371a Mon Sep 17 00:00:00 2001 From: Danny Rorabaugh Date: Mon, 8 Jun 2026 13:26:01 -0400 Subject: [PATCH 1/3] Fix file stream resource leak in CreateOrUpdateDefaultXliffFileIfNecessary (#151) Co-Authored-By: Claude Sonnet 4.6 --- src/L10NSharp.Tests/LocalizationManagerTestsBase.cs | 3 +-- src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs b/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs index 5189f53..181392e 100644 --- a/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs +++ b/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs @@ -85,8 +85,7 @@ public void CreateOrUpdateDefaultTranslationFileIfNecessary_CopiesOverEmptyGener // generate an empty English Translation file Directory.CreateDirectory(GetGeneratedDirectory(folder)); - var fileStream = File.Open(generatedFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); - fileStream.Close(); + using (File.Open(generatedFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { } // SUT (buried down in there somewhere) SetupManager(folder); diff --git a/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs b/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs index fcd284c..de924a3 100644 --- a/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs +++ b/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs @@ -190,8 +190,7 @@ private void CreateOrUpdateDefaultXliffFileIfNecessary( } // Before wasting a bunch of time, make sure we can open the file for writing. - var fileStream = File.Open(DefaultStringFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); - fileStream.Close(); + using (File.Open(DefaultStringFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { } var stringCache = new XliffLocalizedStringCache(this, false); From d09c2e1d37c783206292ac7e2a6f12303d01e31b Mon Sep 17 00:00:00 2001 From: Danny Rorabaugh Date: Mon, 8 Jun 2026 13:31:08 -0400 Subject: [PATCH 2/3] Add changelog for file handle leak fix in CreateOrUpdateDefaultXliffFileIfNecessary (#151) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 895773a..5cfa2a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [L10NSharp.Windows.Forms] Restored project-local Resources support for `FallbackLanguagesDlgBase` button images (`Move`, `Move_up`, and `Move_down`). - [L10NSharp.Windows.Forms] Corrected resource manager base name to `L10NSharp.Windows.Forms.Properties.Resources`. - [L10NSharp.Windows.Forms.Tests] Corrected resource manager base name to `L10NSharp.Windows.Forms.Tests.Properties.Resources`. +- [L10NSharp] Fixed file handle leak in `XliffLocalizationManager.CreateOrUpdateDefaultXliffFileIfNecessary` when an exception was thrown between `File.Open` and `Close`. (#151) ### Removed From 34fd01578aeeb48b80ef97a0e0f78328d708f2ba Mon Sep 17 00:00:00 2001 From: Danny Rorabaugh Date: Tue, 16 Jun 2026 14:19:00 -0400 Subject: [PATCH 3/3] Use more succinct idiom --- src/L10NSharp.Tests/LocalizationManagerTestsBase.cs | 10 +++++----- src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs b/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs index 181392e..39d913a 100644 --- a/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs +++ b/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs @@ -85,7 +85,7 @@ public void CreateOrUpdateDefaultTranslationFileIfNecessary_CopiesOverEmptyGener // generate an empty English Translation file Directory.CreateDirectory(GetGeneratedDirectory(folder)); - using (File.Open(generatedFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { } + File.Open(generatedFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None).Dispose(); // SUT (buried down in there somewhere) SetupManager(folder); @@ -215,19 +215,19 @@ public void CreateOrUpdateDefaultTranslationFileIfNecessary_Missing_IncludesStri Assert.AreEqual("My Own English String", ProxyLocalizationManager.MyOwnGetString("myOwn.English.String.Id", "My Own English String")); - + Assert.AreEqual("My Own English String (with comment)", ProxyLocalizationManager.MyOwnGetString("myOwn.English.String.Id.With.Comment", "My Own English String (with comment)", "This is used to test the case where MyOwnGetString is passed as an extra method to use for extraction.")); - + Assert.AreEqual("Click me", ProxyLocalizationManager.MyOwnGetString("myDlg.btnClickMe.Text", "Click me", "This is the text from the third version of MyOwnGetString.", "Click this thingy to do stuff.", "Ctrl-T", btnClickMe)); - + Assert.AreEqual("String to Localize", "String to Localize".Localize()); - + Assert.AreEqual("Another String to Localize", "Another String to Localize".Localize("With.Id.And.Comment", "This is used to test the case where Localize is passed as an extra method to use for extraction.")); } diff --git a/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs b/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs index de924a3..110e0d4 100644 --- a/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs +++ b/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs @@ -190,7 +190,7 @@ private void CreateOrUpdateDefaultXliffFileIfNecessary( } // Before wasting a bunch of time, make sure we can open the file for writing. - using (File.Open(DefaultStringFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { } + File.Open(DefaultStringFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None).Dispose(); var stringCache = new XliffLocalizedStringCache(this, false); @@ -538,7 +538,7 @@ public virtual void HandleUiLanguageChange() { UiLanguageChanged?.Invoke(this, EventArgs.Empty); } - + /// ------------------------------------------------------------------------------------ public override string ToString() {