Skip to content

Commit

Permalink
Fix crash in TextInput.
Browse files Browse the repository at this point in the history
Ensure the text is laid out before calling componentComplete() on
QImplicitSizeItem, as that can potentially evaluate bindings which
would then access the uninitialized layout.

Change-Id: I5152c1494c54209dae61c13b2f45d343fb76bf9e
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
  • Loading branch information
Andrew den Exter authored and Qt by Nokia committed Jan 4, 2012
1 parent be72fb2 commit 8bd497a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/quick/items/qquicktextinput.cpp
Expand Up @@ -1412,13 +1412,14 @@ void QQuickTextInputPrivate::updateHorizontalScroll()
Q_Q(QQuickTextInput);
QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + m_preeditCursor);
const int preeditLength = m_textLayout.preeditAreaText().length();
const int width = q->width();
const int width = qMax(0, qFloor(q->width()));
int widthUsed = currentLine.isValid() ? qRound(currentLine.naturalTextWidth()) : 0;
int previousScroll = hscroll;

if (!autoScroll || widthUsed <= width || m_echoMode == QQuickTextInput::NoEcho) {
hscroll = 0;
} else {
Q_ASSERT(currentLine.isValid());
int cix = qRound(currentLine.cursorToX(m_cursor + preeditLength));
if (cix - hscroll >= width) {
// text doesn't fit, cursor is to the right of br (scroll right)
Expand Down Expand Up @@ -1447,7 +1448,7 @@ void QQuickTextInputPrivate::updateVerticalScroll()
{
Q_Q(QQuickTextInput);
const int preeditLength = m_textLayout.preeditAreaText().length();
const int height = q->height();
const int height = qMax(0, qFloor(q->height()));
int heightUsed = boundingRect.height();
int previousScroll = vscroll;

Expand All @@ -1466,7 +1467,8 @@ void QQuickTextInputPrivate::updateVerticalScroll()
break;
}
} else {
QRectF r = m_textLayout.lineForTextPosition(m_cursor + preeditLength).rect();
QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + preeditLength);
QRectF r = currentLine.isValid() ? currentLine.rect() : QRectF();
int top = qFloor(r.top());
int bottom = qCeil(r.bottom());

Expand All @@ -1484,10 +1486,10 @@ void QQuickTextInputPrivate::updateVerticalScroll()
if (preeditLength > 0) {
// check to ensure long pre-edit text doesn't push the cursor
// off the top
top = qRound(m_textLayout.lineForTextPosition(
m_cursor + qMax(0, m_preeditCursor - 1)).rect().top());
if (top < vscroll)
vscroll = top;
currentLine = m_textLayout.lineForTextPosition(m_cursor + qMax(0, m_preeditCursor - 1));
top = currentLine.isValid() ? qRound(currentLine.rect().top()) : 0;
if (top < vscroll)
vscroll = top;
}
}
if (previousScroll != vscroll)
Expand Down
19 changes: 19 additions & 0 deletions tests/auto/qtquick2/qquicktextinput/data/negativeDimensions.qml
@@ -0,0 +1,19 @@
import QtQuick 2.0

Item {
TextInput {
objectName: "input"

focus: true
width: -1
height: -1
text: "sushi"

anchors {
left: parent.left;
leftMargin: 5
top: parent.top
topMargin: font.pixelSize
}
}
}
15 changes: 15 additions & 0 deletions tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
Expand Up @@ -176,6 +176,8 @@ private slots:
void QTBUG_19956_data();
void QTBUG_19956_regexp();

void negativeDimensions();

private:
void simulateKey(QQuickView *, int key);

Expand Down Expand Up @@ -3390,6 +3392,19 @@ void tst_qquicktextinput::QTBUG_19956_regexp()
QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
}


void tst_qquicktextinput::negativeDimensions()
{
// Verify this doesn't assert during initialization.
QDeclarativeComponent component(&engine, testFileUrl("negativeDimensions.qml"));
QScopedPointer<QObject> o(component.create());
QVERIFY(o);
QQuickTextInput *input = o->findChild<QQuickTextInput *>("input");
QVERIFY(input);
QCOMPARE(input->width(), qreal(-1));
QCOMPARE(input->height(), qreal(-1));
}

QTEST_MAIN(tst_qquicktextinput)

#include "tst_qquicktextinput.moc"

0 comments on commit 8bd497a

Please sign in to comment.