From cafdbc858b31cb6b387733acfb4b4e44314c9f2b Mon Sep 17 00:00:00 2001 From: "brettw@chromium.org" Date: Mon, 30 Aug 2010 21:08:26 +0000 Subject: Bug=52092 In the code above, we tell windows to create an HBITMAP that contains enough size for height*width * sizeof pixel . However, bitmap.getSize() can return a size greater than that. The underlying pixel array could represent a bitmap of greater width. An example of this occuring is in SkCanvas.extractSubset where we create a truncated bitmap that shares the same underlying pixel buffer. Since, we end up copying too much in memcpy there is a potential for this to crash. Cannot reproduce as easily with Chrome, since it depends on a particular device context for a bitmap to be truncated. Original review: http://codereview.chromium.org/3157011/show Patch by udam.saini@gmail.com git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57906 0039d316-1c4b-4281-b951-d872f2087c98 --- skia/ext/vector_platform_device_win.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'skia') diff --git a/skia/ext/vector_platform_device_win.cc b/skia/ext/vector_platform_device_win.cc index c89badd..5e0454f 100644 --- a/skia/ext/vector_platform_device_win.cc +++ b/skia/ext/vector_platform_device_win.cc @@ -619,7 +619,20 @@ void VectorPlatformDevice::InternalDrawBitmap(const SkBitmap& bitmap, HBITMAP hbitmap = ::CreateDIBSection( bitmap_dc, reinterpret_cast(&hdr), DIB_RGB_COLORS, &bits, NULL, 0); - memcpy(bits, pixels, bitmap.getSize()); + + // static cast to a char so we can do byte ptr arithmatic to + // get the offset. + unsigned char* dest_buffer = static_cast(bits); + + // We will copy row by row to avoid having to worry about + // the row strides being different. + const int dest_row_size = hdr.biBitCount / 8 * hdr.biWidth; + for (int row = 0; row < bitmap.height(); ++row) { + int dest_offset = row * dest_row_size; + // pixels_offset in terms of pixel count. + int src_offset = row * bitmap.rowBytesAsPixels(); + memcpy(dest_buffer + dest_offset, pixels + src_offset, dest_row_size); + } SkASSERT(hbitmap); HGDIOBJ old_bitmap = ::SelectObject(bitmap_dc, hbitmap); -- cgit v1.1