Compare commits

...

9 Commits

Author SHA1 Message Date
Michele Calgaro dc2dea07f7 Fixed (again) search algorithm for iconview widget. This resolves (again) bug 420.
(cherry picked from commit d27f4e2fc3)
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
10 years ago
Michele Calgaro 8eefba828f Added safety harness for currentThreadObject() usage.
currentThreadObject() returns a null pointer if the
current thread was not started using the QThread API.
This relates to bug 1748.

(cherry picked from commit dad70b4c52)
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
10 years ago
Michele Calgaro d1fd5b9b23 Fixed search algorithm for iconview widget. This resolves bug 420.
(cherry picked from commit d6867cf92e)
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
10 years ago
Slávek Banko 6b9213a69c Update buildkey for GCC 5
[taken from RedHat Qt3 patches]
(cherry picked from commit 0d96f74958)
10 years ago
Slávek Banko d3f640f17c Fix security issue CVE-2015-1860
[taken from RedHat Qt3 patches]
(cherry picked from commit 538d6a2440)
10 years ago
Slávek Banko a0008cd747 Fix security issue CVE-2015-0295
[taken from RedHat Qt3 patches]
(cherry picked from commit b3037160f2)
10 years ago
Slávek Banko 5184b53b9b Fix security issue CVE-2014-0190
[taken from RedHat Qt3 patches]
(cherry picked from commit ad74a11abf)
10 years ago
Slávek Banko 2383ee57b0 Fix security issue CVE-2013-4549
[taken from RedHat Qt3 patches]
(cherry picked from commit 73584365f8)
10 years ago
Michele Calgaro cdabaf42b0 Fixed Multicolumn view filtering item arrangement. This relates to bug 146.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>

(cherry picked from commit 9655b0b845)

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
11 years ago

4
configure vendored

@ -2810,7 +2810,7 @@ case "$COMPILER" in
g++*) g++*)
# GNU C++ # GNU C++
QMAKE_CONF_COMPILER=`grep "QMAKE_CXX[^_A-Z0-9a-z]" $QMAKESPEC/qmake.conf | sed "s,.* *= *\(.*\)$,\1,"` QMAKE_CONF_COMPILER=`grep "QMAKE_CXX[^_A-Z0-9a-z]" $QMAKESPEC/qmake.conf | sed "s,.* *= *\(.*\)$,\1,"`
COMPILER_VERSION=`${QMAKE_CONF_COMPILER} --version 2>/dev/null | sed 's,^[^0-9]*,,g'` COMPILER_VERSION=`${QMAKE_CONF_COMPILER} -dumpversion 2>/dev/null | sed 's,^[^0-9]*,,g'`
case "$COMPILER_VERSION" in case "$COMPILER_VERSION" in
2.95.*) 2.95.*)
COMPILER_VERSION="2.95.*" COMPILER_VERSION="2.95.*"
@ -2818,7 +2818,7 @@ g++*)
3.*) 3.*)
COMPILER_VERSION="3.*" COMPILER_VERSION="3.*"
;; ;;
4.*) 5.*|4.*)
COMPILER_VERSION="4.*" COMPILER_VERSION="4.*"
;; ;;
*) *)

@ -528,12 +528,7 @@ private:
DirLeft, DirLeft,
DirRight DirRight
}; };
QIconViewItem* findItem( Direction dir, QIconViewItem* findItem(Direction dir, const QIconViewItem *fromItem) const;
const QPoint &amp;relativeTo,
const QRect &amp;searchRect ) const;
bool neighbourItem( Direction dir,
const QPoint &amp;relativeTo,
const QIconViewItem *item ) const;
QBitmap mask( QPixmap *pix ) const; QBitmap mask( QPixmap *pix ) const;
QIconViewPrivate *d; QIconViewPrivate *d;

@ -287,74 +287,8 @@ public:
struct SortableItem { struct SortableItem {
QIconViewItem *item; QIconViewItem *item;
}; };
public:
/* finds the containers that intersect with \a searchRect in the direction \a dir relative to \a relativeTo */
QPtrList<ItemContainer>* findContainers(
QIconView:: Direction dir,
const QPoint &relativeTo,
const QRect &searchRect ) const;
// friend int cmpIconViewItems( const void *n1, const void *n2 );
}; };
QPtrList<QIconViewPrivate::ItemContainer>* QIconViewPrivate::findContainers(
QIconView:: Direction dir,
const QPoint &relativeTo,
const QRect &searchRect ) const
{
QPtrList<QIconViewPrivate::ItemContainer>* list =
new QPtrList<QIconViewPrivate::ItemContainer>();
if ( arrangement == QIconView::LeftToRight ) {
if ( dir == QIconView::DirLeft || dir == QIconView::DirRight ) {
ItemContainer *c = firstContainer;
for ( ; c; c = c->n )
if ( c->rect.intersects( searchRect ) )
list->append( c );
} else {
if ( dir == QIconView::DirDown ) {
ItemContainer *c = firstContainer;
for ( ; c; c = c->n )
if ( c->rect.intersects( searchRect ) &&
c->rect.bottom() >= relativeTo.y() )
list->append( c );
} else {
ItemContainer *c = lastContainer;
for ( ; c; c = c->p )
if ( c->rect.intersects( searchRect ) &&
c->rect.top() <= relativeTo.y() )
list->append( c );
}
}
} else {
if ( dir == QIconView::DirUp || dir == QIconView::DirDown ) {
ItemContainer *c = firstContainer;
for ( ; c; c = c->n )
if ( c->rect.intersects( searchRect ) )
list->append( c );
} else {
if ( dir == QIconView::DirRight ) {
ItemContainer *c = firstContainer;
for ( ; c; c = c->n )
if ( c->rect.intersects( searchRect ) &&
c->rect.right() >= relativeTo.x() )
list->append( c );
} else {
ItemContainer *c = lastContainer;
for ( ; c; c = c->p )
if ( c->rect.intersects( searchRect ) &&
c->rect.left() <= relativeTo.x() )
list->append( c );
}
}
}
return list;
}
#if defined(Q_C_CALLBACKS) #if defined(Q_C_CALLBACKS)
extern "C" { extern "C" {
#endif #endif
@ -2347,14 +2281,15 @@ void QIconViewItem::checkRect()
When an item is inserted the QIconView allocates a position for it. When an item is inserted the QIconView allocates a position for it.
Existing items are rearranged if autoArrange() is TRUE. The Existing items are rearranged if autoArrange() is TRUE. The
default arrangement is \c LeftToRight -- the QIconView fills up default arrangement is \c LeftToRight -- the QIconView fills
the \e left-most column from top to bottom, then moves one column the \e top-most row from left to right, then moves one row \e down
\e right and fills that from top to bottom and so on. The and fills that row from left to right and so on. The
arrangement can be modified with any of the following approaches: arrangement can be modified with any of the following approaches:
\list \list
\i Call setArrangement(), e.g. with \c TopToBottom which will fill \i Call setArrangement(), e.g. with \c TopToBottom which will fill up
the \e top-most row from left to right, then moves one row \e down the \e left-most column from top to bottom, then moves one column
and fills that row from left to right and so on. \e right and fills that from top to bottom and so on.
\i Construct each QIconViewItem using a constructor which allows \i Construct each QIconViewItem using a constructor which allows
you to specify which item the new one is to follow. you to specify which item the new one is to follow.
\i Call setSorting() or sort() to sort the items. \i Call setSorting() or sort() to sort the items.
@ -5105,6 +5040,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
} }
} break; } break;
#endif #endif
case Key_Home: { case Key_Home: {
d->currInputString = QString::null; d->currInputString = QString::null;
if ( !d->firstItem ) if ( !d->firstItem )
@ -5149,6 +5085,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
e->state() & ControlButton, TRUE ); e->state() & ControlButton, TRUE );
} }
} break; } break;
case Key_End: { case Key_End: {
d->currInputString = QString::null; d->currInputString = QString::null;
if ( !d->lastItem ) if ( !d->lastItem )
@ -5192,50 +5129,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
e->state() & ControlButton, TRUE ); e->state() & ControlButton, TRUE );
} }
} break; } break;
case Key_Right: {
d->currInputString = QString::null;
QIconViewItem *item;
selectCurrent = FALSE;
Direction dir = DirRight;
QRect r( 0, d->currentItem->y(), contentsWidth(), d->currentItem->height() );
item = findItem( dir, d->currentItem->rect().center(), r );
// search the row below from the right
while ( !item && r.y() < contentsHeight() ) {
r.moveBy(0, d->currentItem->height() );
item = findItem( dir, QPoint( 0, r.center().y() ), r );
}
if ( item ) {
QIconViewItem *old = d->currentItem;
setCurrentItem( item );
ensureItemVisible( item );
handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
}
} break;
case Key_Left: {
d->currInputString = QString::null;
QIconViewItem *item;
selectCurrent = FALSE;
Direction dir = DirLeft;
QRect r( 0, d->currentItem->y(), contentsWidth(), d->currentItem->height() );
item = findItem( dir, d->currentItem->rect().center(), r );
// search the row above from the left
while ( !item && r.y() >= 0 ) {
r.moveBy(0, - d->currentItem->height() );
item = findItem( dir, QPoint( contentsWidth(), r.center().y() ), r );
}
if ( item ) {
QIconViewItem *old = d->currentItem;
setCurrentItem( item );
ensureItemVisible( item );
handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
}
} break;
case Key_Space: { case Key_Space: {
d->currInputString = QString::null; d->currInputString = QString::null;
if ( d->selectionMode == Single) if ( d->selectionMode == Single)
@ -5243,51 +5137,65 @@ void QIconView::keyPressEvent( QKeyEvent *e )
d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE ); d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE );
} break; } break;
case Key_Enter: case Key_Return:
case Key_Enter:
case Key_Return:
d->currInputString = QString::null; d->currInputString = QString::null;
emit returnPressed( d->currentItem ); emit returnPressed( d->currentItem );
break; break;
case Key_Down: {
case Key_Right: {
d->currInputString = QString::null; d->currInputString = QString::null;
QIconViewItem *item;
selectCurrent = FALSE; selectCurrent = FALSE;
Direction dir = DirDown; Direction dir = DirRight;
QIconViewItem *item = findItem(dir, d->currentItem);
QRect r( d->currentItem->x(), 0, d->currentItem->width(), contentsHeight() ); if (item) {
item = findItem( dir, d->currentItem->rect().center(), r ); QIconViewItem *old=d->currentItem;
setCurrentItem(item);
// finding the closest item below and to the right ensureItemVisible(item);
while ( !item && r.x() < contentsWidth() ) { handleItemChange(old, e->state() & ShiftButton, e->state() & ControlButton );
r.moveBy( r.width() , 0 ); }
item = findItem( dir, QPoint( r.center().x(), 0 ), r ); } break;
}
case Key_Left: {
d->currInputString = QString::null;
selectCurrent = FALSE;
Direction dir = DirLeft;
QIconViewItem *item = findItem(dir, d->currentItem);
if (item) {
QIconViewItem *old=d->currentItem;
setCurrentItem(item);
ensureItemVisible(item);
handleItemChange(old, e->state() & ShiftButton, e->state() & ControlButton );
}
} break;
QIconViewItem *i = d->currentItem; case Key_Down: {
setCurrentItem( item ); d->currInputString = QString::null;
item = i; selectCurrent = FALSE;
handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton ); Direction dir = DirDown;
QIconViewItem *item = findItem(dir, d->currentItem);
if (item) {
QIconViewItem *old=d->currentItem;
setCurrentItem(item);
ensureItemVisible(item);
handleItemChange(old, e->state() & ShiftButton, e->state() & ControlButton );
}
} break; } break;
case Key_Up: { case Key_Up: {
d->currInputString = QString::null; d->currInputString = QString::null;
QIconViewItem *item;
selectCurrent = FALSE; selectCurrent = FALSE;
Direction dir = DirUp; Direction dir = DirUp;
QIconViewItem *item = findItem(dir, d->currentItem);
QRect r( d->currentItem->x(), 0, d->currentItem->width(), contentsHeight() ); if (item) {
item = findItem( dir, d->currentItem->rect().center(), r ); QIconViewItem *old=d->currentItem;
setCurrentItem(item);
// finding the closest item above and to the left ensureItemVisible(item);
while ( !item && r.x() >= 0 ) { handleItemChange(old, e->state() & ShiftButton, e->state() & ControlButton );
r.moveBy(- r.width(), 0 ); }
item = findItem( dir, QPoint(r.center().x(), contentsHeight() ), r );
}
QIconViewItem *i = d->currentItem;
setCurrentItem( item );
item = i;
handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
} break; } break;
case Key_Next: { case Key_Next: {
d->currInputString = QString::null; d->currInputString = QString::null;
selectCurrent = FALSE; selectCurrent = FALSE;
@ -5310,6 +5218,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton ); handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
} }
} break; } break;
case Key_Prior: { case Key_Prior: {
d->currInputString = QString::null; d->currInputString = QString::null;
selectCurrent = FALSE; selectCurrent = FALSE;
@ -5332,6 +5241,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton ); handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
} }
} break; } break;
default: default:
if ( !e->text().isEmpty() && e->text()[ 0 ].isPrint() ) { if ( !e->text().isEmpty() && e->text()[ 0 ].isPrint() ) {
selectCurrent = FALSE; selectCurrent = FALSE;
@ -5402,79 +5312,193 @@ void QIconView::keyPressEvent( QKeyEvent *e )
} }
/* /*
Finds the closest item in the Direction \a dir relative from the point \a relativeTo Finds the closest item in the direction \a dir starting from the specified \a fromItem.
which intersects with the searchRect. If the arrangement is LeftToRight (icon view mode): use (center, top) as item reference
If the arrangement is TopToBottom (multicolumn view mode): use (left, top) as item reference
The function choses the closest item with its center in the searchRect. This is to allow for smooth scrolling when using the keyboard arrow keys.
*/ */
QIconViewItem* QIconView::findItem( Direction dir, QIconViewItem* QIconView::findItem(Direction dir, const QIconViewItem *fromItem) const
const QPoint &relativeTo, {
const QRect &searchRect ) const QIconViewItem *closestItem=NULL;
{ int distPri=0, distSec=0;
QIconViewItem *item; int itemDistancePri=0, itemDistanceSec=0;
QIconViewItem *centerMatch = 0;
int centerMatchML = 0; QPoint pos=fromItem->rect().topLeft();
if (d->arrangement == LeftToRight) {
// gets list of containers with potential items pos.setX(fromItem->rect().center().x());
QPtrList<QIconViewPrivate::ItemContainer>* cList = }
d->findContainers( dir, relativeTo, searchRect);
QRect searchRect;
cList->first(); switch (dir) {
while ( cList->current() && !centerMatch ) { case DirDown:
QPtrList<QIconViewItem> &list = (cList->current())->items; searchRect.setCoords(pos.x(), 0, contentsWidth(), contentsHeight());
for ( item = list.first(); item; item = list.next() ) { break;
if ( neighbourItem( dir, relativeTo, item ) &&
searchRect.contains( item->rect().center() ) && case DirUp:
item != currentItem() ) { searchRect.setCoords(0, 0, pos.x(), contentsHeight());
int ml = (relativeTo - item->rect().center()).manhattanLength(); break;
if ( centerMatch ) {
if ( ml < centerMatchML ) { case DirRight:
centerMatch = item; searchRect.setCoords(0, pos.y(), contentsWidth(), contentsHeight());
centerMatchML = ml; break;
}
} else { case DirLeft:
centerMatch = item; searchRect.setCoords(0, 0, contentsWidth(), pos.y());
centerMatchML = ml; break;
} }
}
} for (QIconViewPrivate::ItemContainer *c=d->firstContainer; c; c=c->n) {
cList->next(); if (c->rect.intersects(searchRect)) {
} QPtrList<QIconViewItem> &list = c->items;
delete cList; for (QIconViewItem *item=list.first(); item; item=list.next()) {
return centerMatch; if (item != fromItem) {
} bool itemOK = true;
const QRect &ir = item->rect();
// DirDown/DirUp : primary distance X, secondary distance Y
/* // DirLeft/DirRight: primary distance Y, secondary distance X
Returns TRUE if the items orientation compared to if (d->arrangement == LeftToRight) {
the point \a relativeTo is correct. // Left to right arrangement (icon view mode): use (center, top) as item reference
*/ switch (dir) {
bool QIconView::neighbourItem( Direction dir, case DirDown:
const QPoint &relativeTo, if (ir.center().x() > pos.x()) {
const QIconViewItem *item ) const distPri = ir.center().x()-pos.x();
{ distSec = ir.top();
switch ( dir ) { }
case DirUp: else if (ir.center().x() == pos.x() && ir.top() > pos.y()) {
if ( item->rect().center().y() < relativeTo.y() ) distPri = 0;
return TRUE; distSec = ir.top()-pos.y();
break; }
case DirDown: else {
if ( item->rect().center().y() > relativeTo.y() ) itemOK = false;
return TRUE; }
break; break;
case DirLeft:
if ( item->rect().center().x() < relativeTo.x() ) case DirUp:
return TRUE; if (ir.center().x() < pos.x()) {
break; distPri = pos.x()-ir.center().x();
case DirRight: distSec = contentsHeight()-ir.top();
if ( item->rect().center().x() > relativeTo.x() ) }
return TRUE; else if (ir.center().x() == pos.x() && ir.top() < pos.y()) {
break; distPri = 0;
default: distSec = pos.y()-ir.top();
// nothing }
break; else {
itemOK = false;
}
break;
case DirRight:
if (ir.top() > pos.y()) {
distPri = ir.top()-pos.y();
distSec = ir.center().x();
}
else if (ir.top() == pos.y() && ir.center().x() > pos.x()) {
distPri = 0;
distSec = ir.center().x()-pos.x();
}
else {
itemOK = false;
}
break;
case DirLeft:
if (ir.top() < pos.y()) {
distPri = pos.y()-ir.top();
distSec = contentsWidth()-ir.center().x();
}
else if (ir.top() == pos.y() && ir.center().x() < pos.x()) {
distPri = 0;
distSec = pos.x()-ir.center().x();
}
else {
itemOK = false;
}
break;
default:
itemOK = false;
break;
}
}
else {
// Top to bottom arrangement (multicolumn view mode): use (left, top) as item reference
switch (dir) {
case DirDown:
if (ir.left() > pos.x()) {
distPri = ir.left()-pos.x();
distSec = ir.top();
}
else if (ir.left() == pos.x() && ir.top() > pos.y()) {
distPri = 0;
distSec = ir.top()-pos.y();
}
else {
itemOK = false;
}
break;
case DirUp:
if (ir.left() < pos.x()) {
distPri = pos.x()-ir.left();
distSec = contentsHeight()-ir.top();
}
else if (ir.left() == pos.x() && ir.top() < pos.y()) {
distPri = 0;
distSec = pos.y()-ir.top();
}
else {
itemOK = false;
}
break;
case DirRight:
if (ir.top() > pos.y()) {
distPri = ir.top()-pos.y();
distSec = ir.left();
}
else if (ir.top() == pos.y() && ir.left() > pos.x()) {
distPri = 0;
distSec = ir.left()-pos.x();
}
else {
itemOK = false;
}
break;
case DirLeft:
if (ir.top() < pos.y()) {
distPri = pos.y()-ir.top();
distSec = contentsWidth()-ir.left();
}
else if (ir.top() == pos.y() && ir.left() < pos.x()) {
distPri = 0;
distSec = pos.x()-ir.left();
}
else {
itemOK = false;
}
break;
default:
itemOK = false;
break;
}
}
if (itemOK) {
if (!closestItem ||
((distPri < itemDistancePri) ||
(distPri == itemDistancePri && distSec < itemDistanceSec))) {
closestItem = item;
itemDistancePri = distPri;
itemDistanceSec = distSec;
}
}
}
}
}
} }
return FALSE; return closestItem;
} }
/*! /*!
@ -6040,7 +6064,7 @@ QIconViewItem *QIconView::makeRowLayout( QIconViewItem *begin, int &y, bool &cha
} }
} else { // -------------------------------- SOUTH ------------------------------ } else { // -------------------------------- TopToBottom ------------------------------
int x = y; int x = y;
@ -6075,6 +6099,7 @@ QIconViewItem *QIconView::makeRowLayout( QIconViewItem *begin, int &y, bool &cha
// now move the items // now move the items
item = begin; item = begin;
QIconViewItem *prevVisibleItem = NULL;
for (;;) { for (;;) {
item->dirty = FALSE; item->dirty = FALSE;
if ( d->itemTextPos == Bottom ) { if ( d->itemTextPos == Bottom ) {
@ -6082,15 +6107,16 @@ QIconViewItem *QIconView::makeRowLayout( QIconViewItem *begin, int &y, bool &cha
changed = item->move( x + ( w - item->width() ) / 2, d->spacing ) || changed; changed = item->move( x + ( w - item->width() ) / 2, d->spacing ) || changed;
else else
changed = item->move( x + ( w - item->width() ) / 2, changed = item->move( x + ( w - item->width() ) / 2,
item->prev->y() + item->prev->height() + d->spacing ) || changed; prevVisibleItem->y() + prevVisibleItem->height() + d->spacing ) || changed;
} else { } else {
if ( item == begin ) if ( item == begin )
changed = item->move( x, d->spacing ) || changed; changed = item->move( x, d->spacing ) || changed;
else else
changed = item->move( x, item->prev->y() + item->prev->height() + d->spacing ) || changed; changed = item->move( x, prevVisibleItem->y() + prevVisibleItem->height() + d->spacing ) || changed;
} }
if ( item == end ) if ( item == end )
break; break;
prevVisibleItem = item;
item = item->next; item = item->next;
while (item && (item->isVisible() == FALSE)) { while (item && (item->isVisible() == FALSE)) {
item = item->next; item = item->next;

@ -497,12 +497,7 @@ private:
DirLeft, DirLeft,
DirRight DirRight
}; };
QIconViewItem* findItem( Direction dir, QIconViewItem* findItem(Direction dir, const QIconViewItem *fromItem) const;
const QPoint &relativeTo,
const QRect &searchRect ) const;
bool neighbourItem( Direction dir,
const QPoint &relativeTo,
const QIconViewItem *item ) const;
QBitmap mask( QPixmap *pix ) const; QBitmap mask( QPixmap *pix ) const;
int visibleWidthSB() const; int visibleWidthSB() const;
int visibleHeightSB() const; int visibleHeightSB() const;

@ -904,7 +904,12 @@ int QGIFFormat::decode(QImage& img, QImageConsumer* consumer,
sheight = newtop + newheight; sheight = newtop + newheight;
if (img.isNull()) { if (img.isNull()) {
img.create(swidth, sheight, 32); if (!img.create(swidth, sheight, 32)) {
// Check if the attempt to create the image failed. If
// it did, the image is broken and we should give up.
state = Error;
return -1;
}
memset( img.bits(), 0, img.numBytes() ); memset( img.bits(), 0, img.numBytes() );
if (consumer) consumer->setSize(swidth, sheight); if (consumer) consumer->setSize(swidth, sheight);
} }
@ -1221,6 +1226,8 @@ void QGIFFormat::fillRect(QImage& img, int col, int row, int w, int h, QRgb colo
void QGIFFormat::nextY(QImage& img, QImageConsumer* consumer) void QGIFFormat::nextY(QImage& img, QImageConsumer* consumer)
{ {
if (out_of_bounds)
return;
int my; int my;
switch (interlace) { switch (interlace) {
case 0: case 0:

@ -688,7 +688,9 @@ int QEventLoop::activateTimers()
QTimerEvent e( t->id ); QTimerEvent e( t->id );
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
// Be careful...the current thread may not be the target object's thread! // Be careful...the current thread may not be the target object's thread!
if ((!t->obj) || (QThread::currentThreadObject()->threadPostedEventsDisabled()) || (t->obj && (t->obj->contextThreadObject() == QThread::currentThreadObject()))) { if ((!t->obj) ||
(QThread::currentThreadObject() && QThread::currentThreadObject()->threadPostedEventsDisabled()) ||
(t->obj && t->obj->contextThreadObject() == QThread::currentThreadObject())) {
QApplication::sendEvent( t->obj, &e ); // send event QApplication::sendEvent( t->obj, &e ); // send event
} }
else { else {
@ -731,7 +733,9 @@ int QEventLoop::activateSocketNotifiers()
sn->pending = FALSE; sn->pending = FALSE;
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
// Be careful...the current thread may not be the target object's thread! // Be careful...the current thread may not be the target object's thread!
if ((!sn->obj) || (QThread::currentThreadObject()->threadPostedEventsDisabled()) || (sn->obj && (sn->obj->contextThreadObject() == QThread::currentThreadObject()))) { if ((!sn->obj) ||
(QThread::currentThreadObject() && QThread::currentThreadObject()->threadPostedEventsDisabled()) ||
(sn->obj && sn->obj->contextThreadObject() == QThread::currentThreadObject())) {
QApplication::sendEvent( sn->obj, &event ); // send event QApplication::sendEvent( sn->obj, &event ); // send event
} }
else { else {

@ -4716,10 +4716,16 @@ bool read_dib( QDataStream& s, int offset, int startpos, QImage& image )
if ( (Q_ULONG)d->readBlock( (char *)&blue_mask, sizeof(blue_mask) ) != sizeof(blue_mask) ) if ( (Q_ULONG)d->readBlock( (char *)&blue_mask, sizeof(blue_mask) ) != sizeof(blue_mask) )
return FALSE; return FALSE;
red_shift = calc_shift(red_mask); red_shift = calc_shift(red_mask);
if (((red_mask >> red_shift) + 1) == 0)
return FALSE;
red_scale = 256 / ((red_mask >> red_shift) + 1); red_scale = 256 / ((red_mask >> red_shift) + 1);
green_shift = calc_shift(green_mask); green_shift = calc_shift(green_mask);
if (((green_mask >> green_shift) + 1) == 0)
return FALSE;
green_scale = 256 / ((green_mask >> green_shift) + 1); green_scale = 256 / ((green_mask >> green_shift) + 1);
blue_shift = calc_shift(blue_mask); blue_shift = calc_shift(blue_mask);
if (((blue_mask >> blue_shift) + 1) == 0)
return FALSE;
blue_scale = 256 / ((blue_mask >> blue_shift) + 1); blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
} else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) { } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
blue_mask = 0x000000ff; blue_mask = 0x000000ff;

@ -203,9 +203,10 @@ void QObject::moveToThread(QThread *targetThread)
} }
QThread *objectThread = contextThreadObject(); QThread *objectThread = contextThreadObject();
// NOTE currentThread could be NULL if the current thread was not started using the QThread API
QThread *currentThread = QThread::currentThreadObject(); QThread *currentThread = QThread::currentThreadObject();
if (objectThread != currentThread) { if (currentThread && objectThread != currentThread) {
#if defined(QT_DEBUG) #if defined(QT_DEBUG)
qWarning( "QObject::moveToThread: Current thread is not the object's thread" ); qWarning( "QObject::moveToThread: Current thread is not the object's thread" );
#endif #endif
@ -2760,6 +2761,7 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
} }
#endif #endif
// NOTE currentThread could be NULL if the current thread was not started using the QThread API
const QThread *currentThread = QThread::currentThreadObject(); const QThread *currentThread = QThread::currentThreadObject();
QObject *object; QObject *object;
@ -2779,7 +2781,10 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
sol->currentSender = this; sol->currentSender = this;
} }
if ( c->memberType() == QSIGNAL_CODE ) { if ( c->memberType() == QSIGNAL_CODE ) {
if ((d->disableThreadPostedEvents) || (object->d->disableThreadPostedEvents) || (currentThread->threadPostedEventsDisabled()) || (object->d->ownThread == currentThread)) { if ((d->disableThreadPostedEvents) ||
(object->d->disableThreadPostedEvents) ||
(currentThread && currentThread->threadPostedEventsDisabled()) ||
(currentThread && object->d->ownThread == currentThread)) {
#ifdef QT_THREAD_SUPPORT #ifdef QT_THREAD_SUPPORT
sol->listMutex->unlock(); sol->listMutex->unlock();
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT
@ -2798,7 +2803,10 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
} }
} }
else { else {
if ((d->disableThreadPostedEvents) || (object->d->disableThreadPostedEvents) || (currentThread->threadPostedEventsDisabled()) || (object->d->ownThread == currentThread)) { if ((d->disableThreadPostedEvents) ||
(object->d->disableThreadPostedEvents) ||
(currentThread && currentThread->threadPostedEventsDisabled()) ||
(currentThread && object->d->ownThread == currentThread)) {
#ifdef QT_THREAD_SUPPORT #ifdef QT_THREAD_SUPPORT
sol->listMutex->unlock(); sol->listMutex->unlock();
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT
@ -2846,7 +2854,10 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
sol->currentSender = this; sol->currentSender = this;
} }
if ( c->memberType() == QSIGNAL_CODE ) { if ( c->memberType() == QSIGNAL_CODE ) {
if ((d->disableThreadPostedEvents) || (object->d->disableThreadPostedEvents) || (currentThread->threadPostedEventsDisabled()) || (object->d->ownThread == currentThread)) { if ((d->disableThreadPostedEvents) ||
(object->d->disableThreadPostedEvents) ||
(currentThread && currentThread->threadPostedEventsDisabled()) ||
(currentThread && object->d->ownThread == currentThread)) {
#ifdef QT_THREAD_SUPPORT #ifdef QT_THREAD_SUPPORT
sol->listMutex->unlock(); sol->listMutex->unlock();
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT
@ -2865,7 +2876,10 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
} }
} }
else { else {
if ((d->disableThreadPostedEvents) || (object->d->disableThreadPostedEvents) || (currentThread->threadPostedEventsDisabled()) || (object->d->ownThread == currentThread)) { if ((d->disableThreadPostedEvents) ||
(object->d->disableThreadPostedEvents) ||
(currentThread && currentThread->threadPostedEventsDisabled()) ||
(currentThread && object->d->ownThread == currentThread)) {
#ifdef QT_THREAD_SUPPORT #ifdef QT_THREAD_SUPPORT
sol->listMutex->unlock(); sol->listMutex->unlock();
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT

@ -4529,6 +4529,11 @@ bool QXmlSimpleReader::parseDoctype()
} }
break; break;
case Mup: case Mup:
if (dtdRecursionLimit > 0U && d->parameterEntities.size() > dtdRecursionLimit) {
reportParseError(QString::fromLatin1(
"DTD parsing exceeded recursion limit of %1.").arg(dtdRecursionLimit));
return FALSE;
}
if ( !parseMarkupdecl() ) { if ( !parseMarkupdecl() ) {
parseFailed( &QXmlSimpleReader::parseDoctype, state ); parseFailed( &QXmlSimpleReader::parseDoctype, state );
return FALSE; return FALSE;
@ -6128,6 +6133,58 @@ bool QXmlSimpleReader::parseChoiceSeq()
} }
} }
bool QXmlSimpleReader::isExpandedEntityValueTooLarge(QString *errorMessage)
{
QMap<QString, uint> literalEntitySizes;
// The entity at (QMap<QString,) referenced the entities at (QMap<QString,) (uint>) times.
QMap<QString, QMap<QString, uint> > referencesToOtherEntities;
QMap<QString, uint> expandedSizes;
// For every entity, check how many times all entity names were referenced in its value.
QMap<QString,QString>::ConstIterator toSearchIterator;
for (toSearchIterator = d->entities.begin(); toSearchIterator != d->entities.end(); ++toSearchIterator) {
QString toSearch = toSearchIterator.key();
// The amount of characters that weren't entity names, but literals, like 'X'.
QString leftOvers = toSearchIterator.data();
QMap<QString,QString>::ConstIterator entityNameIterator;
// How many times was entityName referenced by toSearch?
for (entityNameIterator = d->entities.begin(); entityNameIterator != d->entities.end(); ++entityNameIterator) {
QString entityName = entityNameIterator.key();
for (int i = 0; i >= 0 && (uint) i < leftOvers.length(); ) {
i = leftOvers.find(QString::fromLatin1("&%1;").arg(entityName), i);
if (i != -1) {
leftOvers.remove(i, entityName.length() + 2U);
// The entityName we're currently trying to find was matched in this string; increase our count.
++referencesToOtherEntities[toSearch][entityName];
}
}
}
literalEntitySizes[toSearch] = leftOvers.length();
}
QMap<QString, QMap<QString, uint> >::ConstIterator entityIterator;
for (entityIterator = referencesToOtherEntities.begin(); entityIterator != referencesToOtherEntities.end(); ++entityIterator) {
QString entity = entityIterator.key();
expandedSizes[entity] = literalEntitySizes[entity];
QMap<QString, uint>::ConstIterator referenceToIterator;
for (referenceToIterator = entityIterator.data().begin(); referenceToIterator != entityIterator.data().end(); ++referenceToIterator) {
QString referenceTo = referenceToIterator.key();
const uint references = referenceToIterator.data();
// The total size of an entity's value is the expanded size of all of its referenced entities, plus its literal size.
expandedSizes[entity] += expandedSizes[referenceTo] * references + literalEntitySizes[referenceTo] * references;
}
if (expandedSizes[entity] > entityCharacterLimit) {
if (errorMessage) {
*errorMessage = QString::fromLatin1("The XML entity \"%1\" expands to a string that is too large to process (%2 characters > %3).");
*errorMessage = (*errorMessage).arg(entity).arg(expandedSizes[entity]).arg(entityCharacterLimit);
}
return TRUE;
}
}
return FALSE;
}
/* /*
Parse a EntityDecl [70]. Parse a EntityDecl [70].
@ -6222,6 +6279,12 @@ bool QXmlSimpleReader::parseEntityDecl()
switch ( state ) { switch ( state ) {
case EValue: case EValue:
if ( !entityExist( name() ) ) { if ( !entityExist( name() ) ) {
QString errorMessage;
if (isExpandedEntityValueTooLarge(&errorMessage)) {
reportParseError(errorMessage);
return FALSE;
}
d->entities.insert( name(), string() ); d->entities.insert( name(), string() );
if ( declHnd ) { if ( declHnd ) {
if ( !declHnd->internalEntityDecl( name(), string() ) ) { if ( !declHnd->internalEntityDecl( name(), string() ) ) {

@ -307,6 +307,12 @@ private:
QXmlSimpleReaderPrivate* d; QXmlSimpleReaderPrivate* d;
// The limit to the amount of times the DTD parsing functions can be called
// for the DTD currently being parsed.
static const uint dtdRecursionLimit = 2U;
// The maximum amount of characters an entity value may contain, after expansion.
static const uint entityCharacterLimit = 65536U;
const QString &string(); const QString &string();
void stringClear(); void stringClear();
inline void stringAddC() { stringAddC(c); } inline void stringAddC() { stringAddC(c); }
@ -378,6 +384,7 @@ private:
void unexpectedEof( ParseFunction where, int state ); void unexpectedEof( ParseFunction where, int state );
void parseFailed( ParseFunction where, int state ); void parseFailed( ParseFunction where, int state );
void pushParseState( ParseFunction function, int state ); void pushParseState( ParseFunction function, int state );
bool isExpandedEntityValueTooLarge(QString *errorMessage);
void setUndefEntityInAttrHack(bool b); void setUndefEntityInAttrHack(bool b);

Loading…
Cancel
Save