pbek/qmarkdowntextedit

Mismatch Between Text Modification and Indexing in QMarkdownTextEdit::handleBracketClosing Causing Failure

com3dian opened this issue · 3 comments

Issue Description:

// get the current text from the block (inserted character not included)
// Remove whitespace at start of string (e.g. in multilevel-lists).
const QString text = cursor.block().text().remove(QRegularExpression("^\\s+"));
const int pib = cursor.positionInBlock();

In the method QMarkdownTextEdit::handleBracketClosing, the selected text within a block has its leading white-spaces removed. However, the index pib does not account for these white-spaces, which can result in an ASSERT: "pos <= d.size" error in QString and potentially crash the software when code like text.at(pib - 1) is executed.

To fix

    const QString text = cursor.block().text().remove(QRegularExpression("^\\s+"));

    const int pib = cursor.positionInBlock() - cursor.block().text().length() + text.length();

Note

I'm a beginner in cpp and qt, so please correct me if I'm wrong.

Thanks for this awesome project!

pbek commented

What issue are you trying to fix?

@Waqar144, any clues?

I would say just submit a PR. The issue that is being described seems like a possible scenario and would be good to safe guard against it.

Hi both @pbek @Waqar144, thanks for your response. PR just submitted.

What issue are you trying to fix?

The issue is that the integer pib is created based on the cursor's position in the text block, while the QString text is created by removing the whitespace from the beginning. Therefore if the user have a newline like

                         some text|
^^^^^^^^^^^^^^^^^^^^^^^^^         ^
// start with some spaces         cursor
// In this case the `text` variable is "some text" while `pib` is 35

and the user input an asterisk character *, the program crash with ASSERT: "pos <= d.size" error in Qstring class which is caused by the following boolean computations, specifically text.at(pib-1).

bool hasSpaceOrAsteriskBefore = !text.isEmpty() && pib > 0 &&
(text.at(pib - 1).isSpace() ||
text.at(pib - 1) == QLatin1Char('*'));