mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
term_bidi_line: fix failure to initialise wcTo.
The bidi algorithm is called on the array term->wcFrom, modifying it in place. Then the Arabic-shaping algorithm - which can't work in place because it needs to check the original value of array entries it's already modified - is called, copying term->wcFrom to term->wcTo as a side effect. Then the cleanup code expects the final version of the line to be in wcTo. So if shaping is turned off, we still need to copy wcFrom into wcTo, even if we don't modify it en route. Previously, that copy was done under an if statement whose condition boils down to 'if bidi is enabled but shaping is not'. So if that code was ever reached with _both_ bidi and shaping turned off, then nothing at all would copy wcFrom into wcTo, and wcTo would be filled with nonsense. Before trust sigils were introduced, that was OK, because the whole function body was skipped if both bidi and shaping were turned off. But now trust-sigil handling lives in there too, so we can get into that code with the previously disallowed combination of flags. If you're lucky, this means that the assert(opos == term->cols) near the bottom of the function fails, on the basis that opos is the sum of nonsense values from wcTo; if you're unlucky I suppose you might manage to get _plausible_ nonsense through to the screen. Now fixed, by changing that central if statement into a much more obvious one: if we're running do_shape, then that can copy wcFrom into wcTo, and if and only if we're _not_, then we must copy it another way. (And while I'm here, I've turned that other way from a manual for loop into memcpy.)
This commit is contained in:
parent
399603fd95
commit
117c7857d2
12
terminal.c
12
terminal.c
@ -5130,13 +5130,13 @@ static termchar *term_bidi_line(Terminal *term, struct termline *ldata,
|
||||
if(!term->bidi)
|
||||
do_bidi(term->wcFrom, nbc);
|
||||
|
||||
/* this is saved iff done from inside the shaping */
|
||||
if(!term->bidi && term->arabicshaping)
|
||||
for(it=0; it<nbc; it++)
|
||||
term->wcTo[it] = term->wcFrom[it];
|
||||
|
||||
if(!term->arabicshaping)
|
||||
if(!term->arabicshaping) {
|
||||
do_shape(term->wcFrom, term->wcTo, nbc);
|
||||
} else {
|
||||
/* If we're not calling do_shape, we must copy the
|
||||
* data into wcTo anyway, unchanged */
|
||||
memcpy(term->wcTo, term->wcFrom, nbc * sizeof(*term->wcTo));
|
||||
}
|
||||
|
||||
if (term->ltemp_size < ldata->size) {
|
||||
term->ltemp_size = ldata->size;
|
||||
|
Loading…
Reference in New Issue
Block a user