Text property XML: writer emits properties and values its own reader rejects (record fails to load)
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 25/100
Línea de trabajo
Read TsPropsSerializer and TsStringSerializer in SIL.LCModel.Core, then inspect their readers and the existing writer and reader tests. Start by checking how each FwTextPropType is serialized and accepted, including malformed values. Add data driven round trip coverage for both serializers and a guard that classifies every property; done means released writer output remains readable, writer output round trips where supported, and malformed values do not throw.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
The text property XML writer and readers in SIL.LCModel.Core disagree. TsPropsSerializer (StyleRules) and TsStringSerializer (string runs) write some properties and values that their own readers reject with XmlSchemaException. They also write some properties that are dropped when read back.
Impact
When the reader rejects a record, CmObjectSurrogate reports a "corrupted record" and FieldWorks closes. The project then can't be opened until the data is fixed by hand. Properties that are dropped lose data silently on every save and load. For example, a custom bullet character (LT-16341) is never written, so it is lost on save.
Repro
Build an ITsTextProps (or a one-run ITsString) holding the property, serialize it with TsPropsSerializer.SerializePropsToXml (or TsStringSerializer.SerializeTsStringToXml), then deserialize the result.
var bldr = TsStringUtils.MakePropsBldr();
bldr.SetIntPropValues((int)FwTextPropType.ktptMarginTop, (int)FwTextPropVar.ktpvMilliPoint, 1500);
string xml = TsPropsSerializer.SerializePropsToXml(bldr.GetTextProps(), wsf); // <Prop MarginTop="1500">
TsPropsSerializer.DeserializePropsFromXml(xml, wsf); // XmlSchemaException: Unknown Prop attribute: MarginTop
Observed (current master, both serializers unless noted)
| Property (number) | Written as | On read |
|---|---|---|
| ktptMarginTop (50) | MarginTop |
throws; the reader only knows marginTop |
| ktptDirectionDepth (129), ktptHyphenate (150), ktptMaxLines (151), ktptCellBorderWidth (152), ktptCellSpacing (153), ktptCellPadding (154), ktptSetRowDefaults (159), ktptRelLineHeight (160) | own name | throws: unknown attribute |
| ktptEditable (155) | editable |
throws in StyleRules; ignored on a run |
| ktptTabDef (23, int), ktptTabList (4), ktptCharStyle (2), ktptParaStyle (3) | own name | ignored (Debug.Fail in a Debug build) |
| ktptCustomBullet (7, string) | nothing | the custom bullet is lost on save (the reader accepts bulCusTxt, but the writer has no case) |
| ktptTableRule (161) | nothing | dropped on save |
| negative values: font size 6, offset 7 on a run (raised or lowered text), 19, 20, 128, 134-141, 143, 144, 148, 149, 162 | -n |
throws: negative number not valid |
| values outside the enumeration: 2, 3, 4, 5, 17, 26 | the number | throws: invalid value |
| a variation other than mpt/rel on 6, 7, 24 | fontsizeUnit="3" etc. |
throws: invalid unit |
| ktptLineHeight (24) = int.MinValue | the writer throws OverflowException (Math.Abs) |
|
| ktptBulNumFontInfo (147) with a font name and font features (what BulletInfo encodes) | the writer throws: NUL character in the attribute | |
| ktptBulNumFontInfo (147) holding another int property | prop_N |
throws: unknown attribute |
| ktptBulNumFontInfo (147) / ktptWsStyle (156), truncated | the writer throws IndexOutOfRangeException |
|
| ktptObjData (6) with a GUID type but too short to hold a GUID | the writer throws | |
| string values holding characters XML can't represent | the writer throws ArgumentException |
|
| ktptTags (5) shorter than one GUID | tags="" |
loads as an empty tags property |
There is no round-trip test, so nothing catches a mismatch. MarginTop is covered only by separate writer and reader tests, each pinning the other's spelling.
Proposed fix
- The reader accepts everything a released writer has emitted. That covers
MarginTop, the eight missing attribute names, negative numbers, numbers for enumerations and variations, andprop_NinsideBulNumFontInfo. Existing files that now fail to load will open again. - The writer emits only what older readers already accept. It writes
marginTop. It writesbulCusTxtfor the custom bullet. It no longer writes tabDef, tabList, charStyle, paraStyle or editable: no reader has ever kept them, and nothing in liblcm or FieldWorks sets the first four. It still doesn't write ktptTableRule, because a new attribute name would make older readers reject the record. - The writer never throws on a value it holds. It leaves out a malformed binary value or a partial GUID. It strips characters XML can't represent, the same way it already does for run text. It decodes BulNumFontInfo string properties correctly.
- Add a data-driven test that round-trips every
FwTextPropTypeconstant through both serializers. A guard test fails when a new constant has no classification.
- Lenguaje dominante
- C#
- Estrellas
- 3
- Forks
- 15
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de sillsdev/liblcm
-
Dificultad 4/5 3-5 días Aptitud para principiantes 54/100
-
Saving run text that contains a lone (unpaired) surrogate throws in TsString normalizationPosiblemente ocupada @johnml1135 la tomó hace 1 día. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 30/100
-
Text props: an unknown writing-system handle is saved as ws="", which no reader can loadPosiblemente ocupada @johnml1135 la tomó hace 1 día. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 25/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 68/100
-
DeepWiki-found bugsAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 38/100
Todos los issues de sillsdev/liblcm
Issues similares
-
needs-triage
Dificultad 1/5 1-3 horas Aptitud para principiantes 76/100
Azure/azure-sdk-for-net#64658 · 1 comentario · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
dotnet/aspnetcore#70370 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
NethermindEth/nethermind#15684 ·
Los mantenedores suelen responder en 1 día
-
area/ai-assistant squad/flyt
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
Altinn/altinn-studio#21798 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
SubtitleEdit/subtitleedit#16699 ·
Los mantenedores suelen responder en 1 día