Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-24710

CRASH: QMacPixmapData does not check if memory allocation but copies data

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 4.8.3
    • 4.8.0
    • Image formats
    • None
    • 3b7edefb5b8a3dd6b1b53af4039cf1a862cd0aed

    Description

      Code to reproduce

          for(;;)
          {
              qDebug() << "allocating....";
              QPixmap* testPixmap = new QPixmap(10000,10000);
              QImage testImage2(10000,10000, QImage::Format_RGB32);
              testPixmap->convertFromImage( testImage2 );
          }
      

      Remark: In contrast to https://bugreports.qt-project.org/browse/QTBUG-24709 this bug is forcing a waste of memory leading to the crash.

      0   libsystem_c.dylib             	0x936d1a57 memmove$VARIANT$sse42 + 154
      1   QtGui                         	0x034df3ab QMacPixmapData::resize(int, int) + 211
      2   QtGui                         	0x034df7a5 QMacPixmapData::fromImage(QImage const&, QFlags<Qt::ImageConversionFlag>) + 1003
      3   QtGui                         	0x034cc00e QPixmap::convertFromImage(QImage const&, QFlags<Qt::ImageConversionFlag>) + 62
      4   de.code-and-web.TexturePacker 	0x0016bea1 guiMode(int, char**) + 961 (main.cpp:518)
      5   de.code-and-web.TexturePacker 	0x00177972 main + 226 (main.cpp:1132)
      6   de.code-and-web.TexturePacker 	0x000fae45 start + 53
      
      void QMacPixmapData::macCreatePixels()
      {
          const int numBytes = bytesPerRow * h;
          quint32 *base_pixels;
          if (pixelsToFree && pixelsToFree != pixels) {
              // Reuse unused block of memory lying around from a previous callback.
              base_pixels = pixelsToFree;                                         // Does this really have the right size????
              pixelsToFree = 0;
          } else {
              // We need a block of memory to do stuff with.
              base_pixels = static_cast<quint32 *>(malloc(numBytes));             // allocatio, no check
          }
      
          if (pixels)
              memcpy(base_pixels, pixels, qMin(pixelsSize, (uint) numBytes));     // just copy them over, no check for target size
                                                                                  // no check if memory was allocated at all
          pixels = base_pixels;
          pixelsSize = numBytes;
      }
      

      This complete code block is quite buggy in my opinion.

      Who tells us that the block we want to re-use from pixelsToFree has the right size for this operation?

      The bigger problem is that the memory is simply memcpy'ed without ever checking if the allocation was ok.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            andysh Andy Shaw
            andreasloew Andreas Loew
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes