[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Bug#4109: PATCH: kcontrol/kicker dies when loading background
From:       Wolfgang Oertl <wolfgang.oertl () uibk ! ac ! at>
Date:       2000-05-26 17:55:37
[Download RAW message or body]

Package: kcontrol
Version: v2.0pre (KDE 1.90 Beta >= 20000517)
Severity: grave



Problem description
-------------------

kcmshell LookNFeel/panel: (configuration of "kicker")



How to reproduce the problem:

start with: right mouse button on kicker -> configure...
	-> Panel Settings
go to tab "Look & Feel"
enable "Use background theme"
click on "Browse"
click on "Cancel/close" w/o selecting a file (or w/entering a non-existent
	file)
---> SEGV.



Qt's Reason
-----------

QtImage::smoothScale(w,h) goes into an endless recursion when called with a
"null" image.  Of course this should be fixed too (see attached bug report
already sent to our friends at Troll Tech).



KDE's reason
------------

This is done by kdebase/kcontrol/kicker/lnftab.cpp: LnFTab::browse_theme() if
you close the KFileDialog without selecting a valid file:


void LnFTab::browse_theme()
{
  QString newtheme = KFileDialog::getOpenFileName(QString::null,
                                                  \
                KImageIO::pattern(KImageIO::Reading),
                                                  0,i18n("Select a image file"));
  if (theme == newtheme) return;

  QImage tmpImg(newtheme);
  tmpImg = tmpImg.smoothScale(theme_label->contentsRect().width(),theme_label->contentsRect().height());


  ...


As you can see, smoothScale is called even if tmpImg is a "null" image, i.e.
loading fails (eg. if "newtheme" is empty, or contains a non-existent file
name).

Fix:
1. check "newtheme" for emptiness before constructing tmpImg
2. check whether tmpImg is valid before doing anything with it:


Patch: tested and it works: on
Linux/i386 2.3.99-pre8
XFree86 3.3.6



diff -urH kdebase/kcontrol/kicker/lnftab.cpp \
                /usr/src/kde1/kdebase/kcontrol/kicker/lnftab.cpp
--- kdebase/kcontrol/kicker/lnftab.cpp	Thu May 11 17:41:52 2000
+++ /usr/src/kde1/kdebase/kcontrol/kicker/lnftab.cpp	Fri May 26 19:40:16 2000
@@ -167,19 +167,22 @@
                                                   \
                KImageIO::pattern(KImageIO::Reading),
                                                   0,i18n("Select a image file"));
   if (theme == newtheme) return;
+  if (newtheme.isEmpty()) return;
 
   QImage tmpImg(newtheme);
-  tmpImg = tmpImg.smoothScale(theme_label->contentsRect().width(),theme_label->contentsRect().height());
                
-  theme_preview.convertFromImage(tmpImg);
-  if(theme_preview.isNull()) {
-    KMessageBox::error(this, i18n("Failed to load image file."), i18n("Failed to \
                load image file."));
-    return;
+  if( !tmpImg.isNull() ) {
+    tmpImg = tmpImg.smoothScale(theme_label->contentsRect().width(),theme_label->contentsRect().height());
 +    theme_preview.convertFromImage(tmpImg);
+    if( !theme_preview.isNull() ) {
+      theme = newtheme;
+      theme_input->setText(theme);
+      theme_label->setPixmap(theme_preview);
+      emit changed();
+      return;
+    }
   }
-  
-  theme = newtheme;
-  theme_input->setText(theme);
-  theme_label->setPixmap(theme_preview);
-  emit changed();
+
+  KMessageBox::error(this, i18n("Failed to load image file."), i18n("Failed to load \
image file."));  }
 
 void LnFTab::hide_clicked()


["qimage-1" (text/plain)]

Status: sent (26-05-2000)
To: qt-bugs@trolltech.com
Subject: endless recursion in QImage::smoothScale

BUG REPORT
----------

Compiler:             gcc 2.95.2
Operating System:     Linux/i386 2.3.99-pre8
Qt library version:   2.1.0 (qt-copy in KDE's CVS tree)
Qt configure options: none
X server:             XFree86 Version 3.3.6, Release Date: January 8 1999


When this function is called with a "null" image, an endless loop ensues,
which of course runs at 100% CPU until the stack/heap is full.


Code is qt-copy/src/qimage.cpp: QImage::smoothScale(int,int):

QImage QImage::smoothScale(int w, int h) const
{
    if ( w == width() && h == height() )
	return *this; // nothing to do

    if (depth()==32) {
	QImage img(w, h, 32);
	// 32-bpp to 32-bpp
	pnmscale(*this,img);
	return img;
    } else if (allGray() && !hasAlphaBuffer()) {
	// Inefficient
	return convertDepth(32).smoothScale(w,h).convertDepth(8);
    } else {
	// Inefficient
(1)	return convertDepth(32).smoothScale(w,h);
    }
}

When the image is "null", branch (1) is selected; convertDepth returns a copy
of "*this" if called with a "null" image -> endless loop with this error
message over and over:

QImage::convertDepth: Image is a null image

Fix:
in QImage::smoothScale, check the image for validity (using isNull()) before
doing anything.

Patch as follows (this is tested and works):


diff -urH qt-copy/src/kernel/qimage.cpp /usr/src/kde1/qt-copy/src/kernel/qimage.cpp
--- qt-copy/src/kernel/qimage.cpp	Thu Apr 13 14:31:53 2000
+++ /usr/src/kde1/qt-copy/src/kernel/qimage.cpp	Fri May 26 18:35:27 2000
@@ -2190,6 +2190,13 @@
 */
 QImage QImage::smoothScale(int w, int h) const
 {
+    if ( isNull() ) {
+#if defined(CHECK_RANGE)
+	qWarning( "QImage::smoothScale: Image is a null image" );
+#endif
+	return *this;
+    }
+
     if ( w == width() && h == height() )
 	return *this; // nothing to do
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic