Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
4.8.6
-
c1b46b98edc2f12fb7c596660777debed9191f52
Description
A Potential "Division by zero" exception in QPlainTextEditPrivate line 976
If QPlainTextEdit is used with a Courier font like this:
QFont outputFont("Courier"); mOutputWidget = new QPlainTextEdit(mainWidget); mOutputWidget->setReadOnly(true); mOutputWidget->setFont(outputFont);
This yields divide by zero when GetTextMetrics fails. It flags a diagnostic message "Error: QFontEngineWin: GetTextMetrics failed ()" and then crashes with a "Division by zero" exception with following stack trace:
QtGui4.dll!QPlainTextEditPrivate::_q_adjustScrollbars() Line 976 + 0x34 bytes C++ QtGui4.dll!QPlainTextEdit::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 157 + 0x9 bytes C++ QtCore4.dll!QMetaObject::activate(QObject * sender, const QMetaObject * m, int local_signal_index, void * * argv) Line 3545 + 0x1e bytes C++ QtGui4.dll!QTextControl::documentSizeChanged(const QSizeF & _t1) Line 309 C++ QtGui4.dll!QTextControl::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 139 + 0xc bytes C++ QtCore4.dll!QMetaObject::activate(QObject * sender, const QMetaObject * m, int local_signal_index, void * * argv) Line 3545 + 0x1e bytes C++ QtGui4.dll!QAbstractTextDocumentLayout::documentSizeChanged(const QSizeF & _t1) Line 137 C++ QtGui4.dll!QPlainTextDocumentLayout::documentChanged(int from, int __formal, int charsAdded) Line 315 C++ QtGui4.dll!QTextDocumentPrivate::finishEdit() Line 1201 C++ QtGui4.dll!QTextDocumentPrivate::endEditBlock() Line 1180 C++ QtGui4.dll!QTextCursor::insertText(const QString & text, const QTextCharFormat & _format) Line 1463 C++ QtGui4.dll!QTextCursor::insertText(const QString & text) Line 1388 + 0x10 bytes C+
The logic of the problem is quite clear:
1. It is anticipated that GetTextMetrics() may fail (for whatever reason) and
then the QFontMetrics are zeroed.Commit: #eb39ecc in src/gui/text/qfontengine_win.cpp
(!res) { qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); ZeroMemory(&tm, sizeof(TEXTMETRIC));//this leads to linespacing 0 }
2. If this happens, QFontMetrics::lineSpacing() returns 0, and if this occurs in _q_adjustScrollbars(), the application will crash.
void QPlainTextEditPrivate::_q_adjustScrollbars() { // ... vSliderLength = viewport->height() / q->fontMetrics().lineSpacing(); // ... }