From c2d481aaacd51e82fd02cb24095a752ce0c76dde Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Wed, 17 Jul 2024 18:50:18 +0200 Subject: [PATCH] Xext: xv: ProcDbeGetVisualInfo() collect payload in buffer before writing The payload lengths is already known, so we can easily collect the data in a stack buffer and only need one WriteToClient() operation. This also clears the road for further simplification/unification of the reply sending code, coming with follow-up commits. Signed-off-by: Enrico Weigelt, metux IT consult --- Xext/xvdisp.c | 54 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c index 7bb87e510a..879f781bbd 100644 --- a/Xext/xvdisp.c +++ b/Xext/xvdisp.c @@ -621,28 +621,29 @@ ProcXvQueryPortAttributes(ClientPtr client) int size, i; XvPortPtr pPort; XvAttributePtr pAtt; - xvAttributeInfo Info; REQUEST(xvQueryPortAttributesReq); REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess); + int text_size = 0; + for (i = 0, pAtt = pPort->pAdaptor->pAttributes; + i < pPort->pAdaptor->nAttributes; i++, pAtt++) { + text_size += pad_to_int32(strlen(pAtt->name) + 1); + } + + int length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo) + + text_size; + xvQueryPortAttributesReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .num_attributes = pPort->pAdaptor->nAttributes, + .length = bytes_to_int32(length), + .text_size = text_size, }; - for (i = 0, pAtt = pPort->pAdaptor->pAttributes; - i < pPort->pAdaptor->nAttributes; i++, pAtt++) { - rep.text_size += pad_to_int32(strlen(pAtt->name) + 1); - } - - rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo) - + rep.text_size; - rep.length >>= 2; - if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); @@ -650,27 +651,38 @@ ProcXvQueryPortAttributes(ClientPtr client) swapl(&rep.text_size); } - WriteToClient(client, sizeof(rep), &rep); + char *buf = calloc(1, length); + if (!buf) + return BadAlloc; + + char * walk = buf; for (i = 0, pAtt = pPort->pAdaptor->pAttributes; i < pPort->pAdaptor->nAttributes; i++, pAtt++) { size = strlen(pAtt->name) + 1; /* pass the NULL */ - Info.flags = pAtt->flags; - Info.min = pAtt->min_value; - Info.max = pAtt->max_value; - Info.size = pad_to_int32(size); + + xvAttributeInfo *Info = (xvAttributeInfo*)walk; + Info->flags = pAtt->flags; + Info->min = pAtt->min_value; + Info->max = pAtt->max_value; + Info->size = pad_to_int32(size); if (client->swapped) { - swapl(&Info.flags); - swapl(&Info.size); - swapl(&Info.min); - swapl(&Info.max); + swapl(&Info->flags); + swapl(&Info->size); + swapl(&Info->min); + swapl(&Info->max); } - WriteToClient(client, sizeof(Info), &Info); - WriteToClient(client, size, pAtt->name); + walk += sizeof(xvAttributeInfo); + + memcpy(walk, pAtt->name, size); + walk += pad_to_int32(size); } + WriteToClient(client, sizeof(rep), &rep); + WriteToClient(client, length, buf); + free(buf); return Success; }