Skip to content

Malformed legacy XML .lxp throws NullReferenceException on the file-open path #680

Description

@Hirogen

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugPesky little gritter, needs squashing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions