diff --git a/libfreerdp-core/fastpath.c b/libfreerdp-core/fastpath.c index 035ed9474..c91566653 100644 --- a/libfreerdp-core/fastpath.c +++ b/libfreerdp-core/fastpath.c @@ -42,13 +42,28 @@ #define FASTPATH_MAX_PACKET_SIZE 0x3FFF +/* + * The fastpath header may be two or three bytes long. + * This function assumes that at least two bytes are available in the stream + * and doesn't touch third byte. + */ +uint16 fastpath_header_length(STREAM* s) +{ + uint8 length1; + + stream_seek_uint8(s); + stream_read_uint8(s, length1); + stream_rewind(s, 2); + + return ((length1 & 0x80) != 0 ? 3 : 2); +} + /** * Read a Fast-Path packet header.\n * @param s stream * @param encryptionFlags * @return length */ - uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s) { uint8 header; diff --git a/libfreerdp-core/fastpath.h b/libfreerdp-core/fastpath.h index 70e90bcac..428ce5593 100644 --- a/libfreerdp-core/fastpath.h +++ b/libfreerdp-core/fastpath.h @@ -102,6 +102,7 @@ struct rdp_fastpath STREAM* updateData; }; +uint16 fastpath_header_length(STREAM* s); uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s); uint16 fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s); boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s); diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c index 0ec9d77c6..0bfc62f36 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp-core/transport.c @@ -312,6 +312,13 @@ int transport_check_fds(rdpTransport* transport) stream_set_pos(transport->recv_buffer, pos); return 0; } + /* Fastpath header can be two or three bytes long. */ + length = fastpath_header_length(transport->recv_buffer); + if (pos < length) + { + stream_set_pos(transport->recv_buffer, pos); + return 0; + } length = fastpath_read_header(NULL, transport->recv_buffer); }