Skip to content

Fix excessive combining marks causing GPU overload and rendering corruption#294

Open
vserediuk wants to merge 1 commit intodesktop-app:masterfrom
vserediuk:bugfix/combining-marks-gpu-overload
Open

Fix excessive combining marks causing GPU overload and rendering corruption#294
vserediuk wants to merge 1 commit intodesktop-app:masterfrom
vserediuk:bugfix/combining-marks-gpu-overload

Conversation

@vserediuk
Copy link

@vserediuk vserediuk commented Mar 19, 2026

Fix excessive combining marks causing GPU overload and rendering corruption

Problem

Text containing a large number of Unicode combining characters (such as U+20DD COMBINING ENCLOSING CIRCLE) stacked on a single base character causes:

  1. GPU overload — the text renderer tries to draw hundreds/thousands of overlapping glyphs for a single character
  2. Incorrect display — the rendered text appears as visual noise/garbage

Example of malicious text: ы҉⃝ repeated hundreds of times — a single Cyrillic letter with COMBINING CYRILLIC MILLIONS SIGN (U+0489, Mark_NonSpacing) followed by COMBINING ENCLOSING CIRCLE (U+20DD, Mark_Enclosing).

Root Cause

The IsDiacritic() function in ui/text/text.cpp only checked for QChar::Mark_NonSpacing category. While the block parser already has a limit (kMaxDiacAfterSymbol = 2) on how many diacritics can follow a base character, the combining marks from Mark_Enclosing (e.g., U+20DD COMBINING ENCLOSING CIRCLE, U+20DE COMBINING ENCLOSING SQUARE, U+20DF COMBINING ENCLOSING DIAMOND, U+20E0 COMBINING ENCLOSING CIRCLE BACKSLASH) and Mark_SpacingCombining categories were not recognized as diacritics and bypassed this limit entirely.

Fix

Extend IsDiacritic() to also recognize QChar::Mark_Enclosing and QChar::Mark_SpacingCombining Unicode categories. This ensures the existing per-character combining mark limit applies to ALL types of Unicode combining characters, preventing the stacking abuse while preserving legitimate use (the limit of 2 combining marks is sufficient for all natural scripts).

Affected file

  • ui/text/text.cpp (in desktop-app/lib_ui)

Testing

Text like ы + U+0489 + U+20DD repeated hundreds of times (ы...) should now:

  • Display with at most 2 combining marks per base character
  • Not cause GPU overload
  • Not produce visual corruption

@CLAassistant
Copy link

CLAassistant commented Mar 19, 2026

CLA assistant check
All committers have signed the CLA.

Extend IsDiacritic() to recognize Mark_Enclosing and Mark_SpacingCombining Unicode categories, so the existing per-character combining mark limit (kMaxDiacAfterSymbol = 2) applies to all types of combining characters.

Previously only Mark_NonSpacing was checked, allowing characters like U+20DD (COMBINING ENCLOSING CIRCLE) to bypass the limit and stack hundreds of times on a single base character, causing GPU overload and rendering corruption.
@vserediuk vserediuk force-pushed the bugfix/combining-marks-gpu-overload branch from 31cd135 to 34ea6c5 Compare March 19, 2026 20:01
@vserediuk
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants