#### Brief overview of PR changes/additions
Saving a map at format <= 19 was leaking internal `system.fallback_*`
keys into the live map's user-visible userData, permanently. A format-19
save polluted room userData; a save at format < 19 tainted map userData
forever.
- The first commit serialises a locally-augmented copy, so saves never
mutate the live map. Old-format **file** output stays byte-identical, so
older Mudlets still receive their compatibility keys.
- The second commit strips stale leaked keys on format >= 19 loads, so
already-tainted maps self-clean.
#### Motivation for adding to Mudlet
Users' maps were silently accumulating internal keys they never set, and
those keys survived across save/load cycles. This stops new pollution
and cleans up existing damage.
#### Other info (issues closed, discussion etc)
Stacked on top of #9468 (base branch `add-persistence-roundtrip-tests`);
GitHub will auto-retarget to `development` once that PR merges. Please
merge after #9468. These are the two bugs the round-trip tests caught,
so this PR also flips their `QEXPECT_FAIL` markers to hard assertions.
Human build/test pending; DCO sign-off to be added at squash time.
https://github.com/user-attachments/assets/3931edb7-4daf-4277-bac4-0c6680d5bfe3
#### Brief overview of PR changes/additions
The 12 functional-test sites that dereferenced the result of
`getActiveHost()`, `getArea()`, `getRoom()` or `getHost()` without first
checking it for null now guard the pointer with `QVERIFY(ptr)` before
use. The other lookup sites this PR touched already had a `QVERIFY` and
are left as they were.
#### Motivation for adding to Mudlet
CodeQL's `cpp/inconsistent-null-check` rule flagged these lookups
because some call sites checked the returned pointer for null while
others in the same files dereferenced it directly. Adding `QVERIFY(ptr)`
at the previously-unchecked sites makes the handling consistent: every
lookup result is verified before it is dereferenced, so a null result
fails the test loudly instead of crashing.
`QVERIFY` is the project's accepted idiom for guarding a pointer in a
test, so it is used here rather than an `if (!ptr) { QFAIL(...); }`
block. CodeQL does not recognise `QVERIFY(ptr)` as a null check (the
branch it generates tests `qVerify()`'s return value, not the pointer
itself), so it will keep reporting `cpp/inconsistent-null-check` on
these sites and on the pre-existing `QVERIFY` sites. Those alerts will
be dismissed as false positives rather than changing the test style to
satisfy the checker.
#### Other info (issues closed, discussion etc)
Test files only - no production code is touched. The 12 newly-guarded
sites are:
- `MapRoundTripTest.cpp` - 2 (`pAreaA`, `pAreaB`)
- `TriggerSameLineMatchTest.cpp` - 6 (`host`)
- `TFeedTriggersRecursionTest.cpp` - 4 (`host`)
**Test case:**
Build and run the five affected binaries under the functional-test flock
- all pass:
- `TFeedTriggersRecursionTest` - passed
- `TriggerSameLineMatchTest` - passed
- `MapRoundTripTest` - 6 passed, 0 failed
- `UndoServerWrapTest` - passed
- `UndoServerWrapReplay` - 2 passed, 1 skipped (manual replay tool;
skips without `REPLAY_CAPTURE`/`REPLAY_OUT`)
#### Brief overview of PR changes/additions
Adds two functional round-trip tests.
- **ProfileRoundTripTest** builds a 31-item tree across all five object
types (with non-ASCII names and XML-hostile content), saves it via the
production `XMLexport`, reimports via `XMLimport`, and compares ~40
fields.
- **MapRoundTripTest** builds a map with rooms, areas, exits, special
exits, custom lines, userData and labels, then round-trips it at every
map format (17-20).
Both tests were proven able to fail via temporary sabotage.
#### Motivation for adding to Mudlet
Profile and map persistence had no automated coverage, so regressions in
save/load could ship unnoticed. These tests lock down the round-trip
behaviour. They immediately caught two real map-persistence bugs.
#### Other info (issues closed, discussion etc)
The two map bugs these tests caught are fixed in the stacked follow-up
PR #9469 (`fix-map-userdata-pollution` branch), which flips these tests'
`QEXPECT_FAIL` markers to hard assertions.
Tested by hand. Squash-merge with:
```
Assisted-by: Claude:claude-fable-5
Signed-off-by: Vadim Peretokin <vadim.peretokin@mudlet.org>
```