Merge pull request #4481 from akallabeth/fastpath_fix
Fastpath uncompressed length issue
This commit is contained in:
commit
0af63d4c6f
@ -328,7 +328,7 @@ static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 size, wStream* s)
|
||||
static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, wStream* s)
|
||||
{
|
||||
int status = 0;
|
||||
rdpUpdate* update;
|
||||
@ -346,9 +346,9 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
||||
context = update->context;
|
||||
pointer = update->pointer;
|
||||
#ifdef WITH_DEBUG_RDP
|
||||
DEBUG_RDP("recv Fast-Path %s Update (0x%02"PRIX8"), length:%"PRIu32"",
|
||||
DEBUG_RDP("recv Fast-Path %s Update (0x%02"PRIX8"), length:%"PRIuz"",
|
||||
updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] :
|
||||
"???", updateCode, size);
|
||||
"???", updateCode, Stream_GetLength(s));
|
||||
#endif
|
||||
|
||||
switch (updateCode)
|
||||
@ -451,10 +451,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
int status;
|
||||
UINT16 size;
|
||||
rdpRdp* rdp;
|
||||
size_t next_pos;
|
||||
wStream* cs;
|
||||
int bulkStatus;
|
||||
UINT32 totalSize;
|
||||
BYTE updateCode;
|
||||
BYTE fragmentation;
|
||||
BYTE compression;
|
||||
@ -501,10 +498,9 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
cs = s;
|
||||
next_pos = Stream_GetPosition(s) + size;
|
||||
bulkStatus = bulk_decompress(rdp->bulk, Stream_Pointer(s), size, &pDstData, &DstSize,
|
||||
compressionFlags);
|
||||
Stream_Seek(s, size);
|
||||
|
||||
if (bulkStatus < 0)
|
||||
{
|
||||
@ -512,19 +508,10 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bulkStatus > 0)
|
||||
{
|
||||
/* data was compressed, copy from decompression buffer */
|
||||
size = DstSize;
|
||||
|
||||
if (!(cs = StreamPool_Take(transport->ReceivePool, DstSize)))
|
||||
if (!Stream_EnsureRemainingCapacity(fastpath->updateData, DstSize))
|
||||
return -1;
|
||||
|
||||
Stream_SetPosition(cs, 0);
|
||||
Stream_Write(cs, pDstData, DstSize);
|
||||
Stream_SealLength(cs);
|
||||
Stream_SetPosition(cs, 0);
|
||||
}
|
||||
Stream_Write(fastpath->updateData, pDstData, DstSize);
|
||||
|
||||
if (fragmentation == FASTPATH_FRAGMENT_SINGLE)
|
||||
{
|
||||
@ -534,8 +521,10 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
totalSize = size;
|
||||
status = fastpath_recv_update(fastpath, updateCode, totalSize, cs);
|
||||
Stream_SealLength(fastpath->updateData);
|
||||
Stream_SetPosition(fastpath->updateData, 0);
|
||||
status = fastpath_recv_update(fastpath, updateCode, fastpath->updateData);
|
||||
Stream_SetPosition(fastpath->updateData, 0);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@ -545,6 +534,14 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t totalSize = Stream_GetPosition(fastpath->updateData);
|
||||
if (totalSize > transport->settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "Total size (%"PRIuz") exceeds MultifragMaxRequestSize (%"PRIu32")",
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (fragmentation == FASTPATH_FRAGMENT_FIRST)
|
||||
{
|
||||
if (fastpath->fragmentation != -1)
|
||||
@ -554,20 +551,8 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
}
|
||||
|
||||
fastpath->fragmentation = FASTPATH_FRAGMENT_FIRST;
|
||||
totalSize = size;
|
||||
|
||||
if (totalSize > transport->settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "Total size (%"PRIu32") exceeds MultifragMaxRequestSize (%"PRIu32")",
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (!(fastpath->updateData = StreamPool_Take(transport->ReceivePool, size)))
|
||||
goto out_fail;
|
||||
|
||||
Stream_SetPosition(fastpath->updateData, 0);
|
||||
Stream_Copy(cs, fastpath->updateData, size);
|
||||
}
|
||||
else if (fragmentation == FASTPATH_FRAGMENT_NEXT)
|
||||
{
|
||||
@ -579,22 +564,6 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
}
|
||||
|
||||
fastpath->fragmentation = FASTPATH_FRAGMENT_NEXT;
|
||||
totalSize = Stream_GetPosition(fastpath->updateData) + size;
|
||||
|
||||
if (totalSize > transport->settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "Total size (%"PRIu32") exceeds MultifragMaxRequestSize (%"PRIu32")",
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (!Stream_EnsureCapacity(fastpath->updateData, totalSize))
|
||||
{
|
||||
WLog_ERR(TAG, "Couldn't re-allocate memory for stream");
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
Stream_Copy(cs, fastpath->updateData, size);
|
||||
}
|
||||
else if (fragmentation == FASTPATH_FRAGMENT_LAST)
|
||||
{
|
||||
@ -606,26 +575,11 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
}
|
||||
|
||||
fastpath->fragmentation = -1;
|
||||
totalSize = Stream_GetPosition(fastpath->updateData) + size;
|
||||
|
||||
if (totalSize > transport->settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "Total size (%"PRIu32") exceeds MultifragMaxRequestSize (%"PRIu32")",
|
||||
totalSize, transport->settings->MultifragMaxRequestSize);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (!Stream_EnsureCapacity(fastpath->updateData, totalSize))
|
||||
{
|
||||
WLog_ERR(TAG, "Couldn't re-allocate memory for stream");
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
Stream_Copy(cs, fastpath->updateData, size);
|
||||
Stream_SealLength(fastpath->updateData);
|
||||
Stream_SetPosition(fastpath->updateData, 0);
|
||||
status = fastpath_recv_update(fastpath, updateCode, totalSize, fastpath->updateData);
|
||||
Stream_Release(fastpath->updateData);
|
||||
status = fastpath_recv_update(fastpath, updateCode, fastpath->updateData);
|
||||
Stream_SetPosition(fastpath->updateData, 0);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@ -635,19 +589,9 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
||||
}
|
||||
}
|
||||
|
||||
Stream_SetPosition(s, next_pos);
|
||||
|
||||
if (cs != s)
|
||||
Stream_Release(cs);
|
||||
|
||||
return status;
|
||||
out_fail:
|
||||
|
||||
if (cs != s)
|
||||
{
|
||||
Stream_Release(cs);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1244,13 +1188,14 @@ rdpFastPath* fastpath_new(rdpRdp* rdp)
|
||||
fastpath->rdp = rdp;
|
||||
fastpath->fragmentation = -1;
|
||||
fastpath->fs = Stream_New(NULL, FASTPATH_MAX_PACKET_SIZE);
|
||||
fastpath->updateData = Stream_New(NULL, FASTPATH_MAX_PACKET_SIZE);
|
||||
|
||||
if (!fastpath->fs)
|
||||
if (!fastpath->fs || !fastpath->updateData)
|
||||
goto out_free;
|
||||
|
||||
return fastpath;
|
||||
out_free:
|
||||
free(fastpath);
|
||||
fastpath_free(fastpath);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1258,6 +1203,7 @@ void fastpath_free(rdpFastPath* fastpath)
|
||||
{
|
||||
if (fastpath)
|
||||
{
|
||||
Stream_Free(fastpath->updateData, TRUE);
|
||||
Stream_Free(fastpath->fs, TRUE);
|
||||
free(fastpath);
|
||||
}
|
||||
|
@ -236,17 +236,14 @@ BOOL freerdp_connect(freerdp* instance)
|
||||
update = instance->update;
|
||||
update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
|
||||
|
||||
if (!update->pcap_rfx)
|
||||
{
|
||||
status = FALSE;
|
||||
if (!update->pcap_rfx)
|
||||
goto freerdp_connect_finally;
|
||||
}
|
||||
else
|
||||
{
|
||||
update->play_rfx = TRUE;
|
||||
}
|
||||
|
||||
while (pcap_has_next_record(update->pcap_rfx))
|
||||
status = TRUE;
|
||||
while (pcap_has_next_record(update->pcap_rfx) && status)
|
||||
{
|
||||
pcap_get_next_record_header(update->pcap_rfx, &record);
|
||||
|
||||
@ -257,15 +254,19 @@ BOOL freerdp_connect(freerdp* instance)
|
||||
pcap_get_next_record_content(update->pcap_rfx, &record);
|
||||
Stream_SetLength(s, record.length);
|
||||
Stream_SetPosition(s, 0);
|
||||
update->BeginPaint(update->context);
|
||||
update_recv_surfcmds(update, s);
|
||||
update->EndPaint(update->context);
|
||||
|
||||
if (!update->BeginPaint(update->context))
|
||||
status = FALSE;
|
||||
else if (update_recv_surfcmds(update, s) < 0)
|
||||
status = FALSE;
|
||||
else if (!update->EndPaint(update->context))
|
||||
status = FALSE;
|
||||
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
pcap_close(update->pcap_rfx);
|
||||
update->pcap_rfx = NULL;
|
||||
status = TRUE;
|
||||
goto freerdp_connect_finally;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user