From 44dc14fbae4cbb319f10bb974ff55818179f4c6a Mon Sep 17 00:00:00 2001 From: John Lambert Date: Mon, 12 Oct 2026 14:56:30 -0400 Subject: [PATCH 1/2] Test that a multi-unicode alternative in an unknown writing system is kept Loading an AUni alternative whose writing system the cache has not seen yet currently drops the alternative, because the lookup returns 0 for unknown writing systems. AStr runs create the writing system on demand, so the result depends on activation order. This test fails until AUni does the same. Co-Authored-By: Claude Sonnet 5.5 --- .../DomainImpl/StringsTests.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/SIL.LCModel.Tests/DomainImpl/StringsTests.cs b/tests/SIL.LCModel.Tests/DomainImpl/StringsTests.cs index ee6360b8..9e700aae 100644 --- a/tests/SIL.LCModel.Tests/DomainImpl/StringsTests.cs +++ b/tests/SIL.LCModel.Tests/DomainImpl/StringsTests.cs @@ -286,6 +286,27 @@ public void AppendAlternativesTest() Assert.AreEqual("Saltillo Mejico", Cache.LangProject.FieldWorkLocation.get_String(spanish.Handle).Text); } + /// + /// LT-22834: an AUni alternative in a writing system the cache has not seen yet must be + /// kept (created on demand, as AStr runs are), not dropped. + /// + [Test] + public void ReadMultiUnicodeAlternative_UnknownWritingSystem_IsKept() + { + const string wsId = "qaa-x-lt22834"; + var wsManager = Cache.ServiceLocator.WritingSystemManager; + Assert.AreEqual(0, wsManager.GetWsFromStr(wsId), "precondition: ws must be unknown"); + var node = System.Xml.Linq.XElement.Parse("kept"); + + ITsString tss; + var ws = MultiUnicodeAccessor.ReadMultiUnicodeAlternative(node, Cache.WritingSystemFactory, out tss); + + Assert.AreNotEqual(0, ws, "alternative in an unknown writing system was dropped"); + Assert.AreEqual(ws, wsManager.GetWsFromStr(wsId)); + Assert.AreEqual("kept", tss.Text); + Assert.AreEqual(ws, tss.get_WritingSystemAt(0)); + } + [Test] public void ToXml_WorksAsExpected() { From da61ef0051ab942102ea8e73d5fe0b3d62e90bb4 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Mon, 12 Oct 2026 14:58:03 -0400 Subject: [PATCH 2/2] Fix LT-22834: keep multi-string alternatives in writing systems not yet known to the cache MultiUnicodeAccessor looked AUni alternatives up with GetWsFromStr, which returns 0 for a writing system the cache has not seen, so the alternative was silently dropped. AStr runs create the writing system on demand, so the outcome depended on activation order. AUni alternatives now resolve the writing system the same way runs do. No schema or file-format change. Co-Authored-By: Claude Sonnet 5.5 --- CHANGELOG.md | 1 + src/SIL.LCModel/DomainImpl/Strings.cs | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a172e5d..c5f928e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- [SIL.LCModel] Multi-string (AUni) alternatives in writing systems the cache has not seen yet are no longer dropped on load; the writing system is created on demand, as for string runs, so the result no longer depends on activation order (LT-22834) - [SIL.LCModel] BaseStyleInfo now loads default font features (ktptFontVariations) from style rules, fixing font features set as style defaults being dropped on reload (LT-22351) - [SIL.LCModel] BaseStyleInfo no longer clobbers ws-specific font overrides inherited from a based-on style with the default font info's merely-inherited values; only explicitly-set default properties are propagated to ws overrides (LT-22351) - [SIL.LCModel] BulletInfo now decodes all properties of an encoded bullet font info instead of stopping at the first string property, fixing bullet font features (ktptFontVariations) being lost when a bullet font name was also set (LT-22351) diff --git a/src/SIL.LCModel/DomainImpl/Strings.cs b/src/SIL.LCModel/DomainImpl/Strings.cs index c554f5e9..c6bde652 100644 --- a/src/SIL.LCModel/DomainImpl/Strings.cs +++ b/src/SIL.LCModel/DomainImpl/Strings.cs @@ -929,10 +929,21 @@ internal static int ReadMultiUnicodeAlternative(XElement aUniNode, ILgWritingSys var wsVal = aUniNode.Attribute("ws"); if (wsVal == null || String.IsNullOrEmpty(wsVal.Value)) return 0; - var wsHvo = wsf.GetWsFromStr(wsVal.Value); + // Like the runs of an AStr (see TsStringSerializer.GetWsForId), create the writing + // system on demand: GetWsFromStr returns 0 for one the cache has not seen yet, which + // dropped the alternative and made the result depend on activation order (LT-22834). + int wsHvo; + try + { + wsHvo = wsf.get_Engine(wsVal.Value).Handle; + } + catch (Exception) + { + // An identifier that cannot be made into a writing system is still dropped. + wsHvo = 0; + } // Throwing out a string without a ws is probably better than crashing // and preventing a db from being opened. - // This code currently accepts this data, only storing en__IPA and fr strings. //
// // problematic