Skip to content

Commit 602f4a2

Browse files
committed
Thanks to Eyal Itkin from Check Point Software Technologies.
1 parent 2ee663f commit 602f4a2

File tree

2 files changed

+61
-39
lines changed

2 files changed

+61
-39
lines changed

Diff for: include/freerdp/codec/zgfx.h

+7-23
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,18 @@
3232

3333
#define ZGFX_SEGMENTED_MAXSIZE 65535
3434

35-
struct _ZGFX_CONTEXT
36-
{
37-
BOOL Compressor;
38-
39-
const BYTE* pbInputCurrent;
40-
const BYTE* pbInputEnd;
41-
42-
UINT32 bits;
43-
UINT32 cBitsRemaining;
44-
UINT32 BitsCurrent;
45-
UINT32 cBitsCurrent;
46-
47-
BYTE OutputBuffer[65536];
48-
UINT32 OutputCount;
49-
50-
BYTE HistoryBuffer[2500000];
51-
UINT32 HistoryIndex;
52-
UINT32 HistoryBufferSize;
53-
};
5435
typedef struct _ZGFX_CONTEXT ZGFX_CONTEXT;
5536

5637
#ifdef __cplusplus
5738
extern "C" {
5839
#endif
5940

60-
FREERDP_API int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags);
61-
FREERDP_API int zgfx_compress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags);
62-
FREERDP_API int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUncompressed, UINT32 uncompressedSize, UINT32* pFlags);
41+
FREERDP_API int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize,
42+
BYTE** ppDstData, UINT32* pDstSize, UINT32 flags);
43+
FREERDP_API int zgfx_compress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize,
44+
BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags);
45+
FREERDP_API int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst,
46+
const BYTE* pUncompressed, UINT32 uncompressedSize, UINT32* pFlags);
6347

6448
FREERDP_API void zgfx_context_reset(ZGFX_CONTEXT* zgfx, BOOL flush);
6549

@@ -71,4 +55,4 @@ FREERDP_API void zgfx_context_free(ZGFX_CONTEXT* zgfx);
7155
#endif
7256

7357
#endif /* FREERDP_CODEC_ZGFX_H */
74-
58+

Diff for: libfreerdp/codec/zgfx.c

+54-16
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,34 @@
4444

4545
struct _ZGFX_TOKEN
4646
{
47-
int prefixLength;
48-
int prefixCode;
49-
int valueBits;
50-
int tokenType;
47+
UINT32 prefixLength;
48+
UINT32 prefixCode;
49+
UINT32 valueBits;
50+
UINT32 tokenType;
5151
UINT32 valueBase;
5252
};
5353
typedef struct _ZGFX_TOKEN ZGFX_TOKEN;
5454

55+
struct _ZGFX_CONTEXT
56+
{
57+
BOOL Compressor;
58+
59+
const BYTE* pbInputCurrent;
60+
const BYTE* pbInputEnd;
61+
62+
UINT32 bits;
63+
UINT32 cBitsRemaining;
64+
UINT32 BitsCurrent;
65+
UINT32 cBitsCurrent;
66+
67+
BYTE OutputBuffer[65536];
68+
UINT32 OutputCount;
69+
70+
BYTE HistoryBuffer[2500000];
71+
UINT32 HistoryIndex;
72+
UINT32 HistoryBufferSize;
73+
};
74+
5575
static const ZGFX_TOKEN ZGFX_TOKEN_TABLE[] =
5676
{
5777
// len code vbits type vbase
@@ -98,17 +118,26 @@ static const ZGFX_TOKEN ZGFX_TOKEN_TABLE[] =
98118
{ 0 }
99119
};
100120

101-
#define zgfx_GetBits(_zgfx, _nbits) \
102-
while (_zgfx->cBitsCurrent < _nbits) { \
103-
_zgfx->BitsCurrent <<= 8; \
104-
if (_zgfx->pbInputCurrent < _zgfx->pbInputEnd) \
105-
_zgfx->BitsCurrent += *(_zgfx->pbInputCurrent)++; \
106-
_zgfx->cBitsCurrent += 8; \
107-
} \
108-
_zgfx->cBitsRemaining -= _nbits; \
109-
_zgfx->cBitsCurrent -= _nbits; \
110-
_zgfx->bits = _zgfx->BitsCurrent >> _zgfx->cBitsCurrent; \
121+
static INLINE BOOL zgfx_GetBits(ZGFX_CONTEXT* _zgfx, UINT32 _nbits)
122+
{
123+
if (!_zgfx)
124+
return FALSE;
125+
126+
while (_zgfx->cBitsCurrent < _nbits)
127+
{
128+
_zgfx->BitsCurrent <<= 8;
129+
130+
if (_zgfx->pbInputCurrent < _zgfx->pbInputEnd)
131+
_zgfx->BitsCurrent += *(_zgfx->pbInputCurrent)++;
132+
133+
_zgfx->cBitsCurrent += 8;
134+
}
135+
136+
_zgfx->cBitsRemaining -= _nbits;
137+
_zgfx->cBitsCurrent -= _nbits;
138+
_zgfx->bits = _zgfx->BitsCurrent >> _zgfx->cBitsCurrent;
111139
_zgfx->BitsCurrent &= ((1 << _zgfx->cBitsCurrent) - 1);
140+
}
112141

113142
static void zgfx_history_buffer_ring_write(ZGFX_CONTEXT* zgfx, const BYTE* src, size_t count)
114143
{
@@ -193,7 +222,7 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
193222
{
194223
BYTE c;
195224
BYTE flags;
196-
int extra;
225+
UINT32 extra = 0;
197226
int opIndex;
198227
int haveBits;
199228
int inPrefix;
@@ -317,8 +346,8 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
317346
{
318347
int status = -1;
319348
BYTE descriptor;
320-
321349
wStream* stream = Stream_New((BYTE*)pSrcData, SrcSize);
350+
322351
if (!stream)
323352
return -1;
324353

@@ -333,6 +362,7 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
333362
goto fail;
334363

335364
*ppDstData = NULL;
365+
336366
if (zgfx->OutputCount > 0)
337367
*ppDstData = (BYTE*) malloc(zgfx->OutputCount);
338368

@@ -349,6 +379,7 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
349379
UINT16 segmentCount;
350380
UINT32 uncompressedSize;
351381
BYTE* pConcatenated;
382+
size_t used = 0;
352383

353384
if (Stream_GetRemainingLength(stream) < 6)
354385
goto fail;
@@ -377,8 +408,15 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
377408
if (!zgfx_decompress_segment(zgfx, stream, segmentSize))
378409
goto fail;
379410

411+
if (zgfx->OutputCount > UINT32_MAX - used)
412+
goto fail;
413+
414+
if (used + zgfx->OutputCount > uncompressedSize)
415+
goto fail;
416+
380417
CopyMemory(pConcatenated, zgfx->OutputBuffer, zgfx->OutputCount);
381418
pConcatenated += zgfx->OutputCount;
419+
used += zgfx->OutputCount;
382420
}
383421
}
384422
else

0 commit comments

Comments
 (0)