microsoft / microsoft/WindowsAppSDK

DWriteCore empty vertical text layout crash

Open
#4,070 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area-DWriteCore
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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.