Commit 704fdc48 for guacamole.apache.org
commit 704fdc487581195cc5bfccad1b816527c24153b2
Author: Michael Jumper <mjumper@apache.org>
Date: Sat Jul 11 16:08:24 2026 -0700
GUACAMOLE-2118: Correct potential infinite loop in guac_display_frame_complete().
diff --git a/src/libguac/display-flush.c b/src/libguac/display-flush.c
index c3985431..c3a403d4 100644
--- a/src/libguac/display-flush.c
+++ b/src/libguac/display-flush.c
@@ -115,15 +115,20 @@ static int PFW_LFW_guac_display_frame_complete(guac_display* display) {
int retval = 0;
display->last_frame.layers = display->pending_frame.layers;
- guac_display_layer* current = display->pending_frame.layers;
- while (current != NULL) {
+ for (guac_display_layer* current = display->pending_frame.layers;
+ current != NULL; current = current->pending_frame.next) {
- /* Skip processing any layers whose buffers have been replaced with
- * NULL (this is intentionally allowed to ensure references to external
- * buffers can be safely removed if necessary, even before guac_display
- * is freed) */
+ /* Duplicate layers from pending frame to last frame */
+ current->last_frame.prev = current->pending_frame.prev;
+ current->last_frame.next = current->pending_frame.next;
+
+ /* Skip non-existential updates for any layer whose buffer has been
+ * replaced with NULL (this is intentionally allowed to ensure references
+ * to external buffers can be safely removed if necessary, even before
+ * guac_display is freed) */
if (current->pending_frame.buffer == NULL) {
GUAC_ASSERT(current->pending_frame.buffer_is_external);
+ current->last_frame.dirty = (guac_rect) { 0 };
continue;
}
@@ -251,11 +256,6 @@ static int PFW_LFW_guac_display_frame_complete(guac_display* display) {
* to the client - it affects only how last_frame is interpreted) */
current->last_frame.lossless = current->pending_frame.lossless;
- /* Duplicate layers from pending frame to last frame */
- current->last_frame.prev = current->pending_frame.prev;
- current->last_frame.next = current->pending_frame.next;
- current = current->pending_frame.next;
-
}
display->last_frame.timestamp = display->pending_frame.timestamp;