#### Brief overview of PR changes/additions
- Converts the hand-balanced re-entrancy depth counters to
`qScopeGuard`, matching the pattern already used by `TTimer`, `TAction`,
`TScript` and `Host`: `cTelnet::mDecompressionRecursionDepth` (four
exits across a ~290-line function), `cTelnet::mLoopbackProcessingDepth`,
and `mProcessingDepth` in `AliasUnit`, `TriggerUnit` and `KeyUnit`.
- Strictly behaviour-preserving. Each guard fires exactly where the
manual decrement did, `Q_ASSERT` and the depth-0 drain (`doCleanup()`,
`mRootNodesAddedWhileProcessing.clear()`) included, and the over-limit
cap still trips on the same value and reports the same message. The
recursion cap moves from a file-local constant to
`cTelnet::scmMaxDecompressionRecursion` next to its sibling so a test
can pin the threshold.
- Adds `AliasUnit::processingDepth()` and `KeyUnit::processingDepth()`
(mirroring `TriggerUnit` and `ActionUnit`), a new
`UnitProcessingDepthTest` and a new slot in `cTelnetBufferTest` that
drive each converted exit and assert the count comes back - including an
item that deletes itself mid-pass, so the drain step is covered too.
#### Motivation for adding to Mudlet
The counters are members, so a level leaked by a future early `return`
is permanent for that object rather than for that call. Eight leaks in
`cTelnet::mDecompressionRecursionDepth` and the connection refuses all
further data for the rest of the session, endlessly printing "Too much
data to process at once, some may have been lost" - a sticky, crash-free
hang that no test or sanitizer would catch.
`KeyUnit::processDataStream()` had the same hazard in miniature: it
returned from inside its match loop, so a second copy of the
decrement-assert-drain block had to be kept in step by hand (and it ran
`doCleanup()` while the range-`for` over the list it deletes from was
still in scope). All of these are balanced correctly today; this makes
it impossible for them not to be.
#### Other info (issues closed, discussion etc)
Follows up a review note on PR #9677 ("fix: telnet NUL terminator heap
overflow"). No behaviour change, so nothing to demo.
**Test case:** full `ctest` 72/73 and busted twice (2158 successes / 1
failure), the two failures being `TKeySequenceEditTest` and `UI_spec`
`getMainWindowSize`, both reproduced with `src/` reverted to development
so neither is from this change; sabotage check - restoring the
hand-balanced form with the over-limit decrement omitted, the `KeyUnit`
match-exit decrement omitted, and the `AliasUnit` drain omitted turned
`cTelnetBufferTest` and `UnitProcessingDepthTest` red on exactly those
three points ("a recursion level was leaked", "the drain did not run"),
and restoring the guards turned them green.
Assisted-by: Claude:claude-opus-5