Opened 2 years ago

Closed 23 months ago

#6451 closed defect (fixed)

Single word wrapping infinite loop

Reported by: bb Owned by: bb
Priority: Release Blocker Milestone: Alpha 26
Component: Core engine Keywords:
Cc: Patch: phab:D4530

Description (last modified by bb)

Currently (r26604) when I select the en_GB language and open the replay menu, the game will hang, eat up all RAM and crash.

Trisecting the issue lead to the following string "%(min)s - %(max)s min" in the durationFilters of the replayMenu. In en_GB this is translated as "%(min)s–%(max)s min". Notice the em_dash directly (no spaces) between two sprintf variables, both of which will be replaced by a number.

The resulting string is too long for the textbox, however since there are no spaces, we cannot word-warp either.

Since r26522 we have the crash as described.

Before r26522 this issue was hided by blindly adding a full width of the word in case of failure. Notice this is wrong because we could end up with wrapping "too late" (there could be a short word following the long word which stays on the same line this way).

Instead we should not process the line on the first word of the line (unless it is the last word of the string).

This issue could also be fixed by changing the translation and adding some spaces around the em-dash, but that is nowhere near a permanent solution.

Change History (10)

comment:1 by bb, 2 years ago

Description: modified (diff)

comment:2 by s0600204, 2 years ago

I can duplicate on ArchLinux.

Couple of things to note:

  • The crash occurs only if the width of the window (if windowed) is less than 1060 pixels (at least on my computer);
  • Adding debugging statements reveal that:
    • The exact string being choked on is 90—120 min (earlier strings containing en-dashes are handled without problem);
    • Specifically: the code is caught in an infinite loop in which it calculates the height of the sub-string 90—120 (the space is not a typo) and adds it to the overall calculated height of the full (line wrapped) string, causing said value to increase infinitely;
  • Removing the space in %(min)s—%(max)s min so that the problematic translated string becomes 90—120min also (sub-optimally) resolves the issue.
    • However, doing this then causes pyrogenesis to choke on the string Very Large (in the same GUI page) if the window's width is reduced below 968 pixels.

This looks to me like a text-wrapping issue, and not that the text renderer is struggling with unicode.


Also:

The en-dash () is stored as a multi-byte UTF-8 character (E2 80 93) within the .po file, and then converted into an entry in a wide-character string typed variable upon file load. This happens within the UTF8Codec class (lib/utf8.cpp), and long before the text renderer gets invoked.

Each character gets its own separate entry in that variable; so by the time it gets to the text renderer - with the sprintf substitutions performed - the contents of the variable will be something like:

['3', '0', '–', '4', '5', '\0']

Or, if you prefer:

[0x33, 0x30, 0x2013, 0x34, 0x35, 0x00]

comment:3 by bb, 2 years ago

Component: Internationalization & LocalizationCore engine
Description: modified (diff)
Patch: phab:D4530
Summary: Em-dash sprinf combination crashSingle word wrapping infinite loop

comment:4 by s0600204, 2 years ago

The resulting string is too long for the textbox, however since there are no spaces, we cannot word-warp either.

Interestingly enough, making the first word of the string longer (e.g. "{––%(min)s––%(max)s––} min") also prevents a crash on page open.

As one gradually widens the window, there's a point where it seems to reach a threshold (about where the width of the available space to display the word becomes roughly equal to that of the word) where it does crash.

comment:5 by Langbart, 2 years ago

closed duplicate #6457 - Tooltip line wrap issue (13/Mar/22)

Applying the linked patch (D4530) fixes the issue for the tooltip.

comment:6 by Silier, 2 years ago

Owner: set to bb

comment:7 by marder, 2 years ago

Note: on windows / svn 26772: the crash seems to happen on all languages

comment:8 by Langbart, 2 years ago

a duplicated issue has been closed #6523

comment:9 by Langbart, 2 years ago

a duplicated issue has been closed #6530

comment:10 by bb, 23 months ago

Resolution: fixed
Status: newclosed

In 26889:

Fix an infinite loop when trying to word-wrap

Comments By: Stan, Phosit, s0600204, Langbart, Silier, marder, vladislav
Reviewed By: wraitii

Differential Revision: D4530
fixes #6451

Note: See TracTickets for help on using tickets.