Fix Markdown preview crash on UTF-8 files with >2MB size and <1.5M characters#47391
Merged
Merged
Conversation
…aracters Agent-Logs-Url: https://github.com/microsoft/PowerToys/sessions/a1e3bb35-9ace-491a-a6b5-6bfe70634c0f Co-authored-by: MuyuanMS <116717757+MuyuanMS@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix preview pane crash on large UTF-8 markdown files
Fix Markdown preview crash on UTF-8 files with >2MB size and <1.5M characters
Apr 29, 2026
MuyuanMS
approved these changes
May 13, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates Markdown preview sizing logic so WebView2 avoids NavigateToString for HTML whose UTF-8 byte size exceeds the safe threshold, preventing crashes with large multi-byte Unicode Markdown content.
Changes:
- Replaces
string.Lengththreshold checking withEncoding.UTF8.GetByteCount. - Updates comments to clarify the WebView2 limit is byte-size sensitive.
| if (markdownHTML.Length > 1_500_000) | ||
| // While testing the limit, it turned out it is ~1.5MB of UTF-8 encoded content, so to be on the safe side we check the UTF-8 byte count. | ||
| // Using character count (string.Length) is not sufficient because multi-byte UTF-8 characters (e.g. CJK) can cause the byte size to exceed the limit even when the character count is below it. | ||
| if (System.Text.Encoding.UTF8.GetByteCount(markdownHTML) > 1_500_000) |
Contributor
There was a problem hiding this comment.
Added the requested coverage in MarkdownPreviewHandlerTest.cs:
- multi-byte UTF-8 content under 1.5M chars but over 2MB -> temp-file navigation
- content under both thresholds ->
NavigateToString - ASCII content over 1.5M chars -> temp-file navigation
The tests verify the navigation path by checking whether _localFileURI is populated and, for temp-file cases, that the WebView source points to the generated file. I also rebuilt the handler/test projects with MSBuild and ran PreviewPaneUnitTests via vstest.console.exe (14/14 passing).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
@copilot please re-review the latest changes. |
LegendaryBlair
approved these changes
May 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
NavigateToStringthrowsArgumentExceptionwhen previewing Markdown files containing many multi-byte UTF-8 characters (e.g., CJK) — file size exceeds 2MB but character count stays under 1.5M, bypassing the guard.Summary of the Pull Request
The size guard in
MarkdownPreviewHandlerControlusedmarkdownHTML.Length(character count / UTF-16 code units), but WebView2'sNavigateToStringlimit is measured in bytes. A string with 700K CJK characters has only 700K.Lengthunits but ~2.1MB of UTF-8 bytes — enough to crash the API while passing the old check.Changes:
MarkdownPreviewHandlerControl.cs: Replace character-count guard with UTF-8 byte count:When the byte threshold is exceeded, content is written to a temp file and loaded via
_browser.Sourceinstead ofNavigateToString— existing fallback path, now correctly triggered.MarkdownPreviewHandlerTest.cs: Added 3 regression tests to prevent this class of bug from recurring:NavigateToStringpathPR Checklist
Detailed Description of the Pull Request / Additional comments
The existing fallback (write HTML to a temp file, navigate via
_browser.Source) was already correct and handles arbitrarily large content safely. The only bug was in the guard condition that decides when to use it — it measured the wrong unit (characters vs. bytes). Single-byte ASCII content is unaffected; only multi-byte Unicode content was under-counted.The tests use reflection to read the private
_localFileURIfield. Since this field is set synchronously beforeControls.Add(_browser), the check is race-free: once the wait loop exits withControls.Count > 0,_localFileURIis guaranteed to have its final value.Validation Steps Performed
Length= 700K (passes old check) → UTF-8 bytes ≈ 2.1MB (fails new check → uses temp file path, no crash).UnitTests-MarkdownPreviewHandlercovering the multi-byte threshold boundary; all 14 tests in the suite pass (14/14).