microsoft / microsoft/WindowsAppSDK
DWriteCore empty vertical text layout crash
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 4.7k
- Forks
- 471
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 28
Description
### Describe the bug
DWriteCore crashes when the text layout is empty _**and**_ the text layout layouts the text vertically.
### Steps to reproduce the bug
1. open the WindowSdkApp samples and open DWriteCoreGallery
2. In MarkdownWindow.cpp, in the function `CreateTextLayoutsFromPseudoMarkdown` add this:
```
result.push_back(CreateTextLayout(bodyFormat.get(), L"A"));
THROW_IF_FAILED(result.back()->SetFlowDirection(DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT));
THROW_IF_FAILED(result.back()->SetReadingDirection(DWRITE_READING_DIRECTION_TOP_TO_BOTTOM));
return result;
```
under `std::vector codeRanges;` so the function essentially becomes this:
```
std::vector> CreateTextLayoutsFromPseudoMarkdown(std::span inputText, MarkdownStyle style)
{
std::vector> result;
auto headingFormat = CreateTextFormat(style.headingFamilyName, style.headingFontSize, style.headingAxisValues);
auto bodyFormat = CreateTextFormat(style.bodyFamilyName, style.bodyFontSize, style.bodyAxisValues);
auto codeFormat = CreateTextFormat(style.codeFamilyName, style.codeFontSize, style.bodyAxisValues);
THROW_IF_FAILED(codeFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP));
auto GetTextFormat = [&](MarkdownBlockType blockType)
{
switch (blockType)
{
case MarkdownBlockType::Body: return bodyFormat.get();
case MarkdownBlockType::Heading: return headingFormat.get();
case MarkdownBlockType::Code: return codeFormat.get();
default: THROW_HR(E_INVALIDARG);
}
};
std::wstring text;
std::vector boldRanges;
std::vector italicRanges;
std::vector codeRanges;
result.push_back(CreateTextLayout(bodyFormat.get(), L"A"));
THROW_IF_FAILED(result.back()->SetFlowDirection(DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT));
THROW_IF_FAILED(result.back()->SetReadingDirection(DWRITE_READING_DIRECTION_TOP_TO_BOTTOM));
return result;
}
```
if you run this, it works like normal, but if you change `result.push_back(CreateTextLayout(bodyFormat.get(), L"A"));` to `result.push_back(CreateTextLayout(bodyFormat.get(), L""));` (an empty string) it crashes.
if you comment out:
```
THROW_IF_FAILED(result.back()->SetFlowDirection(DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT));
THROW_IF_FAILED(result.back()->SetReadingDirection(DWRITE_READING_DIRECTION_TOP_TO_BOTTOM));
```
Then an empty string does not crash.
In my application, this is the error message I get:
```
thread '' panicked at 'index out of bounds: the len is 0 but the index is 0', rust\layout\src\run_list.rs:325:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
I tried a multitude of functions, but all of them then reported this exact message, the first point I got this error was at `text_layout->Draw` but if I ignore the error, and continue, I get the same error with the functions: `text_layout->GetMetrics`, `text_layout->GetLineMetrics` and `text_layout->HitTestTextPosition`. I have not tested other functions.
### Expected behavior
Just like when using a horizontal layout, the code does not crash/report an error.
### Screenshots
_No response_
### NuGet package version
None
### Packaging type
_No response_
### Windows version
_No response_
### IDE
_No response_
### Additional context
_No response_
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the crash in the WindowSdkApp samples through DWriteCoreGallery, following MarkdownWindow.cpp and CreateTextLayoutsFromPseudoMarkdown. Compare empty and non-empty layouts with vertical flow and reading directions, then inspect the reported rust/layout/src/run_list.rs failure. Done means empty vertical layouts no longer crash in Draw, GetMetrics, GetLineMetrics, or HitTestTextPosition.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100