Category: bug
Area: persistence (deprecated XML fallback format)
Found: while writing tests for PersisterXML.ReadEncoding on branch fix/configured-encoding-registry
What happens
PersisterXML.ReadOptions dereferences the options node without a null check:
XmlNodeoptionsNode=startNode.SelectSingleNode("options");varvalue=GetOptionsAttribute(optionsNode,"multifile","enabled");and GetOptionsAttribute calls optionsNode.SelectSingleNode(elementName) straight away. A legacy XML
.lxp whose <file> element has no <options> child therefore throws NullReferenceException. Later in
the same method optionsNode.SelectSingleNode("multifile") is dereferenced again.
Why it escapes
PersisterXML.Load is documented to return null on failure, but its filter only catches
XmlException, UnauthorizedAccessException, IOException and FileNotFoundException — not
NullReferenceException. Its caller Persister.Load invokes it from inside a catch block (the
JSON-to-XML fallback), so the NRE replaces the original exception and propagates. Above that,
PersisterHelpers.FindFilenameForSettings has no handler and is called synchronously from
FileOperationService.AddFileTab, i.e. the file-open path.
Reproduce
Open a .lxp containing:
<?xml version="1.0" encoding="utf-8"?>
<logexpert>
<filefileName="test.log"lineCount="1" />
</logexpert>
Reachability
Low. Current LogExpert saves persistence as JSON; this is the deprecated read-only fallback. A real file
hits it only if hand-edited, truncated, or written by a very old version that omitted the section. It is a
robustness bug rather than a reported one — a corrupt .lxp should degrade to "no persistence data", not
throw.
Suggested fix
Null-guard optionsNode in ReadOptions (return early, leaving PersistenceData defaults) and guard the
second optionsNode.SelectSingleNode("multifile"). Optionally widen PersisterXML.Load's catch so the
documented "returns null on unparseable input" contract actually holds for malformed structure, not just
malformed XML.
Files: src/LogExpert.Core/Classes/Persister/PersisterXML.cs (ReadOptions, GetOptionsAttribute, Load)
Category: bug
Area: persistence (deprecated XML fallback format)
Found: while writing tests for
PersisterXML.ReadEncodingon branchfix/configured-encoding-registryWhat happens
PersisterXML.ReadOptionsdereferences theoptionsnode without a null check:and
GetOptionsAttributecallsoptionsNode.SelectSingleNode(elementName)straight away. A legacy XML.lxpwhose<file>element has no<options>child therefore throwsNullReferenceException. Later inthe same method
optionsNode.SelectSingleNode("multifile")is dereferenced again.Why it escapes
PersisterXML.Loadis documented to returnnullon failure, but its filter only catchesXmlException,UnauthorizedAccessException,IOExceptionandFileNotFoundException— notNullReferenceException. Its callerPersister.Loadinvokes it from inside acatchblock (theJSON-to-XML fallback), so the NRE replaces the original exception and propagates. Above that,
PersisterHelpers.FindFilenameForSettingshas no handler and is called synchronously fromFileOperationService.AddFileTab, i.e. the file-open path.Reproduce
Open a
.lxpcontaining:Reachability
Low. Current LogExpert saves persistence as JSON; this is the deprecated read-only fallback. A real file
hits it only if hand-edited, truncated, or written by a very old version that omitted the section. It is a
robustness bug rather than a reported one — a corrupt
.lxpshould degrade to "no persistence data", notthrow.
Suggested fix
Null-guard
optionsNodeinReadOptions(return early, leavingPersistenceDatadefaults) and guard thesecond
optionsNode.SelectSingleNode("multifile"). Optionally widenPersisterXML.Load's catch so thedocumented "returns null on unparseable input" contract actually holds for malformed structure, not just
malformed XML.
Files:
src/LogExpert.Core/Classes/Persister/PersisterXML.cs(ReadOptions,GetOptionsAttribute,Load)