Description: fix crash when text contains too many directional chars
 In case a text to be layouted contains more than 128 directional characters
 it causes the application to crash.
 .
 The function initScriptAnalysisAndIsolatePairs() collects information of
 RTL/LTR chaaracters into vector "isolatePairs". The size of the vector is
 capped to 128. Later the function generateDirectionalRuns() iterates
 the text again and tries to access items from the previously capped vector
 above the upper bound.
Origin: upstream, a concatenation of two commits:
 https://code.qt.io/cgit/qt/qtbase.git/commit/?id=79f2a9e666a241c5
 https://code.qt.io/cgit/qt/qtbase.git/commit/?id=1232205e32464d90
Last-Update: 2019-10-29

--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -252,8 +252,6 @@ struct QBidiAlgorithm {
 
     void initScriptAnalysisAndIsolatePairs(Vector<IsolatePair> &isolatePairs)
     {
-        isolatePairs.append({ -1, length }); // treat the whole string as one isolate
-
         int isolateStack[128];
         int isolateLevel = 0;
         // load directions of string, and determine isolate pairs
@@ -304,6 +302,14 @@ struct QBidiAlgorithm {
             case QChar::DirS:
             case QChar::DirB:
                 analysis[pos].bidiFlags = QScriptAnalysis::BidiResetToParagraphLevel;
+                if (uc == QChar::ParagraphSeparator) {
+                    // close all open isolates as we start a new paragraph
+                    while (isolateLevel > 0) {
+                        --isolateLevel;
+                        if (isolateLevel < 128)
+                            isolatePairs[isolateStack[isolateLevel]].end = pos;
+                    }
+                }
                 break;
             default:
                 break;
@@ -393,6 +399,7 @@ struct QBidiAlgorithm {
                         analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
                     runHasContent = true;
                     lastRunWithContent = -1;
+                    ++isolatePairPosition;
                 }
                 int runBeforeIsolate = runs.size();
                 ushort newLevel = isRtl ? ((stack.top().level + 1) | 1) : ((stack.top().level + 2) & ~1);
@@ -434,20 +441,18 @@ struct QBidiAlgorithm {
                 doEmbed(true, true, false);
                 break;
             case QChar::DirLRI:
-                ++isolatePairPosition;
-                Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
                 doEmbed(false, false, true);
                 break;
             case QChar::DirRLI:
-                ++isolatePairPosition;
-                Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
                 doEmbed(true, false, true);
                 break;
             case QChar::DirFSI: {
-                ++isolatePairPosition;
-                const auto &pair = isolatePairs.at(isolatePairPosition);
-                Q_ASSERT(pair.start == i);
-                bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
+                bool isRtl = false;
+                if (isolatePairPosition < isolatePairs.size()) {
+                    const auto &pair = isolatePairs.at(isolatePairPosition);
+                    Q_ASSERT(pair.start == i);
+                    isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
+                }
                 doEmbed(isRtl, false, true);
                 break;
             }
@@ -492,16 +497,24 @@ struct QBidiAlgorithm {
                     analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
                 break;
             case QChar::DirB:
-                // paragraph separator, go down to base direction
-                appendRun(i - 1);
-                while (stack.counter > 1) {
-                    // there might be remaining isolates on the stack that are missing a PDI. Those need to get
-                    // a continuation indicating to take the eos from the end of the string (ie. the paragraph level)
-                    const auto &t = stack.top();
-                    if (t.isIsolate) {
-                        runs[t.runBeforeIsolate].continuation = -2;
+                // paragraph separator, go down to base direction, reset all state
+                if (text[i].unicode() == QChar::ParagraphSeparator) {
+                    appendRun(i - 1);
+                    while (stack.counter > 1) {
+                        // there might be remaining isolates on the stack that are missing a PDI. Those need to get
+                        // a continuation indicating to take the eos from the end of the string (ie. the paragraph level)
+                        const auto &t = stack.top();
+                        if (t.isIsolate) {
+                            runs[t.runBeforeIsolate].continuation = -2;
+                        }
+                        --stack.counter;
                     }
-                    --stack.counter;
+                    continuationFrom = -1;
+                    lastRunWithContent = -1;
+                    validIsolateCount = 0;
+                    overflowIsolateCount = 0;
+                    overflowEmbeddingCount = 0;
+                    level = baseLevel;
                 }
                 break;
             default:
