summaryrefslogtreecommitdiffstats
path: root/libfreerdp/codec
diff options
context:
space:
mode:
Diffstat (limited to 'libfreerdp/codec')
-rw-r--r--libfreerdp/codec/clear.c23
-rw-r--r--libfreerdp/codec/color.c91
-rw-r--r--libfreerdp/codec/h264_ffmpeg.c1
-rw-r--r--libfreerdp/codec/interleaved.c11
-rw-r--r--libfreerdp/codec/nsc.c14
-rw-r--r--libfreerdp/codec/planar.c3
-rw-r--r--libfreerdp/codec/progressive.c144
-rw-r--r--libfreerdp/codec/rfx.c3
-rw-r--r--libfreerdp/codec/test/TestFuzzCodecs.c31
-rw-r--r--libfreerdp/codec/yuv.c3
-rw-r--r--libfreerdp/codec/zgfx.c75
11 files changed, 225 insertions, 174 deletions
diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c
index 512aeae..c9538c8 100644
--- a/libfreerdp/codec/clear.c
+++ b/libfreerdp/codec/clear.c
@@ -500,12 +500,12 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* clear, wStream* s,
{
case 0: /* Uncompressed */
{
- UINT32 nSrcStep = width * FreeRDPGetBytesPerPixel(PIXEL_FORMAT_BGR24);
- UINT32 nSrcSize = nSrcStep * height;
+ const UINT32 nSrcStep = width * FreeRDPGetBytesPerPixel(PIXEL_FORMAT_BGR24);
+ const size_t nSrcSize = 1ull * nSrcStep * height;
if (bitmapDataByteCount != nSrcSize)
{
- WLog_ERR(TAG, "bitmapDataByteCount %" PRIu32 " != nSrcSize %" PRIu32 "",
+ WLog_ERR(TAG, "bitmapDataByteCount %" PRIu32 " != nSrcSize %" PRIuz "",
bitmapDataByteCount, nSrcSize);
return FALSE;
}
@@ -798,10 +798,16 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
count = (vBarPixelCount > y) ? (vBarPixelCount - y) : 0;
if (count > 0)
- pSrcPixel =
- &vBarShortEntry
- ->pixels[(y - vBarYOn) * FreeRDPGetBytesPerPixel(clear->format)];
-
+ {
+ const size_t offset =
+ (1ull * y - vBarYOn) * FreeRDPGetBytesPerPixel(clear->format);
+ pSrcPixel = &vBarShortEntry->pixels[offset];
+ if (offset + count > vBarShortEntry->count)
+ {
+ WLog_ERR(TAG, "offset + count > vBarShortEntry->count");
+ return FALSE;
+ }
+ }
for (UINT32 x = 0; x < count; x++)
{
UINT32 color = 0;
@@ -1169,7 +1175,10 @@ CLEAR_CONTEXT* clear_context_new(BOOL Compressor)
return clear;
error_nsc:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
clear_context_free(clear);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c
index 186d477..2c3d08a 100644
--- a/libfreerdp/codec/color.c
+++ b/libfreerdp/codec/color.c
@@ -583,16 +583,16 @@ static BOOL freerdp_image_copy_no_overlap(BYTE* WINPR_RESTRICT pDstData, DWORD D
UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
const gdiPalette* WINPR_RESTRICT palette, UINT32 flags)
{
- const UINT32 dstByte = FreeRDPGetBytesPerPixel(DstFormat);
- const UINT32 srcByte = FreeRDPGetBytesPerPixel(SrcFormat);
- const UINT32 copyDstWidth = nWidth * dstByte;
- const UINT32 xSrcOffset = nXSrc * srcByte;
- const UINT32 xDstOffset = nXDst * dstByte;
+ const SSIZE_T dstByte = FreeRDPGetBytesPerPixel(DstFormat);
+ const SSIZE_T srcByte = FreeRDPGetBytesPerPixel(SrcFormat);
+ const SSIZE_T copyDstWidth = nWidth * dstByte;
+ const SSIZE_T xSrcOffset = nXSrc * srcByte;
+ const SSIZE_T xDstOffset = nXDst * dstByte;
const BOOL vSrcVFlip = (flags & FREERDP_FLIP_VERTICAL) ? TRUE : FALSE;
- UINT32 srcVOffset = 0;
- INT32 srcVMultiplier = 1;
- UINT32 dstVOffset = 0;
- INT32 dstVMultiplier = 1;
+ SSIZE_T srcVOffset = 0;
+ SSIZE_T srcVMultiplier = 1;
+ SSIZE_T dstVOffset = 0;
+ SSIZE_T dstVMultiplier = 1;
if ((nHeight > INT32_MAX) || (nWidth > INT32_MAX))
return FALSE;
@@ -608,24 +608,24 @@ static BOOL freerdp_image_copy_no_overlap(BYTE* WINPR_RESTRICT pDstData, DWORD D
if (vSrcVFlip)
{
- srcVOffset = (nHeight - 1) * nSrcStep;
+ srcVOffset = (nHeight - 1ll) * nSrcStep;
srcVMultiplier = -1;
}
if (((flags & FREERDP_KEEP_DST_ALPHA) != 0) && FreeRDPColorHasAlpha(DstFormat))
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* WINPR_RESTRICT srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
BYTE* WINPR_RESTRICT dstLine =
- &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
UINT32 color = FreeRDPReadColor(&srcLine[nXSrc * srcByte], SrcFormat);
UINT32 oldColor = color;
UINT32 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
FreeRDPWriteColorIgnoreAlpha(&dstLine[nXDst * dstByte], DstFormat, dstColor);
- for (UINT32 x = 1; x < nWidth; x++)
+ for (SSIZE_T x = 1; x < nWidth; x++)
{
color = FreeRDPReadColor(&srcLine[(x + nXSrc) * srcByte], SrcFormat);
if (color == oldColor)
@@ -645,29 +645,29 @@ static BOOL freerdp_image_copy_no_overlap(BYTE* WINPR_RESTRICT pDstData, DWORD D
}
else if (FreeRDPAreColorFormatsEqualNoAlpha(SrcFormat, DstFormat))
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* WINPR_RESTRICT srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
BYTE* WINPR_RESTRICT dstLine =
- &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memcpy(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
else
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* WINPR_RESTRICT srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
BYTE* WINPR_RESTRICT dstLine =
- &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
UINT32 color = FreeRDPReadColor(&srcLine[nXSrc * srcByte], SrcFormat);
UINT32 oldColor = color;
UINT32 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
FreeRDPWriteColor(&dstLine[nXDst * dstByte], DstFormat, dstColor);
- for (UINT32 x = 1; x < nWidth; x++)
+ for (SSIZE_T x = 1; x < nWidth; x++)
{
color = FreeRDPReadColor(&srcLine[(x + nXSrc) * srcByte], SrcFormat);
if (color == oldColor)
@@ -699,10 +699,10 @@ static BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 n
const UINT32 xSrcOffset = nXSrc * srcByte;
const UINT32 xDstOffset = nXDst * dstByte;
const BOOL vSrcVFlip = (flags & FREERDP_FLIP_VERTICAL) ? TRUE : FALSE;
- UINT32 srcVOffset = 0;
- INT32 srcVMultiplier = 1;
- UINT32 dstVOffset = 0;
- INT32 dstVMultiplier = 1;
+ SSIZE_T srcVOffset = 0;
+ SSIZE_T srcVMultiplier = 1;
+ SSIZE_T dstVOffset = 0;
+ SSIZE_T dstVMultiplier = 1;
if ((nHeight > INT32_MAX) || (nWidth > INT32_MAX))
return FALSE;
@@ -718,16 +718,16 @@ static BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 n
if (vSrcVFlip)
{
- srcVOffset = (nHeight - 1) * nSrcStep;
+ srcVOffset = (nHeight - 1ll) * nSrcStep;
srcVMultiplier = -1;
}
if (((flags & FREERDP_KEEP_DST_ALPHA) != 0) && FreeRDPColorHasAlpha(DstFormat))
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
- const BYTE* srcLine = &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ const BYTE* srcLine = &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
UINT32 color = FreeRDPReadColor(&srcLine[nXSrc * srcByte], SrcFormat);
UINT32 oldColor = color;
@@ -756,44 +756,44 @@ static BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 n
/* Copy down */
if (nYDst < nYSrc)
{
- for (INT32 y = 0; y < (INT32)nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* srcLine =
&pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memcpy(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
/* Copy up */
else if (nYDst > nYSrc)
{
- for (INT32 y = (INT32)nHeight - 1; y >= 0; y--)
+ for (SSIZE_T y = nHeight - 1; y >= 0; y--)
{
const BYTE* srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memcpy(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
/* Copy left */
else if (nXSrc > nXDst)
{
- for (INT32 y = 0; y < (INT32)nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memmove(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
/* Copy right */
else if (nXSrc < nXDst)
{
- for (INT32 y = (INT32)nHeight - 1; y >= 0; y--)
+ for (SSIZE_T y = nHeight - 1; y >= 0; y--)
{
const BYTE* srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memmove(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
@@ -804,16 +804,16 @@ static BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 n
}
else
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
- const BYTE* srcLine = &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ const BYTE* srcLine = &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
UINT32 color = FreeRDPReadColor(&srcLine[nXSrc * srcByte], SrcFormat);
UINT32 oldColor = color;
UINT32 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
FreeRDPWriteColor(&dstLine[nXDst * dstByte], DstFormat, dstColor);
- for (UINT32 x = 1; x < nWidth; x++)
+ for (SSIZE_T x = 1; x < nWidth; x++)
{
color = FreeRDPReadColor(&srcLine[(x + nXSrc) * srcByte], SrcFormat);
if (color == oldColor)
@@ -847,6 +847,9 @@ BOOL freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32
if (!pDstData || !pSrcData)
return FALSE;
+ if ((nWidth == 0) || (nHeight == 0))
+ return TRUE;
+
if (nDstStep == 0)
nDstStep = nWidth * FreeRDPGetBytesPerPixel(DstFormat);
diff --git a/libfreerdp/codec/h264_ffmpeg.c b/libfreerdp/codec/h264_ffmpeg.c
index 54492e1..a2ad12f 100644
--- a/libfreerdp/codec/h264_ffmpeg.c
+++ b/libfreerdp/codec/h264_ffmpeg.c
@@ -636,6 +636,7 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
goto fail_hwdevice_create;
}
}
+ WLog_Print(h264->log, WLOG_INFO, "Using VAAPI for accelerated H264 decoding");
sys->codecDecoderContext->get_format = libavcodec_get_format;
sys->hw_pix_fmt = AV_PIX_FMT_VAAPI;
diff --git a/libfreerdp/codec/interleaved.c b/libfreerdp/codec/interleaved.c
index df148b6..262895d 100644
--- a/libfreerdp/codec/interleaved.c
+++ b/libfreerdp/codec/interleaved.c
@@ -212,7 +212,7 @@ static UINT ExtractRunLengthRegularFgBg(const BYTE* pbOrderHdr, const BYTE* pbEn
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
if (runLength == 0)
{
- if (!buffer_within_range(pbOrderHdr, 1, pbEnd))
+ if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
{
*advance = 0;
return 0;
@@ -262,7 +262,7 @@ static UINT ExtractRunLengthRegular(const BYTE* pbOrderHdr, const BYTE* pbEnd, U
runLength = *pbOrderHdr & g_MaskRegularRunLength;
if (runLength == 0)
{
- if (!buffer_within_range(pbOrderHdr, 1, pbEnd))
+ if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
{
*advance = 0;
return 0;
@@ -282,7 +282,7 @@ static UINT ExtractRunLengthMegaMega(const BYTE* pbOrderHdr, const BYTE* pbEnd,
WINPR_ASSERT(pbEnd);
WINPR_ASSERT(advance);
- if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
+ if (!buffer_within_range(pbOrderHdr, 3, pbEnd))
{
*advance = 0;
return 0;
@@ -305,7 +305,7 @@ static UINT ExtractRunLengthLite(const BYTE* pbOrderHdr, const BYTE* pbEnd, UINT
runLength = *pbOrderHdr & g_MaskLiteRunLength;
if (runLength == 0)
{
- if (!buffer_within_range(pbOrderHdr, 1, pbEnd))
+ if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
{
*advance = 0;
return 0;
@@ -735,7 +735,10 @@ BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor)
return interleaved;
fail:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
bitmap_interleaved_context_free(interleaved);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c
index 74f4e28..d1b594b 100644
--- a/libfreerdp/codec/nsc.c
+++ b/libfreerdp/codec/nsc.c
@@ -86,8 +86,8 @@ static BOOL nsc_decode(NSC_CONTEXT* context)
for (UINT32 x = 0; x < context->width; x++)
{
INT16 y_val = (INT16)*yplane;
- INT16 co_val = (INT16)(INT8)(*coplane << shift);
- INT16 cg_val = (INT16)(INT8)(*cgplane << shift);
+ INT16 co_val = (INT16)(INT8)(((INT16)*coplane) << shift);
+ INT16 cg_val = (INT16)(INT8)(((INT16)*cgplane) << shift);
INT16 r_val = y_val + co_val - cg_val;
INT16 g_val = y_val + cg_val;
INT16 b_val = y_val - co_val - cg_val;
@@ -250,6 +250,13 @@ static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
}
Stream_Read_UINT8(s, context->ColorLossLevel); /* ColorLossLevel (1 byte) */
+ if ((context->ColorLossLevel < 1) || (context->ColorLossLevel > 7))
+ {
+ WLog_Print(context->priv->log, WLOG_ERROR,
+ "ColorLossLevel=%" PRIu8 " out of range, must be [1,7] inclusive",
+ context->ColorLossLevel);
+ return FALSE;
+ }
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
Stream_Seek(s, 2); /* Reserved (2 bytes) */
context->Planes = Stream_Pointer(s);
@@ -363,7 +370,10 @@ NSC_CONTEXT* nsc_context_new(void)
NSC_INIT_SIMD(context);
return context;
error:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
nsc_context_free(context);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c
index 4b51a02..e894761 100644
--- a/libfreerdp/codec/planar.c
+++ b/libfreerdp/codec/planar.c
@@ -1747,7 +1747,10 @@ BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, UINT32 max
if (!freerdp_bitmap_planar_context_reset(context, maxWidth, maxHeight))
{
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
freerdp_bitmap_planar_context_free(context);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c
index df98ad3..3ab84ef 100644
--- a/libfreerdp/codec/progressive.c
+++ b/libfreerdp/codec/progressive.c
@@ -2312,67 +2312,11 @@ static SSIZE_T progressive_parse_block(PROGRESSIVE_CONTEXT* progressive, wStream
return rc;
}
-INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize,
- BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
- UINT32 nYDst, REGION16* invalidRegion, UINT16 surfaceId,
- UINT32 frameId)
+static BOOL update_tiles(PROGRESSIVE_CONTEXT* progressive, PROGRESSIVE_SURFACE_CONTEXT* surface,
+ BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
+ UINT32 nYDst, PROGRESSIVE_BLOCK_REGION* region, REGION16* invalidRegion)
{
- INT32 rc = 1;
-
- WINPR_ASSERT(progressive);
- PROGRESSIVE_SURFACE_CONTEXT* surface = progressive_get_surface_data(progressive, surfaceId);
-
- if (!surface)
- {
- WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion no surface for %" PRIu16,
- surfaceId);
- return -1001;
- }
-
- PROGRESSIVE_BLOCK_REGION* region = &progressive->region;
- WINPR_ASSERT(region);
-
- if (surface->frameId != frameId)
- {
- surface->frameId = frameId;
- surface->numUpdatedTiles = 0;
- }
-
- wStream ss = { 0 };
- wStream* s = Stream_StaticConstInit(&ss, pSrcData, SrcSize);
- WINPR_ASSERT(s);
-
- switch (DstFormat)
- {
- case PIXEL_FORMAT_RGBA32:
- case PIXEL_FORMAT_RGBX32:
- case PIXEL_FORMAT_BGRA32:
- case PIXEL_FORMAT_BGRX32:
- progressive->format = DstFormat;
- break;
- default:
- progressive->format = PIXEL_FORMAT_XRGB32;
- break;
- }
-
- const size_t start = Stream_GetPosition(s);
- progressive->state = 0; /* Set state to not initialized */
- while (Stream_GetRemainingLength(s) > 0)
- {
- if (progressive_parse_block(progressive, s, surface, region) < 0)
- goto fail;
- }
-
- const size_t end = Stream_GetPosition(s);
- if ((end - start) != SrcSize)
- {
- WLog_Print(progressive->log, WLOG_ERROR,
- "total block len %" PRIuz " does not match read data %" PRIu32, end - start,
- SrcSize);
- rc = -1041;
- goto fail;
- }
-
+ BOOL rc = TRUE;
REGION16 clippingRects = { 0 };
region16_init(&clippingRects);
@@ -2425,13 +2369,11 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD
goto fail;
if (rect->top + height > surface->height)
goto fail;
- if (!freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width,
+ rc = freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width,
height, tile->data, progressive->format, tile->stride, nXSrc,
- nYSrc, NULL, FREERDP_KEEP_DST_ALPHA))
- {
- rc = -42;
+ nYSrc, NULL, FREERDP_KEEP_DST_ALPHA);
+ if (!rc)
break;
- }
if (invalidRegion)
region16_union_rect(invalidRegion, invalidRegion, rect);
@@ -2441,8 +2383,75 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD
tile->dirty = FALSE;
}
+fail:
region16_uninit(&clippingRects);
- surface->numUpdatedTiles = 0;
+ return rc;
+}
+
+INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize,
+ BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
+ UINT32 nYDst, REGION16* invalidRegion, UINT16 surfaceId,
+ UINT32 frameId)
+{
+ INT32 rc = 1;
+
+ WINPR_ASSERT(progressive);
+ PROGRESSIVE_SURFACE_CONTEXT* surface = progressive_get_surface_data(progressive, surfaceId);
+
+ if (!surface)
+ {
+ WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion no surface for %" PRIu16,
+ surfaceId);
+ return -1001;
+ }
+
+ PROGRESSIVE_BLOCK_REGION* region = &progressive->region;
+ WINPR_ASSERT(region);
+
+ if (surface->frameId != frameId)
+ {
+ surface->frameId = frameId;
+ surface->numUpdatedTiles = 0;
+ }
+
+ wStream ss = { 0 };
+ wStream* s = Stream_StaticConstInit(&ss, pSrcData, SrcSize);
+ WINPR_ASSERT(s);
+
+ switch (DstFormat)
+ {
+ case PIXEL_FORMAT_RGBA32:
+ case PIXEL_FORMAT_RGBX32:
+ case PIXEL_FORMAT_BGRA32:
+ case PIXEL_FORMAT_BGRX32:
+ progressive->format = DstFormat;
+ break;
+ default:
+ progressive->format = PIXEL_FORMAT_XRGB32;
+ break;
+ }
+
+ const size_t start = Stream_GetPosition(s);
+ progressive->state = 0; /* Set state to not initialized */
+ while (Stream_GetRemainingLength(s) > 0)
+ {
+ if (progressive_parse_block(progressive, s, surface, region) < 0)
+ goto fail;
+ }
+
+ const size_t end = Stream_GetPosition(s);
+ if ((end - start) != SrcSize)
+ {
+ WLog_Print(progressive->log, WLOG_ERROR,
+ "total block len %" PRIuz " does not match read data %" PRIu32, end - start,
+ SrcSize);
+ rc = -1041;
+ goto fail;
+ }
+
+ if (!update_tiles(progressive, surface, pDstData, DstFormat, nDstStep, nXDst, nYDst, region,
+ invalidRegion))
+ return -2002;
fail:
return rc;
}
@@ -2631,7 +2640,10 @@ PROGRESSIVE_CONTEXT* progressive_context_new_ex(BOOL Compressor, UINT32 Threadin
}
return progressive;
fail:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
progressive_context_free(progressive);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c
index 66ed1e0..c12f6d4 100644
--- a/libfreerdp/codec/rfx.c
+++ b/libfreerdp/codec/rfx.c
@@ -342,7 +342,10 @@ RFX_CONTEXT* rfx_context_new_ex(BOOL encoder, UINT32 ThreadingFlags)
context->expectedDataBlockType = WBT_FRAME_BEGIN;
return context;
fail:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
rfx_context_free(context);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/test/TestFuzzCodecs.c b/libfreerdp/codec/test/TestFuzzCodecs.c
index d83d8d4..f923765 100644
--- a/libfreerdp/codec/test/TestFuzzCodecs.c
+++ b/libfreerdp/codec/test/TestFuzzCodecs.c
@@ -453,28 +453,15 @@ int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
if (Size < 4)
return 0;
- int i = 0;
- winpr_RAND(&i, sizeof(i));
- i = i % 18;
-
- if (i < 2)
- TestFreeRDPCodecClear(Data, Size);
- else if (i < 4)
- TestFreeRDPCodecXCrush(Data, Size);
- else if (i < 6)
- TestFreeRDPCodecZGfx(Data, Size);
- else if (i < 8)
- TestFreeRDPCodecNCrush(Data, Size);
- else if (i < 10)
- TestFreeRDPCodecRemoteFX(Data, Size);
- else if (i < 12)
- TestFreeRDPCodecMppc(Data, Size);
- else if (i < 14)
- TestFreeRDPCodecProgressive(Data, Size);
- else if (i < 16)
- TestFreeRDPCodecInterleaved(Data, Size);
- else if (i < 18)
- TestFreeRDPCodecPlanar(Data, Size);
+ TestFreeRDPCodecClear(Data, Size);
+ TestFreeRDPCodecXCrush(Data, Size);
+ TestFreeRDPCodecZGfx(Data, Size);
+ TestFreeRDPCodecNCrush(Data, Size);
+ TestFreeRDPCodecRemoteFX(Data, Size);
+ TestFreeRDPCodecMppc(Data, Size);
+ TestFreeRDPCodecProgressive(Data, Size);
+ TestFreeRDPCodecInterleaved(Data, Size);
+ TestFreeRDPCodecPlanar(Data, Size);
return 0;
}
diff --git a/libfreerdp/codec/yuv.c b/libfreerdp/codec/yuv.c
index c546566..97c2374 100644
--- a/libfreerdp/codec/yuv.c
+++ b/libfreerdp/codec/yuv.c
@@ -251,7 +251,10 @@ YUV_CONTEXT* yuv_context_new(BOOL encoder, UINT32 ThreadingFlags)
return ret;
error_threadpool:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
yuv_context_free(ret);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/zgfx.c b/libfreerdp/codec/zgfx.c
index b7ee275..3a9d2e5 100644
--- a/libfreerdp/codec/zgfx.c
+++ b/libfreerdp/codec/zgfx.c
@@ -382,16 +382,46 @@ static BYTE* aligned_zgfx_malloc(size_t size)
return malloc(size + 64);
}
+static BOOL zgfx_append(ZGFX_CONTEXT* zgfx, BYTE** ppConcatenated, size_t uncompressedSize,
+ size_t* pUsed)
+{
+ WINPR_ASSERT(zgfx);
+ WINPR_ASSERT(ppConcatenated);
+ WINPR_ASSERT(pUsed);
+
+ const size_t used = *pUsed;
+ if (zgfx->OutputCount > UINT32_MAX - used)
+ return FALSE;
+
+ if (used + zgfx->OutputCount > uncompressedSize)
+ return FALSE;
+
+ BYTE* tmp = realloc(*ppConcatenated, used + zgfx->OutputCount + 64ull);
+ if (!tmp)
+ return FALSE;
+ *ppConcatenated = tmp;
+ CopyMemory(&tmp[used], zgfx->OutputBuffer, zgfx->OutputCount);
+ *pUsed = used + zgfx->OutputCount;
+ return TRUE;
+}
+
int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
UINT32* pDstSize, UINT32 flags)
{
int status = -1;
BYTE descriptor = 0;
wStream sbuffer = { 0 };
+ size_t used = 0;
+ BYTE* pConcatenated = NULL;
wStream* stream = Stream_StaticConstInit(&sbuffer, pSrcData, SrcSize);
WINPR_ASSERT(zgfx);
WINPR_ASSERT(stream);
+ WINPR_ASSERT(ppDstData);
+ WINPR_ASSERT(pDstSize);
+
+ *ppDstData = NULL;
+ *pDstSize = 0;
if (!Stream_CheckAndLogRequiredLength(TAG, stream, 1))
goto fail;
@@ -403,16 +433,15 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
if (!zgfx_decompress_segment(zgfx, stream, Stream_GetRemainingLength(stream)))
goto fail;
- *ppDstData = NULL;
-
if (zgfx->OutputCount > 0)
- *ppDstData = aligned_zgfx_malloc(zgfx->OutputCount);
-
- if (!*ppDstData)
- goto fail;
-
- *pDstSize = zgfx->OutputCount;
- CopyMemory(*ppDstData, zgfx->OutputBuffer, zgfx->OutputCount);
+ {
+ if (!zgfx_append(zgfx, &pConcatenated, zgfx->OutputCount, &used))
+ goto fail;
+ if (used != zgfx->OutputCount)
+ goto fail;
+ *ppDstData = pConcatenated;
+ *pDstSize = zgfx->OutputCount;
+ }
}
else if (descriptor == ZGFX_SEGMENTED_MULTIPART)
{
@@ -420,8 +449,6 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
UINT16 segmentNumber = 0;
UINT16 segmentCount = 0;
UINT32 uncompressedSize = 0;
- BYTE* pConcatenated = NULL;
- size_t used = 0;
if (!Stream_CheckAndLogRequiredLength(TAG, stream, 6))
goto fail;
@@ -429,17 +456,6 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
Stream_Read_UINT16(stream, segmentCount); /* segmentCount (2 bytes) */
Stream_Read_UINT32(stream, uncompressedSize); /* uncompressedSize (4 bytes) */
- if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, stream, segmentCount, sizeof(UINT32)))
- goto fail;
-
- pConcatenated = aligned_zgfx_malloc(uncompressedSize);
-
- if (!pConcatenated)
- goto fail;
-
- *ppDstData = pConcatenated;
- *pDstSize = uncompressedSize;
-
for (segmentNumber = 0; segmentNumber < segmentCount; segmentNumber++)
{
if (!Stream_CheckAndLogRequiredLength(TAG, stream, sizeof(UINT32)))
@@ -450,16 +466,15 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
if (!zgfx_decompress_segment(zgfx, stream, segmentSize))
goto fail;
- if (zgfx->OutputCount > UINT32_MAX - used)
+ if (!zgfx_append(zgfx, &pConcatenated, uncompressedSize, &used))
goto fail;
+ }
- if (used + zgfx->OutputCount > uncompressedSize)
- goto fail;
+ if (used != uncompressedSize)
+ goto fail;
- CopyMemory(pConcatenated, zgfx->OutputBuffer, zgfx->OutputCount);
- pConcatenated += zgfx->OutputCount;
- used += zgfx->OutputCount;
- }
+ *ppDstData = pConcatenated;
+ *pDstSize = uncompressedSize;
}
else
{
@@ -468,6 +483,8 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
status = 1;
fail:
+ if (status < 0)
+ free(pConcatenated);
return status;
}