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;