diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 27dd0333d..66b06d165 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -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 (!Stream_EnsureRemainingCapacity(fastpath->updateData, DstSize)) + return -1; - if (!(cs = StreamPool_Take(transport->ReceivePool, 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); } diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index e1bf29168..a1733ea9b 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -236,17 +236,14 @@ BOOL freerdp_connect(freerdp* instance) update = instance->update; update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); + status = FALSE; if (!update->pcap_rfx) - { - status = FALSE; 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; } }