[1/2] windowscodecs: Fix *_CopyPixels functions to properly handle a NULL rectangle (try 3).

Krzysztof Nowicki krissn at op.pl
Tue Oct 19 11:50:36 CDT 2010


According to the documentation found on MSDN in case of the.
IWICBitmapSource::CopyPixels function, passing a NULL rectangle pointer means
that the whole bitmap should be taken into account.

The existing code incorrectly assumed that the rectangle pointer will never be
NULL, which could lead to NULL pointer dereferences.

Version 2:
Use unified approach when dealing with NULL rectangles. In all cases a local
rectangle is prepared now and a pointer to it is stored in the pointer, which
was originally NULL.

I've decided to keep the optimisation in copy_pixels() that checks if the source
and dest rectangles + strides matches and if yes, does a straight memcpy of the
whole bitmap.

Version 3:
Remove the optimisation in copy_pixels(). It will be submitted separately.

---
 dlls/windowscodecs/converter.c  |   16 ++++++++++++++++
 dlls/windowscodecs/fliprotate.c |   13 +++++++++++++
 dlls/windowscodecs/gifformat.c  |   16 ++++++++++++++--
 dlls/windowscodecs/jpegformat.c |   16 ++++++++++++++++
 dlls/windowscodecs/main.c       |   16 ++++++++++++++--
 dlls/windowscodecs/tiffformat.c |   18 +++++++++++++++---
 6 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c
index 86cdf55..a83f4a5 100644
--- a/dlls/windowscodecs/converter.c
+++ b/dlls/windowscodecs/converter.c
@@ -850,11 +850,27 @@ static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
     const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
 {
     FormatConverter *This = (FormatConverter*)iface;
+    WICRect rc;
+    HRESULT hr;
     TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
 
     if (This->source)
+    {
+        if (!prc)
+        {
+            UINT width, height;
+            hr = IWICBitmapSource_GetSize(This->source, &width, &height);
+            if (FAILED(hr)) return hr;
+            rc.X = 0;
+            rc.Y = 0;
+            rc.Width = width;
+            rc.Height = height;
+            prc = &rc;
+        }
+
         return This->dst_format->copy_function(This, prc, cbStride, cbBufferSize,
             pbBuffer, This->src_format->format);
+    }
     else
         return WINCODEC_ERR_NOTINITIALIZED;
 }
diff --git a/dlls/windowscodecs/fliprotate.c b/dlls/windowscodecs/fliprotate.c
index 7dac252..dbbb957 100644
--- a/dlls/windowscodecs/fliprotate.c
+++ b/dlls/windowscodecs/fliprotate.c
@@ -140,6 +140,7 @@ static HRESULT WINAPI FlipRotator_CopyPixels(IWICBitmapFlipRotator *iface,
     UINT y;
     UINT srcy, srcwidth, srcheight;
     WICRect rc;
+    WICRect rect;
 
     TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
 
@@ -155,6 +156,18 @@ static HRESULT WINAPI FlipRotator_CopyPixels(IWICBitmapFlipRotator *iface,
     hr = IWICBitmapSource_GetSize(This->source, &srcwidth, &srcheight);
     if (FAILED(hr)) return hr;
 
+    if (!prc)
+    {
+        UINT width, height;
+        hr = IWICBitmapSource_GetSize(iface, &width, &height);
+        if (FAILED(hr)) return hr;
+        rect.X = 0;
+        rect.Y = 0;
+        rect.Width = width;
+        rect.Height = height;
+        prc = ▭
+    }
+
     for (y=prc->Y; y - prc->Y < prc->Height; y++)
     {
         if (This->flip_y)
diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c
index 239d25d..5cbdc26 100644
--- a/dlls/windowscodecs/gifformat.c
+++ b/dlls/windowscodecs/gifformat.c
@@ -184,9 +184,21 @@ static HRESULT copy_interlaced_pixels(const BYTE *srcbuffer,
     const BYTE *src;
     BYTE *dst;
     UINT y;
+    WICRect rect;
 
-    if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
-        return E_INVALIDARG;
+    if (!rc)
+    {
+        rect.X = 0;
+        rect.Y = 0;
+        rect.Width = srcwidth;
+        rect.Height = srcheight;
+        rc = &rect;
+    }
+    else
+    {
+        if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
+            return E_INVALIDARG;
+    }
 
     if (dststride < rc->Width)
         return E_INVALIDARG;
diff --git a/dlls/windowscodecs/jpegformat.c b/dlls/windowscodecs/jpegformat.c
index 5243d94..a5cada7 100644
--- a/dlls/windowscodecs/jpegformat.c
+++ b/dlls/windowscodecs/jpegformat.c
@@ -519,8 +519,24 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
     UINT data_size;
     UINT max_row_needed;
     jmp_buf jmpbuf;
+    WICRect rect;
     TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
 
+    if (!prc)
+    {
+        rect.X = 0;
+        rect.Y = 0;;
+        rect.Width = This->cinfo.output_width;
+        rect.Height = This->cinfo.output_height;
+        prc = &rect;
+    }
+    else
+    {
+        if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->cinfo.output_width ||
+            prc->Y+prc->Height > This->cinfo.output_height)
+            return E_INVALIDARG;
+    }
+
     if (This->cinfo.out_color_space == JCS_GRAYSCALE) bpp = 8;
     else if (This->cinfo.out_color_space == JCS_CMYK) bpp = 32;
     else bpp = 24;
diff --git a/dlls/windowscodecs/main.c b/dlls/windowscodecs/main.c
index ff543d5..906ea16 100644
--- a/dlls/windowscodecs/main.c
+++ b/dlls/windowscodecs/main.c
@@ -53,9 +53,21 @@ HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
 {
     UINT bytesperrow;
     UINT row_offset; /* number of bits into the source rows where the data starts */
+    WICRect rect;
 
-    if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
-        return E_INVALIDARG;
+    if (!rc)
+    {
+        rect.X = 0;
+        rect.Y = 0;
+        rect.Width = srcwidth;
+        rect.Height = srcheight;
+        rc = &rect;
+    }
+    else
+    {
+        if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
+            return E_INVALIDARG;
+    }
 
     bytesperrow = ((bpp * rc->Width)+7)/8;
 
diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c
index 645cfb0..1256110 100644
--- a/dlls/windowscodecs/tiffformat.c
+++ b/dlls/windowscodecs/tiffformat.c
@@ -799,12 +799,24 @@ static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
     HRESULT hr=S_OK;
     BYTE *dst_tilepos;
     UINT bytesperrow;
+    WICRect rect;
 
     TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
 
-    if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->decode_info.width ||
-        prc->Y+prc->Height > This->decode_info.height)
-        return E_INVALIDARG;
+    if (!prc)
+    {
+        rect.X = 0;
+        rect.Y = 0;
+        rect.Width = This->decode_info.width;
+        rect.Height = This->decode_info.height;
+        prc = &rect;
+    }
+    else
+    {
+        if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->decode_info.width ||
+            prc->Y+prc->Height > This->decode_info.height)
+            return E_INVALIDARG;
+    }
 
     bytesperrow = ((This->decode_info.bpp * prc->Width)+7)/8;
 
-- 
1.7.1




More information about the wine-patches mailing list