]> git.eshelyaron.com Git - emacs.git/commitdiff
Handle request serial wraparound more correctly
authorPo Lu <luangruo@yahoo.com>
Sat, 12 Nov 2022 10:52:36 +0000 (18:52 +0800)
committerPo Lu <luangruo@yahoo.com>
Sat, 12 Nov 2022 11:01:30 +0000 (19:01 +0800)
* src/xterm.c (X_COMPARE_SERIALS): Remove macro.
(x_is_serial_more_than, x_is_serial_more_than_or_equal_to)
(x_is_serial_less_than, x_is_serial_less_than_or_equal_to): New
functions.
(x_find_error_handler, x_request_can_fail)
(x_clean_failable_requests, x_stop_ignoring_errors): Use those
functions to perform request serial comparison.

src/xterm.c

index b1e74199d716ff2a955b969a5e05933a85883266..e50f669e671304c42329de204a3df754c73207b5 100644 (file)
@@ -912,11 +912,6 @@ struct x_selection_request_event
 
 struct x_selection_request_event *pending_selection_requests;
 
-/* Compare two request serials A and B with OP, handling
-   wraparound.  */
-#define X_COMPARE_SERIALS(a, op ,b) \
-  (((long) (a) - (long) (b)) op 0)
-
 struct x_atom_ref
 {
   /* Atom name.  */
@@ -25084,6 +25079,48 @@ static struct x_error_message_stack *x_error_message;
 /* The amount of items (depth) in that stack.  */
 int x_error_message_count;
 
+/* Compare various request serials while handling wraparound.  Treat a
+   difference of more than X_ULONG_MAX / 2 as wraparound.
+
+   Note that these functions truncate serials to 32 bits before
+   comparison.  */
+
+static bool
+x_is_serial_more_than (unsigned int a, unsigned int b)
+{
+  if (a > b)
+    return true;
+
+  return (b - a > X_ULONG_MAX / 2);
+}
+
+static bool
+x_is_serial_more_than_or_equal_to (unsigned int a, unsigned int b)
+{
+  if (a >= b)
+    return true;
+
+  return (b - a > X_ULONG_MAX / 2);
+}
+
+static bool
+x_is_serial_less_than (unsigned int a, unsigned int b)
+{
+  if (a < b)
+    return true;
+
+  return (a - b > X_ULONG_MAX / 2);
+}
+
+static bool
+x_is_serial_less_than_or_equal_to (unsigned int a, unsigned int b)
+{
+  if (a <= b)
+    return true;
+
+  return (a - b > X_ULONG_MAX / 2);
+}
+
 static struct x_error_message_stack *
 x_find_error_handler (Display *dpy, XErrorEvent *event)
 {
@@ -25093,8 +25130,8 @@ x_find_error_handler (Display *dpy, XErrorEvent *event)
 
   while (stack)
     {
-      if (X_COMPARE_SERIALS (event->serial, >=,
-                            stack->first_request)
+      if (x_is_serial_more_than_or_equal_to (event->serial,
+                                            stack->first_request)
          && dpy == stack->dpy)
        return stack;
 
@@ -25197,11 +25234,11 @@ x_request_can_fail (struct x_display_info *dpyinfo,
        failable_requests < dpyinfo->next_failable_request;
        failable_requests++)
     {
-      if (X_COMPARE_SERIALS (request, >=,
-                            failable_requests->start)
+      if (x_is_serial_more_than_or_equal_to (request,
+                                            failable_requests->start)
          && (!failable_requests->end
-             || X_COMPARE_SERIALS (request, <=,
-                                   failable_requests->end)))
+             || x_is_serial_less_than_or_equal_to (request,
+                                                   failable_requests->end)))
        return failable_requests;
     }
 
@@ -25219,11 +25256,11 @@ x_clean_failable_requests (struct x_display_info *dpyinfo)
 
   for (first = dpyinfo->failable_requests; first < last; first++)
     {
-      if (X_COMPARE_SERIALS (first->start, >,
-                            LastKnownRequestProcessed (dpyinfo->display))
+      if (x_is_serial_more_than (first->start,
+                                LastKnownRequestProcessed (dpyinfo->display))
          || !first->end
-         || X_COMPARE_SERIALS (first->end, >,
-                               LastKnownRequestProcessed (dpyinfo->display)))
+         || x_is_serial_more_than (first->end,
+                                   LastKnownRequestProcessed (dpyinfo->display)))
        break;
     }
 
@@ -25302,8 +25339,7 @@ x_stop_ignoring_errors (struct x_display_info *dpyinfo)
   /* Abort if no request was made since
      `x_ignore_errors_for_next_request'.  */
 
-  if (X_COMPARE_SERIALS (range->end, <,
-                        range->start))
+  if (x_is_serial_less_than (range->end, range->start))
     emacs_abort ();
 
 #ifdef HAVE_GTK3