Browse Source

PegHighlighter: fix index-out-of-scope issue when parsing results

When user inserts many empty lines at once, the increated block number
may exceed the range of the parser result.
Le Tan 7 years ago
parent
commit
17b1a606d5
3 changed files with 30 additions and 8 deletions
  1. 20 4
      src/peghighlighterresult.cpp
  2. 2 0
      src/peghighlighterresult.h
  3. 8 4
      src/pegmarkdownhighlighter.cpp

+ 20 - 4
src/peghighlighterresult.cpp

@@ -120,6 +120,10 @@ void PegHighlighterResult::parseBlocksHighlightOne(QVector<QVector<HLUnit>> &p_b
     QTextBlock block = p_doc->findBlock(p_pos);
     int startBlockNum = block.blockNumber();
     int endBlockNum = p_doc->findBlock(p_end).blockNumber();
+    if (endBlockNum >= p_blocksHighlights.size()) {
+        endBlockNum = p_blocksHighlights.size() - 1;
+    }
+
     while (block.isValid())
     {
         int blockNum = block.blockNumber();
@@ -148,6 +152,7 @@ void PegHighlighterResult::parseBlocksHighlightOne(QVector<QVector<HLUnit>> &p_b
     }
 }
 
+#if 0
 void PegHighlighterResult::parseBlocksElementRegionOne(QHash<int, QVector<VElementRegion>> &p_regs,
                                                        const QTextDocument *p_doc,
                                                        unsigned long p_pos,
@@ -188,6 +193,7 @@ void PegHighlighterResult::parseBlocksElementRegionOne(QHash<int, QVector<VEleme
         regs.append(VElementRegion(start, end));
     }
 }
+#endif
 
 void PegHighlighterResult::parseFencedCodeBlocks(const PegMarkdownHighlighter *p_peg,
                                                  const QSharedPointer<PegParseResult> &p_result)
@@ -200,6 +206,9 @@ void PegHighlighterResult::parseFencedCodeBlocks(const PegMarkdownHighlighter *p
     for (auto it = regs.begin(); it != regs.end(); ++it) {
         QTextBlock block = doc->findBlock(it.value().m_startPos);
         int lastBlock = doc->findBlock(it.value().m_endPos - 1).blockNumber();
+        if (lastBlock >= p_result->m_numOfBlocks) {
+            lastBlock = p_result->m_numOfBlocks - 1;
+        }
 
         while (block.isValid()) {
             int blockNumber = block.blockNumber();
@@ -257,13 +266,11 @@ void PegHighlighterResult::parseMathjaxBlocks(const PegMarkdownHighlighter *p_pe
     for (auto it = inlineRegs.begin(); it != inlineRegs.end(); ++it) {
         const VElementRegion &r = *it;
         QTextBlock block = doc->findBlock(r.m_startPos);
-        // Inline equation MUST in one block.
-        Q_ASSERT(block.blockNumber() == doc->findBlock(r.m_endPos - 1).blockNumber());
-
         if (!block.isValid()) {
             continue;
         }
 
+        // Inline equation MUST in one block.
         if (r.m_endPos - block.position() > block.length()) {
             continue;
         }
@@ -287,6 +294,9 @@ void PegHighlighterResult::parseMathjaxBlocks(const PegMarkdownHighlighter *p_pe
         const VElementRegion &r = *it;
         QTextBlock block = doc->findBlock(r.m_startPos);
         int lastBlock = doc->findBlock(r.m_endPos - 1).blockNumber();
+        if (lastBlock >= p_result->m_numOfBlocks) {
+            lastBlock = p_result->m_numOfBlocks - 1;
+        }
 
         while (block.isValid()) {
             int blockNum = block.blockNumber();
@@ -308,7 +318,10 @@ void PegHighlighterResult::parseMathjaxBlocks(const PegMarkdownHighlighter *p_pe
                     m_mathjaxBlocks.append(item);
                 }
             } else {
-                Q_ASSERT(text.startsWith(marker));
+                if (!text.startsWith(marker)) {
+                    break;
+                }
+
                 if (text.size() > 2 && text.endsWith(marker)) {
                     // Within one block.
                     item.m_blockNumber = blockNum;
@@ -338,6 +351,9 @@ void PegHighlighterResult::parseHRuleBlocks(const PegMarkdownHighlighter *p_peg,
     for (auto it = regs.begin(); it != regs.end(); ++it) {
         QTextBlock block = doc->findBlock(it->m_startPos);
         int lastBlock = doc->findBlock(it->m_endPos - 1).blockNumber();
+        if (lastBlock >= p_result->m_numOfBlocks) {
+            lastBlock = p_result->m_numOfBlocks - 1;
+        }
 
         while (block.isValid()) {
             int blockNumber = block.blockNumber();

+ 2 - 0
src/peghighlighterresult.h

@@ -94,10 +94,12 @@ private:
     void parseHRuleBlocks(const PegMarkdownHighlighter *p_peg,
                           const QSharedPointer<PegParseResult> &p_result);
 
+#if 0
     void parseBlocksElementRegionOne(QHash<int, QVector<VElementRegion>> &p_regs,
                                      const QTextDocument *p_doc,
                                      unsigned long p_pos,
                                      unsigned long p_end);
+#endif
 
     QRegExp m_codeBlockStartExp;
     QRegExp m_codeBlockEndExp;

+ 8 - 4
src/pegmarkdownhighlighter.cpp

@@ -209,6 +209,10 @@ void PegMarkdownHighlighter::startFastParse(int p_position, int p_charsRemoved,
     // Get affected block range.
     int firstBlockNum, lastBlockNum;
     getFastParseBlockRange(p_position, p_charsRemoved, p_charsAdded, firstBlockNum, lastBlockNum);
+    if (firstBlockNum == -1) {
+        m_fastResult.reset();
+        return;
+    }
 
     QString text;
     QTextBlock block = m_doc->findBlockByNumber(firstBlockNum);
@@ -568,7 +572,7 @@ void PegMarkdownHighlighter::getFastParseBlockRange(int p_position,
                                                     int &p_firstBlock,
                                                     int &p_lastBlock) const
 {
-    const int maxNumOfBlocks = 50;
+    const int maxNumOfBlocks = 500;
 
     int charsChanged = p_charsRemoved + p_charsAdded;
     QTextBlock firstBlock = m_doc->findBlock(p_position);
@@ -580,10 +584,8 @@ void PegMarkdownHighlighter::getFastParseBlockRange(int p_position,
     }
 
     int num = lastBlock.blockNumber() - firstBlock.blockNumber() + 1;
-
     if (num >= maxNumOfBlocks) {
-        p_firstBlock = firstBlock.blockNumber();
-        p_lastBlock = p_firstBlock + maxNumOfBlocks - 1;
+        p_firstBlock = p_lastBlock = -1;
         return;
     }
 
@@ -667,5 +669,7 @@ void PegMarkdownHighlighter::getFastParseBlockRange(int p_position,
     p_lastBlock = lastBlock.blockNumber();
     if (p_lastBlock < p_firstBlock) {
         p_lastBlock = p_firstBlock;
+    } else if (p_lastBlock - p_firstBlock + 1 > maxNumOfBlocks) {
+        p_firstBlock = p_lastBlock = -1;
     }
 }