diff options
-rw-r--r-- | src/XRecord.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/src/XRecord.c b/src/XRecord.c index 6c9b54e..e5357b9 100644 --- a/src/XRecord.c +++ b/src/XRecord.c @@ -725,13 +725,14 @@ parse_reply_call_callback( XRecordInterceptProc callback, XPointer closure) { + XRecordInterceptData *data; unsigned int current_index; int datum_bytes = 0; /* call the callback for each protocol element in the reply */ current_index = 0; do { - XRecordInterceptData *data = alloc_inter_data(info); + data = alloc_inter_data(info); if (!data) return Error; @@ -754,15 +755,15 @@ parse_reply_call_callback( current_index += 4; } if (current_index + 1 > rep->length << 2) - return Error; + goto out; switch (reply->buf[current_index]) { case X_Reply: /* reply */ if (current_index + 8 > rep->length << 2) - return Error; + goto out; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index+4, datum_bytes); if (datum_bytes < 0 || datum_bytes > ((INT_MAX >> 2) - 8)) - return Error; + goto out; datum_bytes = (datum_bytes+8) << 2; break; default: /* error or event */ @@ -772,7 +773,7 @@ parse_reply_call_callback( case XRecordFromClient: if (rep->elementHeader&XRecordFromClientTime) { if (current_index + 4 > rep->length << 2) - return Error; + goto out; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index, data->server_time); @@ -780,19 +781,19 @@ parse_reply_call_callback( } if (rep->elementHeader&XRecordFromClientSequence) { if (current_index + 4 > rep->length << 2) - return Error; + goto out; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index, data->client_seq); current_index += 4; } if (current_index + 4 > rep->length<<2) - return Error; + goto out; if (reply->buf[current_index+2] == 0 && reply->buf[current_index+3] == 0) /* needn't swap 0 */ { /* BIG-REQUESTS */ if (current_index + 8 > rep->length << 2) - return Error; + goto out; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index+4, datum_bytes); } else { @@ -800,12 +801,12 @@ parse_reply_call_callback( reply->buf+current_index+2, datum_bytes); } if (datum_bytes < 0 || datum_bytes > INT_MAX >> 2) - return Error; + goto out; datum_bytes <<= 2; break; case XRecordClientStarted: if (current_index + 8 > rep->length << 2) - return Error; + goto out; EXTRACT_CARD16(rep->clientSwapped, reply->buf+current_index+6, datum_bytes); datum_bytes = (datum_bytes+2) << 2; @@ -813,19 +814,19 @@ parse_reply_call_callback( case XRecordClientDied: if (rep->elementHeader&XRecordFromClientSequence) { if (current_index + 4 > rep->length << 2) - return Error; + goto out; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index, data->client_seq); current_index += 4; } else if (current_index < rep->length << 2) - return Error; + goto out; datum_bytes = 0; break; case XRecordStartOfData: case XRecordEndOfData: if (current_index < rep->length << 2) - return Error; + goto out; datum_bytes = 0; break; } @@ -836,7 +837,7 @@ parse_reply_call_callback( "XRecord: %lu-byte reply claims %d-byte element (seq %lu)\n", (unsigned long)rep->length << 2, current_index + datum_bytes, dpy->last_request_read); - return Error; + goto out; } /* * This assignment (and indeed the whole buffer sharing @@ -859,6 +860,9 @@ parse_reply_call_callback( return End; return Continue; +out: + Xfree(data); + return Error; } Status |