https://bugs.winehq.org/show_bug.cgi?id=37689
--- Comment #3 from Vincent Povirk madewokherd@gmail.com --- Yes, when given a non-NULL data pointer, the Bitmap object uses the data in place, we have tests that verify this.
I grabbed the source code from github, and it seems the only file creating Bitmap objects with a data pointer is src/mui/MuiBase.cpp, which can create a situation like Micheal described.
The object has a data array inside the GraphicsCacheEntry structure, which it uses to initialize the Bitmap* also in the struct. It creates instances of the structure like this:
GraphicsCacheEntry ce; ce.Create(); gGraphicsCache->Append(ce);
Note that ce is on the stack in this case. gGraphicsCache is a Vec<GraphicsCacheEntry>, so ce is copied into the vector. There is no copy constructor, so I guess it's effectively a memcpy. However, the Bitmap object referenced by the Bitmap* now in the vector still references the data from the ce on the stack.
What a great case study in how the automatic things C++ does can hurt you.
It would have been better to pass a NULL pointer so the data is created and owned by the Bitmap object.
That said, having an invalid data pointer in a Bitmap object is fine as long as we never try to draw to the Bitmap or read its data. In this case, that seems to be the intention. However, HtmlFormatter.cpp/TextRender.cpp at least in the 3.0 branch looks like it calls Graphics.GetDC, which is going to lead us to call alpha_blend_pixels on ReleaseDC (and I see these are in the backtrace), which will access the data EVEN IF NOTHING WAS DRAWN ON THE HDC. I bet native doesn't do that, and that could be the source of this bug.