Merge pull request #2330 from akallabeth/h264_decoder_fix

Fixed buffer size checks in h264_decompress
This commit is contained in:
Marc-André Moreau 2015-01-22 16:05:09 -05:00
commit 62d1276a0a
4 changed files with 20 additions and 10 deletions

View File

@ -353,7 +353,8 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_
DstData = surface->data; DstData = surface->data;
status = h264_decompress(xfc->codecs->h264, bs->data, bs->length, &DstData, 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) if (status < 0)
{ {

View File

@ -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_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize);
FREERDP_API int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, 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); FREERDP_API int h264_context_reset(H264_CONTEXT* h264);

View File

@ -423,7 +423,8 @@ static H264_CONTEXT_SUBSYSTEM g_Subsystem_libavcodec =
#endif #endif
int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, 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 index;
int status; int status;
@ -435,7 +436,6 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
int width, height; int width, height;
BYTE* pYUVPoint[3]; BYTE* pYUVPoint[3];
RDPGFX_RECT16* rect; RDPGFX_RECT16* rect;
int UncompressedSize;
primitives_t *prims = primitives_get(); primitives_t *prims = primitives_get();
if (!h264) 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) if ((status = h264->subsystem->Decompress(h264, pSrcData, SrcSize)) < 0)
return status; return status;
UncompressedSize = h264->width * h264->height * 4;
if (UncompressedSize > (nDstStep * nDstHeight))
return -1;
pYUVData = h264->pYUVData; pYUVData = h264->pYUVData;
iStride = h264->iStride; iStride = h264->iStride;
@ -464,6 +459,18 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
{ {
rect = &(regionRects[index]); 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; width = rect->right - rect->left;
height = rect->bottom - rect->top; height = rect->bottom - rect->top;

View File

@ -356,7 +356,8 @@ int gdi_SurfaceCommand_H264(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SU
DstData = surface->data; DstData = surface->data;
status = h264_decompress(gdi->codecs->h264, bs->data, bs->length, &DstData, 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) if (status < 0)
{ {