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

memory corruption when calling QPixmap::convertFromImage()/fromImage()

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P1: Critical
    • None
    • 5.15.2, 6.4.0
    • GUI: Painting
    • None
    • Windows 10 64-bits, Ryzen 7 4800U CPU
    • Windows

    Description

      Calling QPixmap::convertFromImage() or QPixmap::fromImage() causes a memory corruption,

      when source image has ARGB32 format.

       

      Steps to reproduce:

      Build and execute attached code.

      Start the code with "Start Debugging" as (at least for me) the problem is not reproducible when not run from within the debugger.

      As the debugger becomes unreliable with multi-threading, place a break point at the line below the "// memory corruption" comment in the 'if' statement.

       

      Running the code in the debugger will trigger the break point when the memory is corrupted.

       

      The memory is corrupted at offset 16 from the dynamically allocated buffer.

      The values written at this offset are:

      { 113, 113, 113, 170, 113, 113, 113, 170, 113, 113, 113, 170, 113, 113, 113, 170 }

      .

       

      Note that the source image contains ARGB32 values of 0xAAAAAAAA (170, 170, 170, 170) and that 113 == round( 0xAA * (0xAA/0xFF)). So the overwritten values seem to be 4 pre-multiplied RGBA pixels.

       

      Also note that changing the image format from the 'image' member from 'QImage::Format_ARGB32' to 'QImage::Format_ARGB32_Premultiplied' prevents to memory corruption from occurring.

       

      So, it seems that the 'pixmap.convertFromImage(image)' call does a conversion from ARGB32 to ARGB32 pre-multiplied and writes out-of-bounds while doing so. As 4 pixels are observed in the corrupted memory, this probably happens in some code that is optimized to pre-multiply 4 or more pixels at once (likely optimized for the processor, I'm using an Ryzen 7 4800U).

       

      Looking at the Qt code on woboq.org, I noticed several implementations of 'convertARGBToARGB32PM' for different SIMD architectures ('qdrawhelper_???.cpp' files). I suspect that one or more of these routines are the culprit (I use pre-built binaries, so I'm not sure).

       

      Note that I tried setting a data break point at the address that is overwritten, but the timing is off once I start interacting with the debugger, so I was not successful in getting an offset in Qt code for better pinpointing the location of the bug.

       

      Also note that the test buffer seems to be very large for it to be written to (probably due to optimization of small buffer allocations).

       

      Attachments

        Activity

          People

            owolff Oliver Wolff
            ev E Visser
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: