// bug in Qt 5.15.2 QPixmap::convertFromImage() and QPixmap::fromImage() <<<<<<< #include #include #include #include #include #include class PIXMAPBUG : public QWidget { private: // image dimensions static constexpr int W = 960, H = 540; private: QImage image; QPixmap pixmap; QTimer timer; int left; private: void UpdateFrame(); public: PIXMAPBUG(); bool Finished() const { return left==0; } }; PIXMAPBUG::PIXMAPBUG() : image(W,H,QImage::Format_ARGB32/* NOT pre-multiplied */), pixmap(W,H) { image.fill(Qt::transparent); pixmap.convertFromImage(image); left = 10*50; connect(&timer,&QTimer::timeout,this,&PIXMAPBUG::UpdateFrame); timer.start(20); } void PIXMAPBUG::UpdateFrame() { // finshed? if(left==0) return; left -= 1; // fill entire image with 0xAA memset(image.bits(),0xAA,image.sizeInBytes()); // call below will corrupt memory // this will write (at least) 4 pixels out-of-bounds (in pre-multiplied format RRGGBBAA). // note: pixmap = QPixmap::fromImage(image); will also cause memory corruption. pixmap.convertFromImage(image); } static bool BufferOverwriteTest() { static constexpr size_t BUFSIZE = 11749294080; // in bytes //static constexpr size_t BUFSIZE = size_t(1)<<28; // in bytes // an all-zero dynamically allocated buffer unsigned char *const buffer = new unsigned char[BUFSIZE]; (void)memset(buffer,0x00,BUFSIZE); // detect any change to buffer for(size_t t=0; t<40; ++t) { for(size_t i=0; i future(QtConcurrent::run(BufferOverwriteTest)); while(!( future.isFinished() && pixmapbug.Finished() )) { QThread::yieldCurrentThread(); QApplication::processEvents(); } const bool memokay = future.result(); if(memokay) QMessageBox::information(nullptr,"Okay","No error detected."); else QMessageBox::critical(nullptr,"Memory Corruption","Out-of-bounds error detected."); }