diff --git a/CHANGELOG.md b/CHANGELOG.md index 895773a..22b8916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [L10NSharp] Removed emailForSubmissions parameter from LocalizationManager.Create. Since the localization dialog was jettisoned, it no longer makes sense to store this information on the localization manager. - [L10NSharp.Windows.Forms] Removed emailForSubmissions parameter (8th parameter) from LocalizationManagerWinforms.Create. Since the localization dialog was jettisoned, it no longer makes sense to store this information on the localization manager. - [L10NSharp] Replaced the .NET 8.0 target with .NET Standard 2.0 for broader compatibility. +- [L10NSharp] BREAKING CHANGE: `LocalizationManager.GetString`, `GetDynamicString`, and `GetDynamicStringOrEnglish` now throw `ArgumentException` when called with a null or empty string ID. Previously, empty IDs were silently accepted and could produce a malformed XLIFF file that crashed on next launch. (#104) ### Fixed diff --git a/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs b/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs index 5189f53..9949eff 100644 --- a/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs +++ b/src/L10NSharp.Tests/LocalizationManagerTestsBase.cs @@ -292,6 +292,20 @@ public void GetDynamicStringInEnglish_NoDefault_FindsEnglish() } } + [Test] + public void GetDynamicString_WithEmptyId_ThrowsArgumentException() + { + Assert.Throws(() => + LocalizationManager.GetDynamicString(AppId, "", "some text")); + } + + [Test] + public void GetDynamicStringOrEnglish_WithEmptyId_ThrowsArgumentException() + { + Assert.Throws(() => + LocalizationManagerInternal.GetDynamicStringOrEnglish(AppId, "", "some text", null, "en")); + } + [Test] public void GetDynamicStringOrEnglish_LmDisposed_GivesUsefulException() { diff --git a/src/L10NSharp/LocalizationManagerInternal.cs b/src/L10NSharp/LocalizationManagerInternal.cs index e8ecef8..e3996ed 100644 --- a/src/L10NSharp/LocalizationManagerInternal.cs +++ b/src/L10NSharp/LocalizationManagerInternal.cs @@ -464,6 +464,8 @@ public static string GetDynamicString(string appId, string id, string englishTex /// ------------------------------------------------------------------------------------ public static string GetDynamicString(string appId, string id, string englishText, string comment) { + if (string.IsNullOrWhiteSpace(id)) + throw new ArgumentException("id may not be null or empty.", nameof(id)); return GetDynamicStringOrEnglish(appId, id, englishText, comment, LocalizationManager.UILanguageId); } @@ -482,6 +484,8 @@ public static string GetDynamicString(string appId, string id, string englishTex public static string GetDynamicStringOrEnglish(string appId, string id, string englishText, string comment, string langId) { + if (string.IsNullOrWhiteSpace(id)) + throw new ArgumentException("id may not be null or empty.", nameof(id)); // This happens in unit test environments or apps that have imported a library that // is localized, but the app itself isn't initializing L10N yet. if (LoadedManagers.Count == 0) diff --git a/src/L10NSharp/XLiffUtils/XliffTransUnitUpdater.cs b/src/L10NSharp/XLiffUtils/XliffTransUnitUpdater.cs index 6d9cd27..c8a028c 100644 --- a/src/L10NSharp/XLiffUtils/XliffTransUnitUpdater.cs +++ b/src/L10NSharp/XLiffUtils/XliffTransUnitUpdater.cs @@ -46,6 +46,8 @@ internal bool Update(LocalizingInfo locInfo) // Can't do anything without a language id. if (string.IsNullOrEmpty(locInfo.LangId)) return _updated; + if (string.IsNullOrEmpty(locInfo.Id)) + return _updated; var xliffSource = _stringCache.GetDocument(_defaultLang); Debug.Assert(xliffSource != null);