File U_0005-Prepare-for-_XIOError-possibly-returning.patch of Package libX11.28097
From 4cb758019e374fa7c022fe79d28444e13441717b Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 14 Jun 2019 17:54:47 +0200
Subject: [PATCH] Prepare for _XIOError() possibly returning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ensure current state is cut short on _XIOError(), possible reentrancy
should be skipped through the XlibDisplayIOError flag checks.
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
---
src/XlibInt.c | 2 ++
src/xcb_io.c | 62 ++++++++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 46 insertions(+), 18 deletions(-)
Index: libX11-1.6.5/src/XlibInt.c
===================================================================
--- libX11-1.6.5.orig/src/XlibInt.c
+++ libX11-1.6.5/src/XlibInt.c
@@ -656,6 +656,7 @@ _XStoreEventCookie(Display *dpy, XEvent
if (!add) {
ESET(ENOMEM);
_XIOError(dpy);
+ return;
}
add->ev = *cookie;
DL_APPEND(*head, add);
@@ -730,6 +731,7 @@ void _XEnq(
/* Malloc call failed! */
ESET(ENOMEM);
_XIOError(dpy);
+ return;
}
qelt->next = NULL;
Index: libX11-1.6.5/src/xcb_io.c
===================================================================
--- libX11-1.6.5.orig/src/xcb_io.c
+++ libX11-1.6.5/src/xcb_io.c
@@ -55,7 +55,7 @@ static void return_socket(void *closure)
UnlockDisplay(dpy);
}
-static void require_socket(Display *dpy)
+static Bool require_socket(Display *dpy)
{
if(dpy->bufmax == dpy->buffer)
{
@@ -66,12 +66,15 @@ static void require_socket(Display *dpy)
if(dpy->xcb->event_owner != XlibOwnsEventQueue)
flags = XCB_REQUEST_CHECKED;
if(!xcb_take_socket(dpy->xcb->connection, return_socket, dpy,
- flags, &sent))
+ flags, &sent)) {
_XIOError(dpy);
+ return False;
+ }
dpy->xcb->last_flushed = sent;
X_DPY_SET_REQUEST(dpy, sent);
dpy->bufmax = dpy->xcb->real_bufmax;
}
+ return True;
}
/* Call internal connection callbacks for any fds that are currently
@@ -91,7 +94,7 @@ static void require_socket(Display *dpy)
* _XEatData
* _XReadPad
*/
-static void check_internal_connections(Display *dpy)
+static Bool check_internal_connections(Display *dpy)
{
struct _XConnectionInfo *ilist;
fd_set r_mask;
@@ -100,7 +103,7 @@ static void check_internal_connections(D
int highest_fd = -1;
if(dpy->flags & XlibDisplayProcConni || !dpy->im_fd_info)
- return;
+ return True;
FD_ZERO(&r_mask);
for(ilist = dpy->im_fd_info; ilist; ilist = ilist->next)
@@ -118,9 +121,12 @@ static void check_internal_connections(D
if(result == -1)
{
- if(errno == EINTR)
- return;
- _XIOError(dpy);
+ if(errno != EINTR) {
+ _XIOError(dpy);
+ return False;
+ }
+
+ return True;
}
for(ilist = dpy->im_fd_info; result && ilist; ilist = ilist->next)
@@ -129,6 +135,8 @@ static void check_internal_connections(D
_XProcessInternalConnection(dpy, ilist);
--result;
}
+
+ return True;
}
static PendingRequest *append_pending_request(Display *dpy, uint64_t sequence)
@@ -233,7 +241,8 @@ static void widen(uint64_t *wide, unsign
static xcb_generic_reply_t *poll_for_event(Display *dpy, Bool queued_only)
{
/* Make sure the Display's sequence numbers are valid */
- require_socket(dpy);
+ if (!require_socket(dpy))
+ return NULL;
/* Precondition: This thread can safely get events from XCB. */
assert(dpy->xcb->event_owner == XlibOwnsEventQueue && !dpy->xcb->event_waiter);
@@ -351,8 +360,8 @@ int _XEventsQueued(Display *dpy, int mod
if(mode == QueuedAfterFlush)
_XSend(dpy, NULL, 0);
- else
- check_internal_connections(dpy);
+ else if (!check_internal_connections(dpy))
+ return 0;
/* If another thread is blocked waiting for events, then we must
* let that thread pick up the next event. Since it blocked, we
@@ -361,8 +370,10 @@ int _XEventsQueued(Display *dpy, int mod
{
while((response = poll_for_response(dpy)))
handle_response(dpy, response, False);
- if(xcb_connection_has_error(dpy->xcb->connection))
+ if(xcb_connection_has_error(dpy->xcb->connection)) {
_XIOError(dpy);
+ return 0;
+ }
}
return dpy->qlen;
}
@@ -380,7 +391,8 @@ void _XReadEvents(Display *dpy)
_XSend(dpy, NULL, 0);
if(dpy->xcb->event_owner != XlibOwnsEventQueue)
return;
- check_internal_connections(dpy);
+ if (!check_internal_connections(dpy))
+ return;
serial = dpy->next_event_serial_num;
while(serial == dpy->next_event_serial_num || dpy->qlen == 0)
@@ -410,7 +422,10 @@ void _XReadEvents(Display *dpy)
dpy->xcb->event_waiter = 0;
ConditionBroadcast(dpy, dpy->xcb->event_notify);
if(!event)
+ {
_XIOError(dpy);
+ return;
+ }
dpy->xcb->next_event = event;
}
@@ -428,7 +443,10 @@ void _XReadEvents(Display *dpy)
ConditionWait(dpy, dpy->xcb->reply_notify);
}
else
- _XIOError(dpy);
+ {
+ _XIOError(dpy);
+ return;
+ }
}
/* The preceding loop established that there is no
@@ -496,12 +514,15 @@ void _XSend(Display *dpy, const char *da
ext->before_flush(dpy, &ext->codes, vec[i].iov_base, vec[i].iov_len);
}
- if(xcb_writev(c, vec, 3, requests) < 0)
+ if(xcb_writev(c, vec, 3, requests) < 0) {
_XIOError(dpy);
+ return;
+ }
dpy->bufptr = dpy->buffer;
dpy->last_req = (char *) &dummy_request;
- check_internal_connections(dpy);
+ if (!check_internal_connections(dpy))
+ return;
_XSetSeqSyncFunction(dpy);
}
@@ -512,7 +533,9 @@ void _XSend(Display *dpy, const char *da
*/
void _XFlush(Display *dpy)
{
- require_socket(dpy);
+ if (!require_socket(dpy))
+ return;
+
_XSend(dpy, NULL, 0);
_XEventsQueued(dpy, QueuedAfterReading);
@@ -657,7 +680,8 @@ Status _XReply(Display *dpy, xReply *rep
else if(response)
handle_response(dpy, response, True);
}
- check_internal_connections(dpy);
+ if (!check_internal_connections(dpy))
+ return 0;
if(dpy->xcb->next_event && dpy->xcb->next_event->response_type == X_Error)
{
@@ -712,8 +736,10 @@ Status _XReply(Display *dpy, xReply *rep
/* it's not an error, but we don't have a reply, so it's an I/O
* error. */
- if(!reply)
+ if(!reply) {
_XIOError(dpy);
+ return 0;
+ }
/* there's no error and we have a reply. */
dpy->xcb->reply_data = reply;