<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Prevent Settings search from passing queries that normalize to empty or
whitespace-only text into fuzzy matching, and make the shared matcher
return its existing no-match result for whitespace-only queries.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] **Communication:** Scoped to the requested atomic Settings
search-safety audit follow-up; submitted as a draft.
- [x] **Tests:** Added focused regression coverage; all 46 selected
tests pass.
- [x] **Localization:** No new user-facing strings; normalization and
existing localized search behavior are unchanged.
Issue closure, development/user documentation, and new-binary checklist
items are N/A. No new projects, dependencies, binaries, or persisted
settings changes.
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
**Trigger:** A query consisting of U+00A8 (spacing diaeresis) passes the
initial whitespace check in
`src\settings-ui\Settings.UI\Services\SearchIndexService.cs`. FormKD
normalization decomposes it into U+0020 plus a combining mark; removing
nonspacing marks leaves a single space. Previously,
`src\common\Common.Search\FuzzSearch\StringMatcher.cs` checked only for
null/empty input before trimming, then indexed the first element of an
empty token array. With a populated search index, the resulting
`IndexOutOfRangeException` can propagate through `Parallel.ForEach` to
the live search handler, which catches cancellation only. This is a
source/unit-test finding, not a claim of a reproduced live application
crash.
The Settings service now returns no results after normalization when no
searchable text remains. The shared matcher rejects
null/empty/whitespace queries before its per-start-index matching loop,
preventing empty trimmed/tokenized input from reaching the indexed
access. Both use existing no-match behavior rather than adding an
exception catch.
**Shared-caller risk:** Common.Search is also used by Shortcut Guide and
the Command Palette PowerToys extension. Their existing blank-query
handling remains unchanged, as do the matching algorithm, separators,
scoring, highlighting, and case options for nonempty queries. No public
API signature changes. `NormalizeString` becomes internal solely for
direct coverage through the existing Settings test friend assembly.
Tests are in the existing
`src\settings-ui\Settings.UI.UnitTests\Search\StringMatcherTests.cs` and
`src\settings-ui\Settings.UI.UnitTests\Search\SearchIndexServiceTests.cs`;
there is no standalone Common.Search test project on current main. The
service fixture supplies a nonempty in-memory index, restores it
afterward, and does not load Settings resources or change user settings.
This PR deliberately excludes expander-result filtering and prebuilt
search-index generation/embedding changes. It does not auto-close the
different search-crash reports #41817 or #47118.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- Ran the repository first-build prerequisite
`tools\build\build-essentials.cmd -Platform x64 -Configuration Release`
after the fresh worktree reported missing NuGet assets; restore and
essentials completed successfully.
- Built `Settings.UI.UnitTests` in Release x64 using
`tools\build\build.ps1` with the worktree `SolutionDir`; exit code 0.
- Ran the existing Microsoft.Testing.Platform runner with `--filter
"FullyQualifiedName~Settings.UI.UnitTests.Search"
--minimum-expected-tests 46 --report-trx`: **46 passed, 0 failed, 0
skipped**.
- Covered null/empty/ASCII whitespace, Unicode spaces, U+00A8
compatibility normalization, combining-only queries, both Search
overloads with a nonempty index, both case options,
ordinary/padded/multiword queries, unchanged scores/highlights,
exact-match ranking, and accented/fullwidth normalization.
- Did not launch or modify the installed/running PowerToys instance or
user settings.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>