When the buffer has fewer bytes than ``offset + nbytes``, the transform
will either trim the resulting buffer as though ``offset + nbytes == buffer_length``
or produce an empty buffer on which ``bsize:0`` would match. The behavior
is determined by the inclusion of ``truncate`` with the keyword.
The following examples use an input buffer with the value ``curl/7.64.1``.
Without ``truncate`` (the default), when ``offset + nbytes`` exceeds
the buffer length, the transform produces an empty buffer on which
``bsize:0`` would match::
subslice: 0, 30;
When ``truncate`` is present, ``nbytes + offset`` is reduced
to equal the input buffer length. The transform produces ``curl/7.64.1``::
subslice: 0, 30, truncate;
``truncate`` does not require ``nbytes`` to be present. The transform
produces ``curl/7.64.1``::
subslice: 0, truncate;
Negative Offset Handling
~~~~~~~~~~~~~~~~~~~~~~~~~
When a negative offset's absolute value exceeds the buffer length, the behavior
depends on whether ``truncate`` is present:
Without ``truncate``, the transform produces an empty buffer. For example,
with input buffer ``This is Suricata`` (16 bytes), using ``subslice: -17;``
produces an empty string and ``bsize:0`` would match::
subslice: -17;
With ``truncate`` present, an excessive negative offset is reset to the
buffer length, effectively starting at offset 0. Using the same input buffer
``This is Suricata`` (16 bytes), ``subslice: -17, truncate;`` is treated as
``subslice: -16, truncate;`` and produces the full buffer ``This is Suricata``::
subslice: -17, truncate;
This also works with ``nbytes``. For example, ``subslice: -20, 5, truncate;``
with input buffer ``This is Suricata`` starts at offset 0 and takes 5 bytes,
producing ``This`` (with a trailing space)::
subslice: -20, 5, truncate;
Similarly, when ``truncate`` is present, negative ``nbytes`` values that would
place the endpoint before the beginning of the buffer are reset to the
beginning of the buffer. For example, ``subslice: 0, -30, truncate;`` with
input buffer ``This is Suricata`` (16 bytes) resets the endpoint to the
beginning of the buffer, producing an empty buffer::
subslice: 0, -30, truncate;
However, a moderate negative ``nbytes`` works normally. For example,
``subslice: 0, -8, truncate;`` ends 8 bytes from the end (position 8),
producing ``This is`` (with a trailing space)::
subslice: 0, -8, truncate;
Full Rule Examples
~~~~~~~~~~~~~~~~~~
The following rule inspects the first 4 bytes of the HTTP User-Agent
header to match traffic with a User-Agent beginning with ``curl``:
..container:: example-rule
alert http any any -> any any (msg:"curl User-Agent"; :example-rule-emphasis:`http.user_agent; subslice: 0, 4, truncate; content:"curl";` bsize:4; sid:1;)
The following rule inspects the last 4 bytes of the HTTP URI to match
requests whose URI ends with ``.php``:
..container:: example-rule
alert http any any -> any any (msg:"PHP URI"; :example-rule-emphasis:`http.uri; subslice: -4; content:".php";` bsize:4; sid:2;)