Bug Summary

File:dix/property.c
Location:line 271, column 9
Description:Null pointer argument in call to memory copy function

Annotated Source Code

1/***********************************************************
2
3Copyright 1987, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
26
27 All Rights Reserved
28
29Permission to use, copy, modify, and distribute this software and its
30documentation for any purpose and without fee is hereby granted,
31provided that the above copyright notice appear in all copies and that
32both that copyright notice and this permission notice appear in
33supporting documentation, and that the name of Digital not be
34used in advertising or publicity pertaining to distribution of the
35software without specific, written prior permission.
36
37DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43SOFTWARE.
44
45******************************************************************/
46
47#ifdef HAVE_DIX_CONFIG_H1
48#include <dix-config.h>
49#endif
50
51#include <X11/X.h>
52#include <X11/Xproto.h>
53#include "windowstr.h"
54#include "propertyst.h"
55#include "dixstruct.h"
56#include "dispatch.h"
57#include "swaprep.h"
58#include "xace.h"
59
60/*****************************************************************
61 * Property Stuff
62 *
63 * dixLookupProperty, dixChangeProperty, DeleteProperty
64 *
65 * Properties belong to windows. The list of properties should not be
66 * traversed directly. Instead, use the three functions listed above.
67 *
68 *****************************************************************/
69
70#ifdef notdef
71static void
72PrintPropertys(WindowPtr pWin)
73{
74 PropertyPtr pProp;
75 int j;
76
77 pProp = pWin->userProps;
78 while (pProp) {
79 ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type);
80 ErrorF("[dix] property format: %d\n", pProp->format);
81 ErrorF("[dix] property data: \n");
82 for (j = 0; j < (pProp->format / 8) * pProp->size; j++)
83 ErrorF("[dix] %c\n", pProp->data[j]);
84 pProp = pProp->next;
85 }
86}
87#endif
88
89int
90dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName,
91 ClientPtr client, Mask access_mode)
92{
93 PropertyPtr pProp;
94 int rc = BadMatch8;
95
96 client->errorValue = propertyName;
97
98 for (pProp = wUserProps(pWin)((pWin)->optional ? (pWin)->optional->userProps : ((
void*)0))
; pProp; pProp = pProp->next)
99 if (pProp->propertyName == propertyName)
100 break;
101
102 if (pProp)
103 rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode);
104 *result = pProp;
105 return rc;
106}
107
108static void
109deliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom)
110{
111 xEvent event;
112 UpdateCurrentTimeIf();
113 event.u.property.window = pWin->drawable.id;
114 event.u.property.state = state;
115 event.u.property.atom = atom;
116 event.u.property.time = currentTime.milliseconds;
117 event.u.u.type = PropertyNotify28;
118 DeliverEvents(pWin, &event, 1, (WindowPtr) NULL((void*)0));
119}
120
121int
122ProcRotateProperties(ClientPtr client)
123{
124 int i, j, delta, rc;
125
126 REQUEST(xRotatePropertiesReq)xRotatePropertiesReq *stuff = (xRotatePropertiesReq *)client->
requestBuffer
;
127 WindowPtr pWin;
128 Atom *atoms;
129 PropertyPtr *props; /* array of pointer */
130 PropertyPtr pProp, saved;
131
132 REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2)if (((sizeof(xRotatePropertiesReq) >> 2) > client->
req_len) || (((stuff->nAtoms << 2) >> 2) >=
client->req_len) || ((((uint64_t) sizeof(xRotatePropertiesReq
) + (stuff->nAtoms << 2) + 3) >> 2) != (uint64_t
) client->req_len)) return(16)
;
133 UpdateCurrentTime();
134 rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess(1<<8));
135 if (rc != Success0 || stuff->nAtoms <= 0)
136 return rc;
137
138 atoms = (Atom *) &stuff[1];
139 props = xallocarray(stuff->nAtoms, sizeof(PropertyPtr))xreallocarray(((void*)0), (stuff->nAtoms), (sizeof(PropertyPtr
)))
;
140 saved = xallocarray(stuff->nAtoms, sizeof(PropertyRec))xreallocarray(((void*)0), (stuff->nAtoms), (sizeof(PropertyRec
)))
;
141 if (!props || !saved) {
142 rc = BadAlloc11;
143 goto out;
144 }
145
146 for (i = 0; i < stuff->nAtoms; i++) {
147 if (!ValidAtom(atoms[i])) {
148 rc = BadAtom5;
149 client->errorValue = atoms[i];
150 goto out;
151 }
152 for (j = i + 1; j < stuff->nAtoms; j++)
153 if (atoms[j] == atoms[i]) {
154 rc = BadMatch8;
155 goto out;
156 }
157
158 rc = dixLookupProperty(&pProp, pWin, atoms[i], client,
159 DixReadAccess(1<<0) | DixWriteAccess(1<<1));
160 if (rc != Success0)
161 goto out;
162
163 props[i] = pProp;
164 saved[i] = *pProp;
165 }
166 delta = stuff->nPositions;
167
168 /* If the rotation is a complete 360 degrees, then moving the properties
169 around and generating PropertyNotify events should be skipped. */
170
171 if (abs(delta) % stuff->nAtoms) {
172 while (delta < 0) /* faster if abs value is small */
173 delta += stuff->nAtoms;
174 for (i = 0; i < stuff->nAtoms; i++) {
175 j = (i + delta) % stuff->nAtoms;
176 deliverPropertyNotifyEvent(pWin, PropertyNewValue0, atoms[i]);
177
178 /* Preserve name and devPrivates */
179 props[j]->type = saved[i].type;
180 props[j]->format = saved[i].format;
181 props[j]->size = saved[i].size;
182 props[j]->data = saved[i].data;
183 }
184 }
185 out:
186 free(saved);
187 free(props);
188 return rc;
189}
190
191int
192ProcChangeProperty(ClientPtr client)
193{
194 WindowPtr pWin;
195 char format, mode;
196 unsigned long len;
197 int sizeInBytes, totalSize, err;
198
199 REQUEST(xChangePropertyReq)xChangePropertyReq *stuff = (xChangePropertyReq *)client->
requestBuffer
;
200
201 REQUEST_AT_LEAST_SIZE(xChangePropertyReq)if ((sizeof(xChangePropertyReq) >> 2) > client->req_len
) return(16)
;
202 UpdateCurrentTime();
203 format = stuff->format;
204 mode = stuff->mode;
205 if ((mode != PropModeReplace0) && (mode != PropModeAppend2) &&
1
Assuming 'mode' is equal to 0
206 (mode != PropModePrepend1)) {
207 client->errorValue = mode;
208 return BadValue2;
209 }
210 if ((format != 8) && (format != 16) && (format != 32)) {
2
Assuming 'format' is not equal to 8
3
Assuming 'format' is equal to 16
211 client->errorValue = format;
212 return BadValue2;
213 }
214 len = stuff->nUnits;
215 if (len > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq)))
4
Taking false branch
216 return BadLength16;
217 sizeInBytes = format >> 3;
218 totalSize = len * sizeInBytes;
219 REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize)if (((sizeof(xChangePropertyReq) >> 2) > client->
req_len) || (((totalSize) >> 2) >= client->req_len
) || ((((uint64_t) sizeof(xChangePropertyReq) + (totalSize) +
3) >> 2) != (uint64_t) client->req_len)) return(16)
;
220
221 err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess(1<<8));
222 if (err != Success0)
5
Assuming 'err' is equal to 0
6
Taking false branch
223 return err;
224 if (!ValidAtom(stuff->property)) {
7
Taking false branch
225 client->errorValue = stuff->property;
226 return BadAtom5;
227 }
228 if (!ValidAtom(stuff->type)) {
8
Taking false branch
229 client->errorValue = stuff->type;
230 return BadAtom5;
231 }
232
233 err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type,
9
Calling 'dixChangeWindowProperty'
234 (int) format, (int) mode, len, &stuff[1],
235 TRUE1);
236 if (err != Success0)
237 return err;
238 else
239 return Success0;
240}
241
242int
243dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
244 Atom type, int format, int mode, unsigned long len,
245 void *value, Bool sendevent)
246{
247 PropertyPtr pProp;
248 PropertyRec savedProp;
249 int sizeInBytes, totalSize, rc;
250 unsigned char *data;
251 Mask access_mode;
252
253 sizeInBytes = format >> 3;
254 totalSize = len * sizeInBytes;
255 access_mode = (mode == PropModeReplace0) ? DixWriteAccess(1<<1) : DixBlendAccess(1<<16);
10
'?' condition is true
256
257 /* first see if property already exists */
258 rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode);
259
260 if (rc == BadMatch8) { /* just add to list */
11
Assuming 'rc' is equal to 8
12
Taking true branch
261 if (!pWin->optional && !MakeWindowOptional(pWin))
262 return BadAlloc11;
263 pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY)(PropertyRec *) _dixAllocateObjectWithPrivates(sizeof(PropertyRec
), sizeof(PropertyRec), __builtin_offsetof(PropertyRec, devPrivates
), PRIVATE_PROPERTY)
;
264 if (!pProp)
13
Assuming 'pProp' is non-null
14
Taking false branch
265 return BadAlloc11;
266 data = malloc(totalSize);
15
Value assigned to 'data'
267 if (!data && len) {
16
Assuming 'data' is null
17
Taking false branch
268 dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY)_dixFreeObjectWithPrivates(pProp, (pProp)->devPrivates, PRIVATE_PROPERTY
)
;
269 return BadAlloc11;
270 }
271 memcpy(data, value, totalSize)__builtin___memcpy_chk (data, value, totalSize, __builtin_object_size
(data, 0))
;
18
Within the expansion of the macro 'memcpy':
a
Null pointer argument in call to memory copy function
272 pProp->propertyName = property;
273 pProp->type = type;
274 pProp->format = format;
275 pProp->data = data;
276 pProp->size = len;
277 rc = XaceHookPropertyAccess(pClient, pWin, &pProp,
278 DixCreateAccess(1<<3) | DixWriteAccess(1<<1));
279 if (rc != Success0) {
280 free(data);
281 dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY)_dixFreeObjectWithPrivates(pProp, (pProp)->devPrivates, PRIVATE_PROPERTY
)
;
282 pClient->errorValue = property;
283 return rc;
284 }
285 pProp->next = pWin->optional->userProps;
286 pWin->optional->userProps = pProp;
287 }
288 else if (rc == Success0) {
289 /* To append or prepend to a property the request format and type
290 must match those of the already defined property. The
291 existing format and type are irrelevant when using the mode
292 "PropModeReplace" since they will be written over. */
293
294 if ((format != pProp->format) && (mode != PropModeReplace0))
295 return BadMatch8;
296 if ((pProp->type != type) && (mode != PropModeReplace0))
297 return BadMatch8;
298
299 /* save the old values for later */
300 savedProp = *pProp;
301
302 if (mode == PropModeReplace0) {
303 data = malloc(totalSize);
304 if (!data && len)
305 return BadAlloc11;
306 memcpy(data, value, totalSize)__builtin___memcpy_chk (data, value, totalSize, __builtin_object_size
(data, 0))
;
307 pProp->data = data;
308 pProp->size = len;
309 pProp->type = type;
310 pProp->format = format;
311 }
312 else if (len == 0) {
313 /* do nothing */
314 }
315 else if (mode == PropModeAppend2) {
316 data = xallocarray(pProp->size + len, sizeInBytes)xreallocarray(((void*)0), (pProp->size + len), (sizeInBytes
))
;
317 if (!data)
318 return BadAlloc11;
319 memcpy(data, pProp->data, pProp->size * sizeInBytes)__builtin___memcpy_chk (data, pProp->data, pProp->size *
sizeInBytes, __builtin_object_size (data, 0))
;
320 memcpy(data + pProp->size * sizeInBytes, value, totalSize)__builtin___memcpy_chk (data + pProp->size * sizeInBytes, value
, totalSize, __builtin_object_size (data + pProp->size * sizeInBytes
, 0))
;
321 pProp->data = data;
322 pProp->size += len;
323 }
324 else if (mode == PropModePrepend1) {
325 data = xallocarray(len + pProp->size, sizeInBytes)xreallocarray(((void*)0), (len + pProp->size), (sizeInBytes
))
;
326 if (!data)
327 return BadAlloc11;
328 memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes)__builtin___memcpy_chk (data + totalSize, pProp->data, pProp
->size * sizeInBytes, __builtin_object_size (data + totalSize
, 0))
;
329 memcpy(data, value, totalSize)__builtin___memcpy_chk (data, value, totalSize, __builtin_object_size
(data, 0))
;
330 pProp->data = data;
331 pProp->size += len;
332 }
333
334 /* Allow security modules to check the new content */
335 access_mode |= DixPostAccess(1<<28);
336 rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode);
337 if (rc == Success0) {
338 if (savedProp.data != pProp->data)
339 free(savedProp.data);
340 }
341 else {
342 if (savedProp.data != pProp->data)
343 free(pProp->data);
344 *pProp = savedProp;
345 return rc;
346 }
347 }
348 else
349 return rc;
350
351 if (sendevent)
352 deliverPropertyNotifyEvent(pWin, PropertyNewValue0, pProp->propertyName);
353
354 return Success0;
355}
356
357int
358DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
359{
360 PropertyPtr pProp, prevProp;
361 int rc;
362
363 rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess(1<<2));
364 if (rc == BadMatch8)
365 return Success0; /* Succeed if property does not exist */
366
367 if (rc == Success0) {
368 if (pWin->optional->userProps == pProp) {
369 /* Takes care of head */
370 if (!(pWin->optional->userProps = pProp->next))
371 CheckWindowOptionalNeed(pWin);
372 }
373 else {
374 /* Need to traverse to find the previous element */
375 prevProp = pWin->optional->userProps;
376 while (prevProp->next != pProp)
377 prevProp = prevProp->next;
378 prevProp->next = pProp->next;
379 }
380
381 deliverPropertyNotifyEvent(pWin, PropertyDelete1, pProp->propertyName);
382 free(pProp->data);
383 dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY)_dixFreeObjectWithPrivates(pProp, (pProp)->devPrivates, PRIVATE_PROPERTY
)
;
384 }
385 return rc;
386}
387
388void
389DeleteAllWindowProperties(WindowPtr pWin)
390{
391 PropertyPtr pProp, pNextProp;
392
393 pProp = wUserProps(pWin)((pWin)->optional ? (pWin)->optional->userProps : ((
void*)0))
;
394 while (pProp) {
395 deliverPropertyNotifyEvent(pWin, PropertyDelete1, pProp->propertyName);
396 pNextProp = pProp->next;
397 free(pProp->data);
398 dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY)_dixFreeObjectWithPrivates(pProp, (pProp)->devPrivates, PRIVATE_PROPERTY
)
;
399 pProp = pNextProp;
400 }
401
402 if (pWin->optional)
403 pWin->optional->userProps = NULL((void*)0);
404}
405
406static int
407NullPropertyReply(ClientPtr client, ATOM propertyType, int format)
408{
409 xGetPropertyReply reply = {
410 .type = X_Reply1,
411 .format = format,
412 .sequenceNumber = client->sequence,
413 .length = 0,
414 .propertyType = propertyType,
415 .bytesAfter = 0,
416 .nItems = 0
417 };
418 WriteReplyToClient(client, sizeof(xGenericReply), &reply){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xGenericReply
)), &reply); else WriteToClient(client, (int)(sizeof(xGenericReply
)), (&reply)); }
;
419 return Success0;
420}
421
422/*****************
423 * GetProperty
424 * If type Any is specified, returns the property from the specified
425 * window regardless of its type. If a type is specified, returns the
426 * property only if its type equals the specified type.
427 * If delete is True and a property is returned, the property is also
428 * deleted from the window and a PropertyNotify event is generated on the
429 * window.
430 *****************/
431
432int
433ProcGetProperty(ClientPtr client)
434{
435 PropertyPtr pProp, prevProp;
436 unsigned long n, len, ind;
437 int rc;
438 WindowPtr pWin;
439 xGetPropertyReply reply;
440 Mask win_mode = DixGetPropAccess(1<<7), prop_mode = DixReadAccess(1<<0);
441
442 REQUEST(xGetPropertyReq)xGetPropertyReq *stuff = (xGetPropertyReq *)client->requestBuffer;
443
444 REQUEST_SIZE_MATCH(xGetPropertyReq)if ((sizeof(xGetPropertyReq) >> 2) != client->req_len
) return(16)
;
445 if (stuff->delete) {
446 UpdateCurrentTime();
447 win_mode |= DixSetPropAccess(1<<8);
448 prop_mode |= DixDestroyAccess(1<<2);
449 }
450 rc = dixLookupWindow(&pWin, stuff->window, client, win_mode);
451 if (rc != Success0)
452 return rc;
453
454 if (!ValidAtom(stuff->property)) {
455 client->errorValue = stuff->property;
456 return BadAtom5;
457 }
458 if ((stuff->delete != xTrue1) && (stuff->delete != xFalse0)) {
459 client->errorValue = stuff->delete;
460 return BadValue2;
461 }
462 if ((stuff->type != AnyPropertyType0L) && !ValidAtom(stuff->type)) {
463 client->errorValue = stuff->type;
464 return BadAtom5;
465 }
466
467 rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode);
468 if (rc == BadMatch8)
469 return NullPropertyReply(client, None0L, 0);
470 else if (rc != Success0)
471 return rc;
472
473 /* If the request type and actual type don't match. Return the
474 property information, but not the data. */
475
476 if (((stuff->type != pProp->type) && (stuff->type != AnyPropertyType0L))
477 ) {
478 reply = (xGetPropertyReply) {
479 .type = X_Reply1,
480 .sequenceNumber = client->sequence,
481 .bytesAfter = pProp->size,
482 .format = pProp->format,
483 .length = 0,
484 .nItems = 0,
485 .propertyType = pProp->type
486 };
487 WriteReplyToClient(client, sizeof(xGenericReply), &reply){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xGenericReply
)), &reply); else WriteToClient(client, (int)(sizeof(xGenericReply
)), (&reply)); }
;
488 return Success0;
489 }
490
491/*
492 * Return type, format, value to client
493 */
494 n = (pProp->format / 8) * pProp->size; /* size (bytes) of prop */
495 ind = stuff->longOffset << 2;
496
497 /* If longOffset is invalid such that it causes "len" to
498 be negative, it's a value error. */
499
500 if (n < ind) {
501 client->errorValue = stuff->longOffset;
502 return BadValue2;
503 }
504
505 len = min(n - ind, 4 * stuff->longLength)(((n - ind) < (4 * stuff->longLength)) ? (n - ind) : (4
* stuff->longLength))
;
506
507 reply = (xGetPropertyReply) {
508 .type = X_Reply1,
509 .sequenceNumber = client->sequence,
510 .bytesAfter = n - (ind + len),
511 .format = pProp->format,
512 .length = bytes_to_int32(len),
513 .nItems = len / (pProp->format / 8),
514 .propertyType = pProp->type
515 };
516
517 if (stuff->delete && (reply.bytesAfter == 0))
518 deliverPropertyNotifyEvent(pWin, PropertyDelete1, pProp->propertyName);
519
520 WriteReplyToClient(client, sizeof(xGenericReply), &reply){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xGenericReply
)), &reply); else WriteToClient(client, (int)(sizeof(xGenericReply
)), (&reply)); }
;
521 if (len) {
522 switch (reply.format) {
523 case 32:
524 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
525 break;
526 case 16:
527 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
528 break;
529 default:
530 client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
531 break;
532 }
533 WriteSwappedDataToClient(client, len, (char *) pProp->data + ind)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(len), (char *) pProp->data + ind); else WriteToClient
(client, (int)(len), ((char *) pProp->data + ind));
;
534 }
535
536 if (stuff->delete && (reply.bytesAfter == 0)) {
537 /* Delete the Property */
538 if (pWin->optional->userProps == pProp) {
539 /* Takes care of head */
540 if (!(pWin->optional->userProps = pProp->next))
541 CheckWindowOptionalNeed(pWin);
542 }
543 else {
544 /* Need to traverse to find the previous element */
545 prevProp = pWin->optional->userProps;
546 while (prevProp->next != pProp)
547 prevProp = prevProp->next;
548 prevProp->next = pProp->next;
549 }
550
551 free(pProp->data);
552 dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY)_dixFreeObjectWithPrivates(pProp, (pProp)->devPrivates, PRIVATE_PROPERTY
)
;
553 }
554 return Success0;
555}
556
557int
558ProcListProperties(ClientPtr client)
559{
560 Atom *pAtoms = NULL((void*)0), *temppAtoms;
561 xListPropertiesReply xlpr;
562 int rc, numProps = 0;
563 WindowPtr pWin;
564 PropertyPtr pProp, realProp;
565
566 REQUEST(xResourceReq)xResourceReq *stuff = (xResourceReq *)client->requestBuffer;
567
568 REQUEST_SIZE_MATCH(xResourceReq)if ((sizeof(xResourceReq) >> 2) != client->req_len) return
(16)
;
569 rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess(1<<6));
570 if (rc != Success0)
571 return rc;
572
573 for (pProp = wUserProps(pWin)((pWin)->optional ? (pWin)->optional->userProps : ((
void*)0))
; pProp; pProp = pProp->next)
574 numProps++;
575
576 if (numProps && !(pAtoms = xallocarray(numProps, sizeof(Atom))xreallocarray(((void*)0), (numProps), (sizeof(Atom)))))
577 return BadAlloc11;
578
579 numProps = 0;
580 temppAtoms = pAtoms;
581 for (pProp = wUserProps(pWin)((pWin)->optional ? (pWin)->optional->userProps : ((
void*)0))
; pProp; pProp = pProp->next) {
582 realProp = pProp;
583 rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess(1<<4));
584 if (rc == Success0 && realProp == pProp) {
585 *temppAtoms++ = pProp->propertyName;
586 numProps++;
587 }
588 }
589
590 xlpr = (xListPropertiesReply) {
591 .type = X_Reply1,
592 .sequenceNumber = client->sequence,
593 .length = bytes_to_int32(numProps * sizeof(Atom)),
594 .nProperties = numProps
595 };
596 WriteReplyToClient(client, sizeof(xGenericReply), &xlpr){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client
)->requestBuffer)->reqType]) (client, (int)(sizeof(xGenericReply
)), &xlpr); else WriteToClient(client, (int)(sizeof(xGenericReply
)), (&xlpr)); }
;
597 if (numProps) {
598 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
599 WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms)if ((client)->swapped) (*(client)->pSwapReplyFunc)(client
, (int)(numProps * sizeof(Atom)), pAtoms); else WriteToClient
(client, (int)(numProps * sizeof(Atom)), (pAtoms));
;
600 }
601 free(pAtoms);
602 return Success0;
603}
604
605int
606ProcDeleteProperty(ClientPtr client)
607{
608 WindowPtr pWin;
609
610 REQUEST(xDeletePropertyReq)xDeletePropertyReq *stuff = (xDeletePropertyReq *)client->
requestBuffer
;
611 int result;
612
613 REQUEST_SIZE_MATCH(xDeletePropertyReq)if ((sizeof(xDeletePropertyReq) >> 2) != client->req_len
) return(16)
;
614 UpdateCurrentTime();
615 result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess(1<<8));
616 if (result != Success0)
617 return result;
618 if (!ValidAtom(stuff->property)) {
619 client->errorValue = stuff->property;
620 return BadAtom5;
621 }
622
623 return DeleteProperty(client, pWin, stuff->property);
624}