--- FreeRDP-2.0.0-rc3/libfreerdp/codec/zgfx.c 2018-08-01 09:27:31.000000000 -0400 +++ FreeRDP-2.0.0-rc3/libfreerdp/codec/zgfx_1.c 2019-06-05 01:16:46.159000000 -0400 @@ -109,6 +109,7 @@ static const ZGFX_TOKEN ZGFX_TOKEN_TABLE _zgfx->cBitsCurrent -= _nbits; \ _zgfx->bits = _zgfx->BitsCurrent >> _zgfx->cBitsCurrent; \ _zgfx->BitsCurrent &= ((1 << _zgfx->cBitsCurrent) - 1); + return TRUE; static void zgfx_history_buffer_ring_write(ZGFX_CONTEXT* zgfx, const BYTE* src, size_t count) { @@ -200,9 +201,15 @@ static BOOL zgfx_decompress_segment(ZGFX UINT32 count; UINT32 distance; BYTE* pbSegment; - size_t cbSegment = segmentSize - 1; + size_t cbSegment; - if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize < 1)) + if (!zgfx || !stream) + return FALSE; + + cbSegment = segmentSize - 1; + + if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize < 1) || + (segmentSize > UINT32_MAX)) return FALSE; Stream_Read_UINT8(stream, flags); /* header (1 byte) */ @@ -213,6 +220,10 @@ static BOOL zgfx_decompress_segment(ZGFX if (!(flags & PACKET_COMPRESSED)) { zgfx_history_buffer_ring_write(zgfx, pbSegment, cbSegment); + + if (cbSegment > sizeof(zgfx->OutputBuffer)) + return FALSE; + CopyMemory(zgfx->OutputBuffer, pbSegment, cbSegment); zgfx->OutputCount = cbSegment; return TRUE; @@ -251,6 +262,9 @@ static BOOL zgfx_decompress_segment(ZGFX if (++zgfx->HistoryIndex == zgfx->HistoryBufferSize) zgfx->HistoryIndex = 0; + if (zgfx->OutputCount >= sizeof(zgfx->OutputBuffer)) + return FALSE; + zgfx->OutputBuffer[zgfx->OutputCount++] = c; } else @@ -284,6 +298,9 @@ static BOOL zgfx_decompress_segment(ZGFX count += zgfx->bits; } + if (count > sizeof(zgfx->OutputBuffer) - zgfx->OutputCount) + return FALSE; + zgfx_history_buffer_ring_read(zgfx, distance, &(zgfx->OutputBuffer[zgfx->OutputCount]), count); zgfx_history_buffer_ring_write(zgfx, &(zgfx->OutputBuffer[zgfx->OutputCount]), count); zgfx->OutputCount += count; @@ -296,6 +313,10 @@ static BOOL zgfx_decompress_segment(ZGFX zgfx->cBitsRemaining -= zgfx->cBitsCurrent; zgfx->cBitsCurrent = 0; zgfx->BitsCurrent = 0; + + if (count > sizeof(zgfx->OutputBuffer) - zgfx->OutputCount) + return FALSE; + CopyMemory(&(zgfx->OutputBuffer[zgfx->OutputCount]), zgfx->pbInputCurrent, count); zgfx_history_buffer_ring_write(zgfx, zgfx->pbInputCurrent, count); zgfx->pbInputCurrent += count;