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

Crash on convertIndexedToARGB32PM

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P1: Critical
    • Resolution: Done
    • Affects Version/s: 5.6.2
    • Fix Version/s: 5.6.3, 5.9.0 Beta 1
    • Component/s: Image formats
    • Labels:
      None
    • Environment:
      QT 5.6.2 32 bits on Windows 10

      Description

      One of our customers has contacted us reporting a crash managing a XPM file (attached).

      The code that crashes tries to save the image in JPG format to a QBuffer, setting a white background to not have the transparent pixels black in the final image.

      Here is a minimal example code that crashes with the attached image.

      #include <QImageReader>
      #include <QImage>
      #include <QPainter>
      #include <QBuffer>
      #include <QByteArray>
      #include <iostream>
      
      int main(int argc, char *argv[])
      {
          QImageReader imageReader("image.xpm");
          QImage result = imageReader.read();
          if (result.isNull())
          {
              std::cerr << "Image not found" << std::endl;
              return 0;
          }
      
          QImage finalImage(result.size(), QImage::Format_RGB32);
          finalImage.fill(QColor(Qt::white).rgb());
          QPainter painter(&finalImage);
          painter.drawImage(0, 0, result);
      
          QByteArray ba;
          QBuffer buffer(&ba);
          buffer.open(QIODevice::WriteOnly);
          finalImage.save(&buffer, "JPG", 85);
          return 0;
      }
      

      This is the stacktrace:

      1  convertIndexedToARGB32PM               qdrawhelper.cpp         411  0x588763f2 
      2  fetchUntransformed                     qdrawhelper.cpp         1428 0x5887baa6 
      3  blend_untransformed_generic            qdrawhelper.cpp         4165 0x5888e4ac 
      4  qBlendTexture                          qdrawhelper.cpp         5494 0x588756cc 
      5  fillRect_normalized                    qpaintengine_raster.cpp 1441 0x588d268e 
      6  QRasterPaintEngine::drawImage          qpaintengine_raster.cpp 2138 0x588c8ccc 
      7  QPainter::drawImage                    qpainter.cpp            5363 0x588e6ad7 
      8  QPainter::drawImage                    qpainter.h              852  0x585b16ed 
      9  main                                   main.cpp                24   0x27151d   
      10 invoke_main                            exe_common.inl          64   0x27238e   
      11 __scrt_common_main_seh                 exe_common.inl          255  0x2721da   
      12 __scrt_common_main                     exe_common.inl          300  0x27206d   
      13 mainCRTStartup                         exe_main.cpp            17   0x2723a8   
      14 BaseThreadInitThunk                    KERNEL32                     0x74b362c4 
      15 RtlSubscribeWnfStateChangeNotification ntdll                        0x77b40fd9 
      16 RtlSubscribeWnfStateChangeNotification ntdll                        0x77b40fa4 
      

      The crash happens here:

      qdrawhelper.cpp:407
      // To convert in place, let 'dest' and 'src' be the same.
      static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count,
                                                              const QPixelLayout *, const QRgb *clut)
      {
          for (int i = 0; i < count; ++i)
              buffer[i] = qPremultiply(clut[src[i]]); /// <------ crash!
          return buffer;
      }
      

      According to the debugger, "clut" is NULL.

      In the calling function, it's clear that that parameter can be NULL.

      qdrawhelper.cpp:1421
      static const uint *QT_FASTCALL fetchUntransformed(uint *buffer, const Operator *,
                                                        const QSpanData *data, int y, int x, int length)
      {
          const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
          const uint *ptr = qFetchPixels[layout->bpp](buffer, data->texture.scanLine(y), x, length);
          const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
          return layout->convertToARGB32PM(buffer, ptr, length, layout, clut);
      }
      

      So, probably, there should be a protection in the calling function (fetchUntransformed) or in convertToARGB32PM to prevent the crash.

      Thank you!

        Attachments

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

          Activity

            People

            Assignee:
            vgt Eirik Aavitsland
            Reporter:
            js Javier Serrano
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes