From 26dfc533bdb7bc142b565ce29d9d27da6de9ba6a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Jan 2020 14:53:57 -0800 Subject: [PATCH] GUACAMOLE-935: Free internals of rdpBitmap only when required. In FreeRDP 2.0.0-rc0 and earlier, Bitmap_Free(bitmap) invokes the free handler of the given bitmap, frees bitmap->data, and then frees the bitmap. The implementation-specific free handler needs to be aware only of the implementation's own concerns. After FreeRDP 2.0.0-rc0, Bitmap_Free(bitmap) only invokes the implementation-specific free handler, and it's on the implementation to know that bitmap->data must be manually freed with _aligned_free() and bitmap must be freed with free(). The implementation-specific free handler must be aware of the internals of the library. See commit 8dda26a. --- configure.ac | 31 +++++++++++++++++++++++++++++++ src/protocols/rdp/bitmap.c | 9 ++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 24c15884..cac4307f 100644 --- a/configure.ac +++ b/configure.ac @@ -578,6 +578,37 @@ then fi +# Variation in memory internal allocation/free behavior +if test "x${have_freerdp2}" = "xyes" +then + + # FreeRDP 2.0.0-rc0 and older automatically free rdpBitmap and its + # associated data member within Bitmap_Free(), relying on the + # implementation-specific free handler to free only implementation-specific + # data. This changed in commit 2cf10cc, and implementations must now + # manually free all data associated with the rdpBitmap, even data which + # was not allocated by the implementation. + AC_MSG_CHECKING([whether Bitmap_Free() frees the rdpBitmap and its image data]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + + #include + + #include + + int main() { + /* Return successfully if version is 2.0.0-rc0 */ + return strcmp(FREERDP_VERSION_FULL, "2.0.0-dev"); + } + + ]])], + [AC_MSG_RESULT([yes])] + [AC_DEFINE([FREERDP_BITMAP_FREE_FREES_BITMAP],, + [Whether Bitmap_Free() frees the rdpBitmap and its image data])], + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([assuming no (cross-compiling)])]) + +fi + # Glyph callback variants if test "x${have_freerdp2}" = "xyes" then diff --git a/src/protocols/rdp/bitmap.c b/src/protocols/rdp/bitmap.c index db293162..ac4d9794 100644 --- a/src/protocols/rdp/bitmap.c +++ b/src/protocols/rdp/bitmap.c @@ -20,6 +20,7 @@ #include "bitmap.h" #include "common/display.h" #include "common/surface.h" +#include "config.h" #include "rdp.h" #include @@ -127,12 +128,14 @@ void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) { if (buffer != NULL) guac_common_display_free_buffer(rdp_client->display, buffer); - /* NOTE: FreeRDP-allocated memory for the rdpBitmap will NOT be - * automatically released after this free handler is invoked, thus we must - * do so manually here */ +#ifndef FREERDP_BITMAP_FREE_FREES_BITMAP + /* NOTE: Except in FreeRDP 2.0.0-rc0 and earlier, FreeRDP-allocated memory + * for the rdpBitmap will NOT be automatically released after this free + * handler is invoked, thus we must do so manually here */ _aligned_free(bitmap->data); free(bitmap); +#endif }