XNeedle/README.md

3.1 KiB

XNeedle

A simple tool for injecting faults into XML documents.

Description

The purpose of the tool is to hide a metaphorical "needle in a haystack"
in large XML files, such as an EtherCAT SubDevice Information or ESI file.
Therefore it is a FIT (fault injection test) tool, but can be used off-label.

To live up to its name, XPath is utilized to specify precise locations combined with a good enough set of instructions to do CRUD operations.

As the main application lies with injecting faults into ESI files,
additional functions for calcating checksums are included.
This allows recalculation of CRC32 secured sections of a given document,
such as modules in an ESI file.

Language Specification

The XNeedle language consists of three distinct parts.

  1. Expressions

Expressions may consist of function calls, arithmetic operations, sting concats
and values.

This example prepends the existing inner text of a given node with "Faulty '",
and appends the evaluated string "': 2+2=10".

text("Faulty '" .. text() .. "': " .. string(1+1**2) .. "+2=10");
  1. Rules

A rule consists of a selector and a block.
The selector is using XPath to select any amount of nodes,
for which the block is applied to.
A block however can consist of multiple expressions, nested rules or bangs.

This example sets the text and an attribute based on their respective selectors.

$(""//Device/Type[@ProductCode='#x0B583052' and @RevisionNo='#x00110000']/.."")
{
    $("Type") { attr("ProductCode", hexlit(0xDEADBEEF)); }
    $(""Name[@LcId='1033']"") { text(""LE2904, 4 Ch. Danger Output 24V, 0.5A, TwinUNSAFE""); };
}
  1. Bangs

Bangs are special function calls which take either a string or XPath as parameters,
and make structural changes to the document. They are prefixed with, as the name implies, an exclamation mark.

This example adds, removes and swaps nodes.

$(RxPdo/Index[.="#x1600"]/..)
{
    # Modify name
    $(Name) { text("FSoE Outputs"); }

    # Select the Entry/Index #x7000 and change it to #x9001
    $(Entry/Index[.="#x7000"]) { text("#x9001"); }

    # Select the Entry with Index #x7001 and SubIndex 4, remove it
    $(Entry/Index[.="#x7001"]/../SubIndex[.="4"]/..) { remove(); }

    # Select the 3rd Entry
    $(Entry[3])
    {
        # Add a tag before the above selection
        !before("Entry")
        {
            # Add these tags with their contents respectively
            !add("Index") { text("#x4711"); };
            !add("SubIndex") { text("3"); }
            !add("BitLen") { text("256"); }
            !add("Name") { text("Garbage"); }
            !add("DataType") { text("UINT"); }
        }
    }
    # Swap Entries
    !swap("Entry[3]", "Entry[4]");
}

Project Specifications

The project will be written in C# using .NET 8 and released under a BSD 3-Clause permissive license.

Libraries which will be utilized:

  • Sprache: Monadic parser for reading in XNeedle specifications
  • System.IO.Hashing: For calculating checksums to use in the resulting document
  • Command Line Parser: For parsing command line options

Timeline

A feature complete release is expected in Q2 of 2026.