Updated wStream API and added torough checks

* Do length/capacity checks in every read/write/seek function
  if WINPR_ASSERT is defined.
* Ensure s->pointer is valid, e.g. within s->buffer + s->capacity
  (Stream_Rewind, Stream_Seek, ...)
* Add return values to Stream_Set* functions so inalid arguments
  can be reported to the caller
* Deprecated problematic stream manipulation functions
  (Stream_SetBuffer, Stream_SetPointer, Stream_SetCapacity)
* Ensure length/capacity functions never return a value larger
  than the actual length/capacity
This commit is contained in:
Armin Novak 2021-10-04 08:48:38 +02:00 committed by akallabeth
parent 103ff6a758
commit 18a3fcf2fc
7 changed files with 243 additions and 130 deletions

View File

@ -569,7 +569,7 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s)
BOOL tsmf_codec_check_media_type(const char* decoder_name, wStream* s)
{
BYTE* m;
size_t pos;
BOOL ret = FALSE;
TS_AM_MEDIA_TYPE mediatype;
@ -583,10 +583,10 @@ BOOL tsmf_codec_check_media_type(const char* decoder_name, wStream* s)
decoderAvailable = TRUE;
}
Stream_GetPointer(s, m);
pos = Stream_GetPosition(s);
if (decoderAvailable)
ret = tsmf_codec_parse_media_type(&mediatype, s);
Stream_SetPointer(s, m);
Stream_SetPosition(s, pos);
if (ret)
{

View File

@ -1045,8 +1045,6 @@ INT32 clear_decompress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, UINT32 SrcSiz
if (!s)
return -2005;
Stream_SetLength(s, SrcSize);
if (Stream_GetRemainingLength(s) < 2)
{
WLog_ERR(TAG, "stream short %" PRIuz " [2 expected]", Stream_GetRemainingLength(s));

View File

@ -117,12 +117,6 @@ static INT16 read_int16(const BYTE* src)
return (INT16)(src[0] | (src[1] << 8));
}
static void write_int16(BYTE* dst, INT32 val)
{
dst[1] = (val >> 8) & 0xFF;
dst[0] = val & 0xFF;
}
static BOOL freerdp_dsp_channel_mix(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
const AUDIO_FORMAT* srcFormat, const BYTE** data,
size_t* length)
@ -334,7 +328,7 @@ static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* adpcm, unsigned int channel, BY
static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
wStream* out)
{
BYTE* dst;
size_t pos;
BYTE sample;
UINT16 decoded;
size_t out_size = size * 4;
@ -346,7 +340,7 @@ static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYT
if (!Stream_EnsureCapacity(out, out_size))
return FALSE;
dst = Stream_Pointer(out);
pos = Stream_GetPosition(out);
while (size > 0)
{
@ -374,6 +368,8 @@ static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYT
{
for (i = 0; i < 8; i++)
{
BYTE* dst = Stream_Pointer(out);
channel = (i < 4 ? 0 : 1);
sample = ((*src) & 0x0f);
decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
@ -386,11 +382,16 @@ static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYT
src++;
}
dst += 32;
if (!Stream_SafeSeek(out, 32))
return FALSE;
size -= 8;
}
else
{
BYTE* dst = Stream_Pointer(out);
if (!Stream_SafeSeek(out, 4))
return FALSE;
sample = ((*src) & 0x0f);
decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
*dst++ = (decoded & 0xFF);
@ -404,7 +405,6 @@ static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYT
}
}
Stream_SetPointer(out, dst);
return TRUE;
}
@ -712,8 +712,7 @@ static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYT
wStream* out)
{
int i;
BYTE* dst;
BYTE* start;
size_t start;
INT16 sample;
BYTE encoded;
size_t out_size;
@ -723,30 +722,32 @@ static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYT
if (!Stream_EnsureRemainingCapacity(out, size))
return FALSE;
start = Stream_Buffer(context->buffer);
dst = Stream_Pointer(context->buffer);
start = Stream_GetPosition(context->buffer);
align = (context->format.nChannels > 1) ? 32 : 4;
while (size >= align)
{
if ((dst - start) % context->format.nBlockAlign == 0)
if ((Stream_GetPosition(context->buffer) - start) % context->format.nBlockAlign == 0)
{
*dst++ = context->adpcm.ima.last_sample[0] & 0xFF;
*dst++ = (context->adpcm.ima.last_sample[0] >> 8) & 0xFF;
*dst++ = (BYTE)context->adpcm.ima.last_step[0];
*dst++ = 0;
Stream_Write_UINT8(context->buffer, context->adpcm.ima.last_sample[0] & 0xFF);
Stream_Write_UINT8(context->buffer, (context->adpcm.ima.last_sample[0] >> 8) & 0xFF);
Stream_Write_UINT8(context->buffer, (BYTE)context->adpcm.ima.last_step[0]);
Stream_Write_UINT8(context->buffer, 0);
if (context->format.nChannels > 1)
{
*dst++ = context->adpcm.ima.last_sample[1] & 0xFF;
*dst++ = (context->adpcm.ima.last_sample[1] >> 8) & 0xFF;
*dst++ = (BYTE)context->adpcm.ima.last_step[1];
*dst++ = 0;
Stream_Write_UINT8(context->buffer, context->adpcm.ima.last_sample[1] & 0xFF);
Stream_Write_UINT8(context->buffer,
(context->adpcm.ima.last_sample[1] >> 8) & 0xFF);
Stream_Write_UINT8(context->buffer, (BYTE)context->adpcm.ima.last_step[1]);
Stream_Write_UINT8(context->buffer, 0);
}
}
if (context->format.nChannels > 1)
{
BYTE* dst = Stream_Pointer(context->buffer);
ZeroMemory(dst, 8);
for (i = 0; i < 16; i++)
@ -758,7 +759,8 @@ static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYT
<< ima_stereo_encode_map[i].byte_shift;
}
dst += 8;
if (!Stream_SafeSeek(context->buffer, 8))
return FALSE;
size -= 32;
}
else
@ -769,18 +771,18 @@ static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYT
sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
src += 2;
encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
*dst++ = encoded;
Stream_Write_UINT8(context->buffer, encoded);
size -= 4;
}
if (dst - start == context->adpcm.ima.packet_size)
if (Stream_GetPosition(context->buffer) - start == context->adpcm.ima.packet_size)
{
Stream_Write(out, start, context->adpcm.ima.packet_size);
dst = Stream_Buffer(context->buffer);
BYTE* bsrc = Stream_Buffer(context->buffer);
Stream_Write(out, bsrc, context->adpcm.ima.packet_size);
Stream_SetPosition(context->buffer, 0);
}
}
Stream_SetPointer(context->buffer, dst);
return TRUE;
}
@ -825,7 +827,6 @@ static INLINE INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* adpcm, BYTE sample
static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
wStream* out)
{
BYTE* dst;
BYTE sample;
const size_t out_size = size * 4;
const UINT32 channels = context->format.nChannels;
@ -834,8 +835,6 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE
if (!Stream_EnsureCapacity(out, out_size))
return FALSE;
dst = Stream_Pointer(out);
while (size > 0)
{
if (size % block_size == 0)
@ -857,14 +856,10 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE
context->adpcm.ms.sample2[1] = read_int16(src);
src += 2;
size -= 14;
write_int16(dst, context->adpcm.ms.sample2[0]);
dst += 2;
write_int16(dst, context->adpcm.ms.sample2[1]);
dst += 2;
write_int16(dst, context->adpcm.ms.sample1[0]);
dst += 2;
write_int16(dst, context->adpcm.ms.sample1[1]);
dst += 2;
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
}
else
{
@ -876,10 +871,8 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE
context->adpcm.ms.sample2[0] = read_int16(src);
src += 2;
size -= 7;
write_int16(dst, context->adpcm.ms.sample2[0]);
dst += 2;
write_int16(dst, context->adpcm.ms.sample1[0]);
dst += 2;
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
}
}
@ -887,29 +880,28 @@ static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE
{
sample = *src++;
size--;
write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
dst += 2;
write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
dst += 2;
Stream_Write_INT16(out,
freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
Stream_Write_INT16(
out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
sample = *src++;
size--;
write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
dst += 2;
write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
dst += 2;
Stream_Write_INT16(out,
freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
Stream_Write_INT16(
out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
}
else
{
sample = *src++;
size--;
write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
dst += 2;
write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0));
dst += 2;
Stream_Write_INT16(out,
freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
Stream_Write_INT16(
out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0));
}
}
Stream_SetPointer(out, dst);
return TRUE;
}
@ -951,8 +943,7 @@ static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* adpcm, INT32 sample, int c
static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
wStream* out)
{
BYTE* dst;
BYTE* start;
size_t start;
INT32 sample;
size_t out_size;
const size_t step = 8 + ((context->format.nChannels > 1) ? 4 : 0);
@ -961,7 +952,7 @@ static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE
if (!Stream_EnsureRemainingCapacity(out, size))
return FALSE;
start = dst = Stream_Pointer(out);
start = Stream_GetPosition(out);
if (context->adpcm.ms.delta[0] < 16)
context->adpcm.ms.delta[0] = 16;
@ -971,38 +962,42 @@ static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE
while (size >= step)
{
if ((dst - start) % context->format.nBlockAlign == 0)
BYTE val;
if ((Stream_GetPosition(out) - start) % context->format.nBlockAlign == 0)
{
if (context->format.nChannels > 1)
{
*dst++ = context->adpcm.ms.predictor[0];
*dst++ = context->adpcm.ms.predictor[1];
*dst++ = (BYTE)(context->adpcm.ms.delta[0] & 0xFF);
*dst++ = (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF);
*dst++ = (BYTE)(context->adpcm.ms.delta[1] & 0xFF);
*dst++ = (BYTE)((context->adpcm.ms.delta[1] >> 8) & 0xFF);
Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
Stream_Write_UINT8(out, context->adpcm.ms.predictor[1]);
Stream_Write_UINT8(out, (context->adpcm.ms.delta[0] & 0xFF));
Stream_Write_UINT8(out, ((context->adpcm.ms.delta[0] >> 8) & 0xFF));
Stream_Write_UINT8(out, (context->adpcm.ms.delta[1] & 0xFF));
Stream_Write_UINT8(out, ((context->adpcm.ms.delta[1] >> 8) & 0xFF));
context->adpcm.ms.sample1[0] = read_int16(src + 4);
context->adpcm.ms.sample1[1] = read_int16(src + 6);
context->adpcm.ms.sample2[0] = read_int16(src + 0);
context->adpcm.ms.sample2[1] = read_int16(src + 2);
write_int16(dst + 0, context->adpcm.ms.sample1[0]);
write_int16(dst + 2, context->adpcm.ms.sample1[1]);
write_int16(dst + 4, context->adpcm.ms.sample2[0]);
write_int16(dst + 6, context->adpcm.ms.sample2[1]);
dst += 8;
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
src += 8;
size -= 8;
}
else
{
*dst++ = context->adpcm.ms.predictor[0];
*dst++ = (BYTE)(context->adpcm.ms.delta[0] & 0xFF);
*dst++ = (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF);
Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
Stream_Write_UINT8(out, (BYTE)(context->adpcm.ms.delta[0] & 0xFF));
Stream_Write_UINT8(out, (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF));
context->adpcm.ms.sample1[0] = read_int16(src + 2);
context->adpcm.ms.sample2[0] = read_int16(src + 0);
write_int16(dst + 0, context->adpcm.ms.sample1[0]);
write_int16(dst + 2, context->adpcm.ms.sample2[0]);
dst += 4;
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
src += 4;
size -= 4;
}
@ -1010,16 +1005,18 @@ static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE
sample = read_int16(src);
src += 2;
*dst = (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF;
Stream_Write_UINT8(
out, (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF);
sample = read_int16(src);
src += 2;
*dst += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
context->format.nChannels > 1 ? 1 : 0);
dst++;
Stream_Read_UINT8(out, val);
val += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
context->format.nChannels > 1 ? 1 : 0);
Stream_Write_UINT8(out, val);
size -= 4;
}
Stream_SetPointer(out, dst);
return TRUE;
}

View File

@ -995,7 +995,7 @@ BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s)
{
BYTE* mark;
size_t pos;
UINT16 length;
UINT16 channelId;
@ -1003,7 +1003,7 @@ BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s)
if (rdp->mcs->messageChannelId != 0)
{
/* Process any MCS message channel PDUs. */
Stream_GetPointer(s, mark);
pos = Stream_GetPosition(s);
if (rdp_read_header(rdp, s, &length, &channelId))
{
@ -1028,7 +1028,7 @@ BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s)
}
}
Stream_SetPointer(s, mark);
Stream_SetPosition(s, pos);
}
return FALSE;
@ -1058,19 +1058,21 @@ int rdp_client_connect_license(rdpRdp* rdp, wStream* s)
int rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s)
{
BYTE* mark;
size_t pos;
UINT16 width;
UINT16 height;
UINT16 length;
width = rdp->settings->DesktopWidth;
height = rdp->settings->DesktopHeight;
Stream_GetPointer(s, mark);
pos = Stream_GetPosition(s);
if (!rdp_recv_demand_active(rdp, s))
{
int rc;
UINT16 channelId;
Stream_SetPointer(s, mark);
Stream_SetPosition(s, pos);
if (!rdp_recv_get_active_header(rdp, s, &channelId, &length))
return -1;
/* Was Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);

View File

@ -528,7 +528,7 @@ static BOOL tf_peer_dump_rfx(freerdp_peer* client)
record.data = Stream_Buffer(s);
pcap_get_next_record_content(pcap_rfx, &record);
Stream_SetPointer(s, Stream_Buffer(s) + Stream_Capacity(s));
Stream_SetPosition(s, Stream_Capacity(s));
if (info->test_dump_rfx_realtime &&
test_sleep_tsdiff(&prev_seconds, &prev_useconds, record.header.ts_sec,

View File

@ -50,6 +50,10 @@ extern "C"
};
typedef struct _wStream wStream;
static INLINE size_t Stream_Capacity(wStream* _s);
static INLINE size_t Stream_GetRemainingCapacity(wStream* _s);
static INLINE size_t Stream_GetRemainingLength(wStream* _s);
WINPR_API BOOL Stream_EnsureCapacity(wStream* s, size_t size);
WINPR_API BOOL Stream_EnsureRemainingCapacity(wStream* s, size_t size);
@ -60,26 +64,38 @@ extern "C"
static INLINE void Stream_Seek(wStream* s, size_t _offset)
{
WINPR_ASSERT(s);
WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= _offset);
s->pointer += (_offset);
}
static INLINE void Stream_Rewind(wStream* s, size_t _offset)
{
size_t cur;
WINPR_ASSERT(s);
s->pointer -= (_offset);
WINPR_ASSERT(s->buffer <= s->pointer);
cur = (size_t)(s->pointer - s->buffer);
WINPR_ASSERT(cur >= _offset);
if (cur >= _offset)
s->pointer -= (_offset);
else
s->pointer = s->buffer;
}
#define _stream_read_n8(_t, _s, _v, _p) \
do \
{ \
(_v) = (_t)(*(_s)->pointer); \
if (_p) \
Stream_Seek(_s, sizeof(_t)); \
#define _stream_read_n8(_t, _s, _v, _p) \
do \
{ \
WINPR_ASSERT(_s); \
WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 1); \
(_v) = (_t)(*(_s)->pointer); \
if (_p) \
Stream_Seek(_s, sizeof(_t)); \
} while (0)
#define _stream_read_n16_le(_t, _s, _v, _p) \
do \
{ \
WINPR_ASSERT(_s); \
WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 2); \
(_v) = (_t)((*(_s)->pointer) + (((UINT16)(*((_s)->pointer + 1))) << 8)); \
if (_p) \
Stream_Seek(_s, sizeof(_t)); \
@ -88,6 +104,8 @@ extern "C"
#define _stream_read_n16_be(_t, _s, _v, _p) \
do \
{ \
WINPR_ASSERT(_s); \
WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 2); \
(_v) = (_t)((((UINT16)(*(_s)->pointer)) << 8) + (UINT16)(*((_s)->pointer + 1))); \
if (_p) \
Stream_Seek(_s, sizeof(_t)); \
@ -96,6 +114,8 @@ extern "C"
#define _stream_read_n32_le(_t, _s, _v, _p) \
do \
{ \
WINPR_ASSERT(_s); \
WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 4); \
(_v) = (_t)((UINT32)(*(_s)->pointer) + (((UINT32)(*((_s)->pointer + 1))) << 8) + \
(((UINT32)(*((_s)->pointer + 2))) << 16) + \
((((UINT32) * ((_s)->pointer + 3))) << 24)); \
@ -106,6 +126,8 @@ extern "C"
#define _stream_read_n32_be(_t, _s, _v, _p) \
do \
{ \
WINPR_ASSERT(_s); \
WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 4); \
(_v) = (_t)(((((UINT32) * ((_s)->pointer))) << 24) + \
(((UINT32)(*((_s)->pointer + 1))) << 16) + \
(((UINT32)(*((_s)->pointer + 2))) << 8) + (((UINT32)(*((_s)->pointer + 3))))); \
@ -116,6 +138,8 @@ extern "C"
#define _stream_read_n64_le(_t, _s, _v, _p) \
do \
{ \
WINPR_ASSERT(_s); \
WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 8); \
(_v) = (_t)( \
(UINT64)(*(_s)->pointer) + (((UINT64)(*((_s)->pointer + 1))) << 8) + \
(((UINT64)(*((_s)->pointer + 2))) << 16) + (((UINT64)(*((_s)->pointer + 3))) << 24) + \
@ -128,6 +152,8 @@ extern "C"
#define _stream_read_n64_be(_t, _s, _v, _p) \
do \
{ \
WINPR_ASSERT(_s); \
WINPR_ASSERT(Stream_GetRemainingLength(_s) >= 8); \
(_v) = (_t)( \
(((UINT64)(*((_s)->pointer))) << 56) + (((UINT64)(*((_s)->pointer + 1))) << 48) + \
(((UINT64)(*((_s)->pointer + 2))) << 40) + (((UINT64)(*((_s)->pointer + 3))) << 32) + \
@ -162,6 +188,7 @@ extern "C"
{
WINPR_ASSERT(_s);
WINPR_ASSERT(_b || (_n == 0));
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
memcpy(_b, (_s->pointer), (_n));
Stream_Seek(_s, _n);
}
@ -191,18 +218,21 @@ extern "C"
{
WINPR_ASSERT(_s);
WINPR_ASSERT(_b || (_n == 0));
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
memcpy(_b, (_s->pointer), (_n));
}
static INLINE void Stream_Write_UINT8(wStream* _s, UINT8 _v)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
*_s->pointer++ = (UINT8)(_v);
}
static INLINE void Stream_Write_INT16(wStream* _s, INT16 _v)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
*_s->pointer++ = (_v)&0xFF;
*_s->pointer++ = ((_v) >> 8) & 0xFF;
}
@ -210,6 +240,7 @@ extern "C"
static INLINE void Stream_Write_UINT16(wStream* _s, UINT16 _v)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
*_s->pointer++ = (_v)&0xFF;
*_s->pointer++ = ((_v) >> 8) & 0xFF;
}
@ -217,6 +248,7 @@ extern "C"
static INLINE void Stream_Write_UINT16_BE(wStream* _s, UINT16 _v)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
*_s->pointer++ = ((_v) >> 8) & 0xFF;
*_s->pointer++ = (_v)&0xFF;
}
@ -224,6 +256,7 @@ extern "C"
static INLINE void Stream_Write_INT32(wStream* _s, INT32 _v)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
*_s->pointer++ = (_v)&0xFF;
*_s->pointer++ = ((_v) >> 8) & 0xFF;
*_s->pointer++ = ((_v) >> 16) & 0xFF;
@ -233,6 +266,7 @@ extern "C"
static INLINE void Stream_Write_UINT32(wStream* _s, UINT32 _v)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
*_s->pointer++ = (_v)&0xFF;
*_s->pointer++ = ((_v) >> 8) & 0xFF;
*_s->pointer++ = ((_v) >> 16) & 0xFF;
@ -248,6 +282,7 @@ extern "C"
static INLINE void Stream_Write_UINT64(wStream* _s, UINT64 _v)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
*_s->pointer++ = (UINT64)(_v)&0xFF;
*_s->pointer++ = ((UINT64)(_v) >> 8) & 0xFF;
*_s->pointer++ = ((UINT64)(_v) >> 16) & 0xFF;
@ -263,6 +298,7 @@ extern "C"
{
WINPR_ASSERT(_s);
WINPR_ASSERT(_b);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
memcpy(_s->pointer, (_b), (_n));
Stream_Seek(_s, _n);
}
@ -281,6 +317,7 @@ extern "C"
static INLINE void Stream_Zero(wStream* _s, size_t _n)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= (_n));
memset(_s->pointer, '\0', (_n));
Stream_Seek(_s, _n);
}
@ -288,6 +325,7 @@ extern "C"
static INLINE void Stream_Fill(wStream* _s, int _v, size_t _n)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= (_n));
memset(_s->pointer, _v, (_n));
Stream_Seek(_s, _n);
}
@ -296,6 +334,9 @@ extern "C"
{
WINPR_ASSERT(_src);
WINPR_ASSERT(_dst);
WINPR_ASSERT(Stream_GetRemainingCapacity(_src) >= (_n));
WINPR_ASSERT(Stream_GetRemainingCapacity(_dst) >= (_n));
memcpy(_dst->pointer, _src->pointer, _n);
Stream_Seek(_dst, _n);
Stream_Seek(_src, _n);
@ -308,11 +349,6 @@ extern "C"
}
#define Stream_GetBuffer(_s, _b) _b = Stream_Buffer(_s)
static INLINE void Stream_SetBuffer(wStream* _s, BYTE* _b)
{
WINPR_ASSERT(_s);
_s->buffer = _b;
}
static INLINE BYTE* Stream_Pointer(wStream* _s)
{
@ -321,11 +357,15 @@ extern "C"
}
#define Stream_GetPointer(_s, _p) _p = Stream_Pointer(_s)
static INLINE void Stream_SetPointer(wStream* _s, BYTE* _p)
{
WINPR_ASSERT(_s);
_s->pointer = _p;
}
#if defined(WITH_WINPR_DEPRECATED)
WINPR_API WINPR_DEPRECATED_VAR("Use Stream_SetPosition instead",
BOOL Stream_SetPointer(wStream* _s, BYTE* _p));
WINPR_API WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
BOOL Stream_SetBuffer(wStream* _s, BYTE* _b));
WINPR_API WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
void Stream_SetCapacity(wStream* _s, size_t capacity));
#endif
static INLINE size_t Stream_Length(wStream* _s)
{
@ -334,11 +374,7 @@ extern "C"
}
#define Stream_GetLength(_s, _l) _l = Stream_Length(_s)
static INLINE void Stream_SetLength(wStream* _s, size_t _l)
{
WINPR_ASSERT(_s);
_s->length = _l;
}
WINPR_API BOOL Stream_SetLength(wStream* _s, size_t _l);
static INLINE size_t Stream_Capacity(wStream* _s)
{
@ -347,40 +383,67 @@ extern "C"
}
#define Stream_GetCapacity(_s, _c) _c = Stream_Capacity(_s);
static INLINE void Stream_SetCapacity(wStream* _s, size_t _c)
{
WINPR_ASSERT(_s);
_s->capacity = _c;
}
static INLINE size_t Stream_GetPosition(wStream* _s)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(_s->buffer <= _s->pointer);
return (size_t)(_s->pointer - _s->buffer);
}
static INLINE void Stream_SetPosition(wStream* _s, size_t _p)
{
WINPR_ASSERT(_s);
_s->pointer = _s->buffer + (_p);
}
WINPR_API BOOL Stream_SetPosition(wStream* _s, size_t _p);
static INLINE void Stream_SealLength(wStream* _s)
{
size_t cur;
WINPR_ASSERT(_s);
_s->length = (size_t)(_s->pointer - _s->buffer);
WINPR_ASSERT(_s->buffer <= _s->pointer);
cur = (size_t)(_s->pointer - _s->buffer);
WINPR_ASSERT(cur <= _s->capacity);
if (cur <= _s->capacity)
_s->length = cur;
else
{
const char* wTAG = "com.freerdp.winpr.wStream";
WLog_FATAL(wTAG, "wStream API misuse: stream was written out of bounds");
winpr_log_backtrace(wTAG, WLOG_FATAL, 20);
_s->length = 0;
}
}
static INLINE size_t Stream_GetRemainingCapacity(wStream* _s)
{
size_t cur;
WINPR_ASSERT(_s);
return (_s->capacity - (size_t)(_s->pointer - _s->buffer));
WINPR_ASSERT(_s->buffer <= _s->pointer);
cur = (size_t)(_s->pointer - _s->buffer);
WINPR_ASSERT(cur <= _s->capacity);
if (cur > _s->capacity)
{
const char* wTAG = "com.freerdp.winpr.wStream";
WLog_FATAL(wTAG, "wStream API misuse: stream was written out of bounds");
winpr_log_backtrace(wTAG, WLOG_FATAL, 20);
return 0;
}
return (_s->capacity - cur);
}
static INLINE size_t Stream_GetRemainingLength(wStream* _s)
{
size_t cur;
WINPR_ASSERT(_s);
return (_s->length - (size_t)(_s->pointer - _s->buffer));
WINPR_ASSERT(_s->buffer <= _s->pointer);
WINPR_ASSERT(_s->length <= _s->capacity);
cur = (size_t)(_s->pointer - _s->buffer);
WINPR_ASSERT(cur <= _s->length);
if (cur > _s->length)
{
const char* wTAG = "com.freerdp.winpr.wStream";
WLog_FATAL(wTAG, "wStream API misuse: stream was read out of bounds");
winpr_log_backtrace(wTAG, WLOG_FATAL, 20);
return 0;
}
return (_s->length - cur);
}
static INLINE void Stream_Clear(wStream* _s)

View File

@ -133,3 +133,56 @@ void Stream_Free(wStream* s, BOOL bFreeBuffer)
free(s);
}
}
BOOL Stream_SetLength(wStream* _s, size_t _l)
{
if ((_l) > Stream_Capacity(_s))
{
_s->length = 0;
return FALSE;
}
_s->length = _l;
return TRUE;
}
BOOL Stream_SetPosition(wStream* _s, size_t _p)
{
if ((_p) > Stream_Capacity(_s))
{
_s->pointer = _s->buffer;
return FALSE;
}
_s->pointer = _s->buffer + (_p);
return TRUE;
}
#if defined(WITH_WINPR_DEPRECATED)
BOOL Stream_SetPointer(wStream* _s, BYTE* _p)
{
WINPR_ASSERT(_s);
if (!_p || (_s->buffer > _p) || (_s->buffer + _s->capacity < _p))
{
_s->pointer = _s->buffer;
return FALSE;
}
_s->pointer = _p;
return TRUE;
}
BOOL Stream_SetBuffer(wStream* _s, BYTE* _b)
{
WINPR_ASSERT(_s);
WINPR_ASSERT(_b);
_s->buffer = _b;
_s->pointer = _b;
return _s->buffer != NULL;
}
void Stream_SetCapacity(wStream* _s, size_t _c)
{
WINPR_ASSERT(_s);
_s->capacity = _c;
}
#endif