diff --git a/dix/rpcbuf.c b/dix/rpcbuf.c index 05b77867e9..de9dfcd560 100644 --- a/dix/rpcbuf.c +++ b/dix/rpcbuf.c @@ -16,10 +16,8 @@ Bool x_rpcbuf_makeroom(struct x_rpcbuf *rpcbuf, size_t needed) /* not allocated yet ? */ if (!rpcbuf->buffer) { - if (!(rpcbuf->buffer = calloc(1, XLIBRE_RPCBUF_CHUNK_SIZE))) { - rpcbuf->error = TRUE; - return FALSE; - } + if (!(rpcbuf->buffer = calloc(1, XLIBRE_RPCBUF_CHUNK_SIZE))) + goto err; rpcbuf->size = XLIBRE_RPCBUF_CHUNK_SIZE; rpcbuf->wpos = 0; } @@ -32,15 +30,22 @@ Bool x_rpcbuf_makeroom(struct x_rpcbuf *rpcbuf, size_t needed) * XLIBRE_RPCBUF_CHUNK_SIZE; char *newbuf = realloc(rpcbuf->buffer, newsize); - if (!newbuf) { - rpcbuf->error = TRUE; - return FALSE; - } + if (!newbuf) + goto err; + memset(newbuf + rpcbuf->size, 0, newsize - rpcbuf->size); rpcbuf->buffer = newbuf; rpcbuf->size = newsize; return TRUE; + +err: + rpcbuf->error = TRUE; + if (rpcbuf->err_clear) { + free(rpcbuf->buffer); + rpcbuf->buffer = NULL; + } + return FALSE; } void x_rpcbuf_clear(struct x_rpcbuf *rpcbuf) diff --git a/dix/rpcbuf_priv.h b/dix/rpcbuf_priv.h index 725791be70..f853f66f61 100644 --- a/dix/rpcbuf_priv.h +++ b/dix/rpcbuf_priv.h @@ -32,6 +32,7 @@ typedef struct x_rpcbuf { char *buffer; /* pointer to whole buffer */ Bool swapped; /* TRUE when typed write operation shall byte-swap */ Bool error; /* TRUE when the last allocation failed */ + Bool err_clear; /* set to TRUE if should automatically clear on error */ } x_rpcbuf_t; #define XLIBRE_RPCBUF_CHUNK_SIZE 4096