diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 526181def..673d046c1 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -353,7 +353,8 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ DstData = surface->data; status = h264_decompress(xfc->codecs->h264, bs->data, bs->length, &DstData, - surface->format, surface->scanline , surface->height, meta->regionRects, meta->numRegionRects); + surface->format, surface->scanline , surface->width, + surface->height, meta->regionRects, meta->numRegionRects); if (status < 0) { diff --git a/include/freerdp/codec/h264.h b/include/freerdp/codec/h264.h index 8e835a9e7..2c9900805 100644 --- a/include/freerdp/codec/h264.h +++ b/include/freerdp/codec/h264.h @@ -61,7 +61,8 @@ extern "C" { FREERDP_API int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize); FREERDP_API int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, - BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRect); + BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstWidth, int nDstHeight, + RDPGFX_RECT16* regionRects, int numRegionRect); FREERDP_API int h264_context_reset(H264_CONTEXT* h264); diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index f42f1be0f..d3fdf2a0a 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -423,7 +423,8 @@ static H264_CONTEXT_SUBSYSTEM g_Subsystem_libavcodec = #endif int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, - BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRects) + BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstWidth, + int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRects) { int index; int status; @@ -435,7 +436,6 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, int width, height; BYTE* pYUVPoint[3]; RDPGFX_RECT16* rect; - int UncompressedSize; primitives_t *prims = primitives_get(); if (!h264) @@ -452,11 +452,6 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, if ((status = h264->subsystem->Decompress(h264, pSrcData, SrcSize)) < 0) return status; - UncompressedSize = h264->width * h264->height * 4; - - if (UncompressedSize > (nDstStep * nDstHeight)) - return -1; - pYUVData = h264->pYUVData; iStride = h264->iStride; @@ -464,6 +459,18 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, { rect = &(regionRects[index]); + /* Check, if the ouput rectangle is valid in decoded h264 frame. */ + if ((rect->right > h264->width) || (rect->left > h264->width)) + return -1; + if ((rect->top > h264->height) || (rect->bottom > h264->height)) + return -1; + + /* Check, if the output rectangle is valid in destination buffer. */ + if ((rect->right > nDstWidth) || (rect->left > nDstWidth)) + return -1; + if ((rect->bottom > nDstHeight) || (rect->top > nDstHeight)) + return -1; + width = rect->right - rect->left; height = rect->bottom - rect->top; diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c index 9447fa01f..1b7076f25 100644 --- a/libfreerdp/gdi/gfx.c +++ b/libfreerdp/gdi/gfx.c @@ -356,7 +356,8 @@ int gdi_SurfaceCommand_H264(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SU DstData = surface->data; status = h264_decompress(gdi->codecs->h264, bs->data, bs->length, &DstData, - PIXEL_FORMAT_XRGB32, surface->scanline , surface->height, meta->regionRects, meta->numRegionRects); + PIXEL_FORMAT_XRGB32, surface->scanline , surface->width, surface->height, + meta->regionRects, meta->numRegionRects); if (status < 0) {