1 /* this is a file autogenerated by spice_codegen.py */
2 /*
3 Copyright (C) 2013 Red Hat, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 #include "common/messages.h"
23 #include <string.h>
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <spice/protocol.h>
28 #include <spice/macros.h>
29 #include <common/mem.h>
30 #include <common/demarshallers.h>
31
32 #ifdef _MSC_VER
33 #pragma warning(disable:4101)
34 #endif
35
36
37
38 #include <spice/start-packed.h>
39 typedef struct SPICE_ATTR_PACKED {
40 int16_t v;
41 } int16_unaligned_t;
42 typedef struct SPICE_ATTR_PACKED {
43 uint16_t v;
44 } uint16_unaligned_t;
45 typedef struct SPICE_ATTR_PACKED {
46 int32_t v;
47 } int32_unaligned_t;
48 typedef struct SPICE_ATTR_PACKED {
49 uint32_t v;
50 } uint32_unaligned_t;
51 typedef struct SPICE_ATTR_PACKED {
52 int64_t v;
53 } int64_unaligned_t;
54 typedef struct SPICE_ATTR_PACKED {
55 uint64_t v;
56 } uint64_unaligned_t;
57 #include <spice/end-packed.h>
58
59 #define read_int8(ptr) (*((int8_t *)(ptr)))
60 #define write_int8(ptr, val) *(int8_t *)(ptr) = val
61 #define read_uint8(ptr) (*((uint8_t *)(ptr)))
62 #define write_uint8(ptr, val) *(uint8_t *)(ptr) = val
63
64 #ifdef WORDS_BIGENDIAN
65 #define read_int16(ptr) ((int16_t)SPICE_BYTESWAP16(((uint16_unaligned_t *)(ptr))->v))
66 #define write_int16(ptr, val) ((uint16_unaligned_t *)(ptr))->v = SPICE_BYTESWAP16((uint16_t)val)
67 #define read_uint16(ptr) ((uint16_t)SPICE_BYTESWAP16(((uint16_unaligned_t *)(ptr))->v))
68 #define write_uint16(ptr, val) ((uint16_unaligned_t *)(ptr))->v = SPICE_BYTESWAP16((uint16_t)val)
69 #define read_int32(ptr) ((int32_t)SPICE_BYTESWAP32(((uint32_unaligned_t *)(ptr))->v))
70 #define write_int32(ptr, val) ((uint32_unaligned_t *)(ptr))->v = SPICE_BYTESWAP32((uint32_t)val)
71 #define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(((uint32_unaligned_t *)(ptr))->v))
72 #define write_uint32(ptr, val) ((uint32_unaligned_t *)(ptr))->v = SPICE_BYTESWAP32((uint32_t)val)
73 #define read_int64(ptr) ((int64_t)SPICE_BYTESWAP64(((uint64_unaligned_t *)(ptr))->v))
74 #define write_int64(ptr, val) ((uint64_unaligned_t *)(ptr))->v = SPICE_BYTESWAP64((uint64_t)val)
75 #define read_uint64(ptr) ((uint64_t)SPICE_BYTESWAP64(((uint64_unaligned_t *)(ptr))->v))
76 #define write_uint64(ptr, val) ((uint64_unaligned_t *)(ptr))->v = SPICE_BYTESWAP64((uint64_t)val)
77 #else
78 #define read_int16(ptr) (((int16_unaligned_t *)(ptr))->v)
79 #define write_int16(ptr, val) (((int16_unaligned_t *)(ptr))->v) = val
80 #define read_uint16(ptr) (((uint16_unaligned_t *)(ptr))->v)
81 #define write_uint16(ptr, val) (((uint16_unaligned_t *)(ptr))->v) = val
82 #define read_int32(ptr) (((int32_unaligned_t *)(ptr))->v)
83 #define write_int32(ptr, val) (((int32_unaligned_t *)(ptr))->v) = val
84 #define read_uint32(ptr) (((uint32_unaligned_t *)(ptr))->v)
85 #define write_uint32(ptr, val) (((uint32_unaligned_t *)(ptr))->v) = val
86 #define read_int64(ptr) (((int64_unaligned_t *)(ptr))->v)
87 #define write_int64(ptr, val) (((int64_unaligned_t *)(ptr))->v) = val
88 #define read_uint64(ptr) (((uint64_unaligned_t *)(ptr))->v)
89 #define write_uint64(ptr, val) (((uint64_unaligned_t *)(ptr))->v) = val
90 #endif
91
consume_int8(uint8_t ** ptr)92 static int8_t SPICE_GNUC_UNUSED consume_int8(uint8_t **ptr)
93 {
94 int8_t val;
95 val = read_int8(*ptr);
96 *ptr += 1;
97 return val;
98 }
99
consume_uint8(uint8_t ** ptr)100 static uint8_t SPICE_GNUC_UNUSED consume_uint8(uint8_t **ptr)
101 {
102 uint8_t val;
103 val = read_uint8(*ptr);
104 *ptr += 1;
105 return val;
106 }
107
consume_int16(uint8_t ** ptr)108 static int16_t SPICE_GNUC_UNUSED consume_int16(uint8_t **ptr)
109 {
110 int16_t val;
111 val = read_int16(*ptr);
112 *ptr += 2;
113 return val;
114 }
115
consume_uint16(uint8_t ** ptr)116 static uint16_t SPICE_GNUC_UNUSED consume_uint16(uint8_t **ptr)
117 {
118 uint16_t val;
119 val = read_uint16(*ptr);
120 *ptr += 2;
121 return val;
122 }
123
consume_int32(uint8_t ** ptr)124 static int32_t SPICE_GNUC_UNUSED consume_int32(uint8_t **ptr)
125 {
126 int32_t val;
127 val = read_int32(*ptr);
128 *ptr += 4;
129 return val;
130 }
131
consume_uint32(uint8_t ** ptr)132 static uint32_t SPICE_GNUC_UNUSED consume_uint32(uint8_t **ptr)
133 {
134 uint32_t val;
135 val = read_uint32(*ptr);
136 *ptr += 4;
137 return val;
138 }
139
consume_int64(uint8_t ** ptr)140 static int64_t SPICE_GNUC_UNUSED consume_int64(uint8_t **ptr)
141 {
142 int64_t val;
143 val = read_int64(*ptr);
144 *ptr += 8;
145 return val;
146 }
147
consume_uint64(uint8_t ** ptr)148 static uint64_t SPICE_GNUC_UNUSED consume_uint64(uint8_t **ptr)
149 {
150 uint64_t val;
151 val = read_uint64(*ptr);
152 *ptr += 8;
153 return val;
154 }
consume_fd(uint8_t ** ptr SPICE_GNUC_UNUSED)155 static int SPICE_GNUC_UNUSED consume_fd(uint8_t **ptr SPICE_GNUC_UNUSED)
156 {
157 return -1;
158 }
159
160 typedef struct PointerInfo PointerInfo;
161 typedef void (*message_destructor_t)(uint8_t *message);
162 typedef uint8_t * (*parse_func_t)(uint8_t *message_start, uint8_t *message_end, uint8_t *struct_data, PointerInfo *ptr_info);
163 typedef uint8_t * (*parse_msg_func_t)(uint8_t *message_start, uint8_t *message_end, size_t *size_out, message_destructor_t *free_message);
164 typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor, size_t *size_out, message_destructor_t *free_message);
165
166 struct PointerInfo {
167 uint64_t offset;
168 parse_func_t parse;
169 void * *dest;
170 uint64_t nelements;
171 };
172
parse_msg_migrate(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)173 static uint8_t * parse_msg_migrate(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
174 {
175 SPICE_GNUC_UNUSED uint8_t *pos;
176 uint8_t *start = message_start;
177 uint8_t *data = NULL;
178 uint64_t nw_size;
179 uint64_t mem_size;
180 uint8_t *in, *end;
181 SpiceMsgMigrate *out;
182
183 nw_size = 4;
184 mem_size = sizeof(SpiceMsgMigrate);
185
186 /* Check if message fits in reported side */
187 if (nw_size > (uintptr_t) (message_end - start)) {
188 return NULL;
189 }
190
191 /* Validated extents and calculated size */
192 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
193 if (SPICE_UNLIKELY(data == NULL)) {
194 goto error;
195 }
196 end = data + sizeof(SpiceMsgMigrate);
197 in = start;
198
199 out = (SpiceMsgMigrate *)data;
200
201 out->flags = consume_uint32(&in);
202
203 assert(in <= message_end);
204 assert(end <= data + mem_size);
205
206 *size = end - data;
207 *free_message = (message_destructor_t) free;
208 return data;
209
210 error:
211 free(data);
212 return NULL;
213 }
214
nofree(SPICE_GNUC_UNUSED uint8_t * data)215 static void nofree(SPICE_GNUC_UNUSED uint8_t *data)
216 {
217 }
218
parse_SpiceMsgData(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)219 static uint8_t * parse_SpiceMsgData(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
220 {
221 SPICE_GNUC_UNUSED uint8_t *pos;
222 uint8_t *start = message_start;
223 uint8_t *data = NULL;
224 uint64_t nw_size;
225 uint64_t data__nw_size;
226 uint64_t data__nelements;
227
228 { /* data */
229 if (SPICE_UNLIKELY((start + 0) > message_end)) {
230 goto error;
231 }
232 data__nelements = message_end - (start + 0);
233
234 data__nw_size = data__nelements;
235 }
236
237 nw_size = 0 + data__nw_size;
238
239 /* Check if message fits in reported side */
240 if (nw_size > (uintptr_t) (message_end - start)) {
241 return NULL;
242 }
243
244 /* Validated extents and calculated size */
245 data = message_start;
246 *size = message_end - message_start;
247 *free_message = nofree;
248 return data;
249
250 error:
251 free(data);
252 return NULL;
253 }
254
parse_msg_set_ack(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)255 static uint8_t * parse_msg_set_ack(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
256 {
257 SPICE_GNUC_UNUSED uint8_t *pos;
258 uint8_t *start = message_start;
259 uint8_t *data = NULL;
260 uint64_t nw_size;
261 uint64_t mem_size;
262 uint8_t *in, *end;
263 SpiceMsgSetAck *out;
264
265 nw_size = 8;
266 mem_size = sizeof(SpiceMsgSetAck);
267
268 /* Check if message fits in reported side */
269 if (nw_size > (uintptr_t) (message_end - start)) {
270 return NULL;
271 }
272
273 /* Validated extents and calculated size */
274 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
275 if (SPICE_UNLIKELY(data == NULL)) {
276 goto error;
277 }
278 end = data + sizeof(SpiceMsgSetAck);
279 in = start;
280
281 out = (SpiceMsgSetAck *)data;
282
283 out->generation = consume_uint32(&in);
284 out->window = consume_uint32(&in);
285
286 assert(in <= message_end);
287 assert(end <= data + mem_size);
288
289 *size = end - data;
290 *free_message = (message_destructor_t) free;
291 return data;
292
293 error:
294 free(data);
295 return NULL;
296 }
297
parse_msg_ping(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)298 static uint8_t * parse_msg_ping(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
299 {
300 SPICE_GNUC_UNUSED uint8_t *pos;
301 uint8_t *start = message_start;
302 uint8_t *data = NULL;
303 uint64_t nw_size;
304 uint64_t mem_size;
305 uint8_t *in, *end;
306 uint64_t data__nw_size;
307 uint64_t data__nelements;
308 SpiceMsgPing *out;
309
310 { /* data */
311 if (SPICE_UNLIKELY((start + 12) > message_end)) {
312 goto error;
313 }
314 data__nelements = message_end - (start + 12);
315
316 data__nw_size = data__nelements;
317 }
318
319 nw_size = 12 + data__nw_size;
320 mem_size = sizeof(SpiceMsgPing);
321
322 /* Check if message fits in reported side */
323 if (nw_size > (uintptr_t) (message_end - start)) {
324 return NULL;
325 }
326
327 /* Validated extents and calculated size */
328 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
329 if (SPICE_UNLIKELY(data == NULL)) {
330 goto error;
331 }
332 end = data + sizeof(SpiceMsgPing);
333 in = start;
334
335 out = (SpiceMsgPing *)data;
336
337 out->id = consume_uint32(&in);
338 out->timestamp = consume_uint64(&in);
339 /* use array as pointer */
340 out->data = (uint8_t *)in;
341 out->data_len = data__nelements;
342 in += data__nelements;
343
344 assert(in <= message_end);
345 assert(end <= data + mem_size);
346
347 *size = end - data;
348 *free_message = (message_destructor_t) free;
349 return data;
350
351 error:
352 free(data);
353 return NULL;
354 }
355
parse_msg_wait_for_channels(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)356 static uint8_t * parse_msg_wait_for_channels(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
357 {
358 SPICE_GNUC_UNUSED uint8_t *pos;
359 uint8_t *start = message_start;
360 uint8_t *data = NULL;
361 uint64_t nw_size;
362 uint64_t mem_size;
363 uint8_t *in, *end;
364 uint64_t wait_list__nw_size, wait_list__mem_size;
365 uint64_t wait_list__nelements;
366 SpiceMsgWaitForChannels *out;
367 uint32_t i;
368
369 { /* wait_list */
370 uint8_t wait_count__value;
371 pos = start + 0;
372 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
373 goto error;
374 }
375 wait_count__value = read_uint8(pos);
376 wait_list__nelements = wait_count__value;
377
378 wait_list__nw_size = (10) * wait_list__nelements;
379 wait_list__mem_size = sizeof(SpiceWaitForChannel) * wait_list__nelements;
380 }
381
382 nw_size = 1 + wait_list__nw_size;
383 mem_size = sizeof(SpiceMsgWaitForChannels) + wait_list__mem_size;
384
385 /* Check if message fits in reported side */
386 if (nw_size > (uintptr_t) (message_end - start)) {
387 return NULL;
388 }
389
390 /* Validated extents and calculated size */
391 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
392 if (SPICE_UNLIKELY(data == NULL)) {
393 goto error;
394 }
395 end = data + sizeof(SpiceMsgWaitForChannels);
396 in = start;
397
398 out = (SpiceMsgWaitForChannels *)data;
399
400 out->wait_count = consume_uint8(&in);
401 for (i = 0; i < wait_list__nelements; i++) {
402 SpiceWaitForChannel *out2;
403 out2 = (SpiceWaitForChannel *)end;
404 end += sizeof(SpiceWaitForChannel);
405
406 out2->channel_type = consume_uint8(&in);
407 out2->channel_id = consume_uint8(&in);
408 out2->message_serial = consume_uint64(&in);
409 }
410
411 assert(in <= message_end);
412 assert(end <= data + mem_size);
413
414 *size = end - data;
415 *free_message = (message_destructor_t) free;
416 return data;
417
418 error:
419 free(data);
420 return NULL;
421 }
422
parse_msg_disconnecting(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)423 static uint8_t * parse_msg_disconnecting(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
424 {
425 SPICE_GNUC_UNUSED uint8_t *pos;
426 uint8_t *start = message_start;
427 uint8_t *data = NULL;
428 uint64_t nw_size;
429 uint64_t mem_size;
430 uint8_t *in, *end;
431 SpiceMsgDisconnect *out;
432
433 nw_size = 12;
434 mem_size = sizeof(SpiceMsgDisconnect);
435
436 /* Check if message fits in reported side */
437 if (nw_size > (uintptr_t) (message_end - start)) {
438 return NULL;
439 }
440
441 /* Validated extents and calculated size */
442 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
443 if (SPICE_UNLIKELY(data == NULL)) {
444 goto error;
445 }
446 end = data + sizeof(SpiceMsgDisconnect);
447 in = start;
448
449 out = (SpiceMsgDisconnect *)data;
450
451 out->time_stamp = consume_uint64(&in);
452 out->reason = consume_uint32(&in);
453
454 assert(in <= message_end);
455 assert(end <= data + mem_size);
456
457 *size = end - data;
458 *free_message = (message_destructor_t) free;
459 return data;
460
461 error:
462 free(data);
463 return NULL;
464 }
465
parse_msg_notify(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)466 static uint8_t * parse_msg_notify(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
467 {
468 SPICE_GNUC_UNUSED uint8_t *pos;
469 uint8_t *start = message_start;
470 uint8_t *data = NULL;
471 uint64_t nw_size;
472 uint64_t mem_size;
473 uint8_t *in, *end;
474 uint64_t message__nw_size, message__mem_size;
475 uint64_t message__nelements;
476 SpiceMsgNotify *out;
477
478 { /* message */
479 uint32_t message_len__value;
480 pos = start + 20;
481 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
482 goto error;
483 }
484 message_len__value = read_uint32(pos);
485 message__nelements = message_len__value;
486
487 message__nw_size = message__nelements;
488 message__mem_size = sizeof(uint8_t) * message__nelements;
489 }
490
491 nw_size = 24 + message__nw_size;
492 mem_size = sizeof(SpiceMsgNotify) + message__mem_size;
493
494 /* Check if message fits in reported side */
495 if (nw_size > (uintptr_t) (message_end - start)) {
496 return NULL;
497 }
498
499 /* Validated extents and calculated size */
500 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
501 if (SPICE_UNLIKELY(data == NULL)) {
502 goto error;
503 }
504 end = data + sizeof(SpiceMsgNotify);
505 in = start;
506
507 out = (SpiceMsgNotify *)data;
508
509 out->time_stamp = consume_uint64(&in);
510 out->severity = consume_uint32(&in);
511 out->visibilty = consume_uint32(&in);
512 out->what = consume_uint32(&in);
513 out->message_len = consume_uint32(&in);
514 memcpy(out->message, in, message__nelements);
515 in += message__nelements;
516 end += message__nelements;
517
518 assert(in <= message_end);
519 assert(end <= data + mem_size);
520
521 *size = end - data;
522 *free_message = (message_destructor_t) free;
523 return data;
524
525 error:
526 free(data);
527 return NULL;
528 }
529
parse_SpiceMsgEmpty(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)530 static uint8_t * parse_SpiceMsgEmpty(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
531 {
532 SPICE_GNUC_UNUSED uint8_t *pos;
533 uint8_t *start = message_start;
534 uint8_t *data = NULL;
535 uint64_t nw_size;
536 uint64_t mem_size;
537 uint8_t *in, *end;
538
539 nw_size = 0;
540 mem_size = sizeof(SpiceMsgEmpty);
541
542 /* Check if message fits in reported side */
543 if (nw_size > (uintptr_t) (message_end - start)) {
544 return NULL;
545 }
546
547 /* Validated extents and calculated size */
548 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
549 if (SPICE_UNLIKELY(data == NULL)) {
550 goto error;
551 }
552 end = data + sizeof(SpiceMsgEmpty);
553 in = start;
554
555
556 assert(in <= message_end);
557 assert(end <= data + mem_size);
558
559 *size = end - data;
560 *free_message = (message_destructor_t) free;
561 return data;
562
563 error:
564 free(data);
565 return NULL;
566 }
567
parse_array_uint8(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)568 static uint8_t * parse_array_uint8(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
569 {
570 uint8_t *in = message_start + this_ptr_info->offset;
571 uint8_t *end;
572
573 end = struct_data;
574 memcpy(end, in, this_ptr_info->nelements);
575 in += this_ptr_info->nelements;
576 end += this_ptr_info->nelements;
577 return end;
578 }
579
parse_msg_main_migrate_begin(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)580 static uint8_t * parse_msg_main_migrate_begin(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
581 {
582 SPICE_GNUC_UNUSED uint8_t *pos;
583 uint8_t *start = message_start;
584 uint8_t *data = NULL;
585 uint64_t nw_size;
586 uint64_t mem_size;
587 uint8_t *in, *end;
588 SPICE_GNUC_UNUSED intptr_t ptr_size;
589 uint32_t n_ptr=0;
590 PointerInfo ptr_info[2];
591 uint64_t dst_info__extra_size;
592 SpiceMsgMainMigrationBegin *out;
593 uint32_t i;
594
595 { /* dst_info */
596 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
597 uint64_t dst_info_host_data__extra_size;
598 uint64_t dst_info_host_data__array__nelements;
599 uint64_t dst_info_cert_subject_data__extra_size;
600 uint64_t dst_info_cert_subject_data__array__nelements;
601 { /* host_data */
602 uint32_t host_data__value;
603 uint64_t dst_info_host_data__array__nw_size;
604 uint64_t dst_info_host_data__array__mem_size;
605 uint32_t host_size__value;
606 pos = (start2 + 8);
607 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
608 goto error;
609 }
610 host_data__value = read_uint32(pos);
611 if (SPICE_UNLIKELY(host_data__value == 0)) {
612 goto error;
613 }
614 if (SPICE_UNLIKELY(host_data__value >= (uintptr_t) (message_end - message_start))) {
615 goto error;
616 }
617 pos = start2 + 4;
618 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
619 goto error;
620 }
621 host_size__value = read_uint32(pos);
622 dst_info_host_data__array__nelements = host_size__value;
623
624 dst_info_host_data__array__nw_size = dst_info_host_data__array__nelements;
625 dst_info_host_data__array__mem_size = sizeof(uint8_t) * dst_info_host_data__array__nelements;
626 if (SPICE_UNLIKELY(host_data__value + dst_info_host_data__array__nw_size > (uintptr_t) (message_end - message_start))) {
627 goto error;
628 }
629 dst_info_host_data__extra_size = dst_info_host_data__array__mem_size + /* for alignment */ 3;
630 }
631
632 { /* cert_subject_data */
633 uint32_t cert_subject_data__value;
634 uint64_t dst_info_cert_subject_data__array__nw_size;
635 uint64_t dst_info_cert_subject_data__array__mem_size;
636 uint32_t cert_subject_size__value;
637 pos = (start2 + 16);
638 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
639 goto error;
640 }
641 cert_subject_data__value = read_uint32(pos);
642 if (SPICE_UNLIKELY(cert_subject_data__value >= (uintptr_t) (message_end - message_start))) {
643 goto error;
644 }
645 pos = start2 + 12;
646 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
647 goto error;
648 }
649 cert_subject_size__value = read_uint32(pos);
650 dst_info_cert_subject_data__array__nelements = cert_subject_size__value;
651
652 dst_info_cert_subject_data__array__nw_size = dst_info_cert_subject_data__array__nelements;
653 dst_info_cert_subject_data__array__mem_size = sizeof(uint8_t) * dst_info_cert_subject_data__array__nelements;
654 if (SPICE_UNLIKELY(cert_subject_data__value + dst_info_cert_subject_data__array__nw_size > (uintptr_t) (message_end - message_start))) {
655 goto error;
656 }
657 dst_info_cert_subject_data__extra_size = dst_info_cert_subject_data__array__mem_size + /* for alignment */ 3;
658 }
659
660 dst_info__extra_size = dst_info_host_data__extra_size + dst_info_cert_subject_data__extra_size;
661 }
662
663 nw_size = 20;
664 mem_size = sizeof(SpiceMsgMainMigrationBegin) + dst_info__extra_size;
665
666 /* Check if message fits in reported side */
667 if (nw_size > (uintptr_t) (message_end - start)) {
668 return NULL;
669 }
670
671 /* Validated extents and calculated size */
672 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
673 if (SPICE_UNLIKELY(data == NULL)) {
674 goto error;
675 }
676 end = data + sizeof(SpiceMsgMainMigrationBegin);
677 in = start;
678
679 out = (SpiceMsgMainMigrationBegin *)data;
680
681 /* dst_info */ {
682 uint64_t host_data__array__nelements;
683 uint64_t cert_subject_data__array__nelements;
684 out->dst_info.port = consume_uint16(&in);
685 out->dst_info.sport = consume_uint16(&in);
686 out->dst_info.host_size = consume_uint32(&in);
687 ptr_info[n_ptr].offset = consume_uint32(&in);
688 ptr_info[n_ptr].parse = parse_array_uint8;
689 ptr_info[n_ptr].dest = (void **)&out->dst_info.host_data;
690 host_data__array__nelements = out->dst_info.host_size;
691 ptr_info[n_ptr].nelements = host_data__array__nelements;
692 n_ptr++;
693 out->dst_info.cert_subject_size = consume_uint32(&in);
694 ptr_info[n_ptr].offset = consume_uint32(&in);
695 ptr_info[n_ptr].parse = parse_array_uint8;
696 ptr_info[n_ptr].dest = (void **)&out->dst_info.cert_subject_data;
697 cert_subject_data__array__nelements = out->dst_info.cert_subject_size;
698 ptr_info[n_ptr].nelements = cert_subject_data__array__nelements;
699 n_ptr++;
700 }
701
702 assert(in <= message_end);
703
704 for (i = 0; i < n_ptr; i++) {
705 if (ptr_info[i].offset == 0) {
706 *ptr_info[i].dest = NULL;
707 } else {
708 /* Align to 32 bit */
709 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
710 *ptr_info[i].dest = (void *)end;
711 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
712 if (SPICE_UNLIKELY(end == NULL)) {
713 goto error;
714 }
715 }
716 }
717
718 assert(end <= data + mem_size);
719
720 *size = end - data;
721 *free_message = (message_destructor_t) free;
722 return data;
723
724 error:
725 free(data);
726 return NULL;
727 }
728
parse_msg_main_init(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)729 static uint8_t * parse_msg_main_init(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
730 {
731 SPICE_GNUC_UNUSED uint8_t *pos;
732 uint8_t *start = message_start;
733 uint8_t *data = NULL;
734 uint64_t nw_size;
735 uint64_t mem_size;
736 uint8_t *in, *end;
737 SpiceMsgMainInit *out;
738
739 nw_size = 32;
740 mem_size = sizeof(SpiceMsgMainInit);
741
742 /* Check if message fits in reported side */
743 if (nw_size > (uintptr_t) (message_end - start)) {
744 return NULL;
745 }
746
747 /* Validated extents and calculated size */
748 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
749 if (SPICE_UNLIKELY(data == NULL)) {
750 goto error;
751 }
752 end = data + sizeof(SpiceMsgMainInit);
753 in = start;
754
755 out = (SpiceMsgMainInit *)data;
756
757 out->session_id = consume_uint32(&in);
758 out->display_channels_hint = consume_uint32(&in);
759 out->supported_mouse_modes = consume_uint32(&in);
760 out->current_mouse_mode = consume_uint32(&in);
761 out->agent_connected = consume_uint32(&in);
762 out->agent_tokens = consume_uint32(&in);
763 out->multi_media_time = consume_uint32(&in);
764 out->ram_hint = consume_uint32(&in);
765
766 assert(in <= message_end);
767 assert(end <= data + mem_size);
768
769 *size = end - data;
770 *free_message = (message_destructor_t) free;
771 return data;
772
773 error:
774 free(data);
775 return NULL;
776 }
777
parse_msg_main_channels_list(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)778 static uint8_t * parse_msg_main_channels_list(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
779 {
780 SPICE_GNUC_UNUSED uint8_t *pos;
781 uint8_t *start = message_start;
782 uint8_t *data = NULL;
783 uint64_t nw_size;
784 uint64_t mem_size;
785 uint8_t *in, *end;
786 uint64_t channels__nw_size, channels__mem_size;
787 uint64_t channels__nelements;
788 SpiceMsgChannels *out;
789 uint32_t i;
790
791 { /* channels */
792 uint32_t num_of_channels__value;
793 pos = start + 0;
794 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
795 goto error;
796 }
797 num_of_channels__value = read_uint32(pos);
798 channels__nelements = num_of_channels__value;
799
800 channels__nw_size = (2) * channels__nelements;
801 channels__mem_size = sizeof(SpiceChannelId) * channels__nelements;
802 }
803
804 nw_size = 4 + channels__nw_size;
805 mem_size = sizeof(SpiceMsgChannels) + channels__mem_size;
806
807 /* Check if message fits in reported side */
808 if (nw_size > (uintptr_t) (message_end - start)) {
809 return NULL;
810 }
811
812 /* Validated extents and calculated size */
813 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
814 if (SPICE_UNLIKELY(data == NULL)) {
815 goto error;
816 }
817 end = data + sizeof(SpiceMsgChannels);
818 in = start;
819
820 out = (SpiceMsgChannels *)data;
821
822 out->num_of_channels = consume_uint32(&in);
823 for (i = 0; i < channels__nelements; i++) {
824 SpiceChannelId *out2;
825 out2 = (SpiceChannelId *)end;
826 end += sizeof(SpiceChannelId);
827
828 out2->type = consume_uint8(&in);
829 out2->id = consume_uint8(&in);
830 }
831
832 assert(in <= message_end);
833 assert(end <= data + mem_size);
834
835 *size = end - data;
836 *free_message = (message_destructor_t) free;
837 return data;
838
839 error:
840 free(data);
841 return NULL;
842 }
843
parse_msg_main_mouse_mode(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)844 static uint8_t * parse_msg_main_mouse_mode(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
845 {
846 SPICE_GNUC_UNUSED uint8_t *pos;
847 uint8_t *start = message_start;
848 uint8_t *data = NULL;
849 uint64_t nw_size;
850 uint64_t mem_size;
851 uint8_t *in, *end;
852 SpiceMsgMainMouseMode *out;
853
854 nw_size = 4;
855 mem_size = sizeof(SpiceMsgMainMouseMode);
856
857 /* Check if message fits in reported side */
858 if (nw_size > (uintptr_t) (message_end - start)) {
859 return NULL;
860 }
861
862 /* Validated extents and calculated size */
863 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
864 if (SPICE_UNLIKELY(data == NULL)) {
865 goto error;
866 }
867 end = data + sizeof(SpiceMsgMainMouseMode);
868 in = start;
869
870 out = (SpiceMsgMainMouseMode *)data;
871
872 out->supported_modes = consume_uint16(&in);
873 out->current_mode = consume_uint16(&in);
874
875 assert(in <= message_end);
876 assert(end <= data + mem_size);
877
878 *size = end - data;
879 *free_message = (message_destructor_t) free;
880 return data;
881
882 error:
883 free(data);
884 return NULL;
885 }
886
parse_msg_main_multi_media_time(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)887 static uint8_t * parse_msg_main_multi_media_time(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
888 {
889 SPICE_GNUC_UNUSED uint8_t *pos;
890 uint8_t *start = message_start;
891 uint8_t *data = NULL;
892 uint64_t nw_size;
893 uint64_t mem_size;
894 uint8_t *in, *end;
895 SpiceMsgMainMultiMediaTime *out;
896
897 nw_size = 4;
898 mem_size = sizeof(SpiceMsgMainMultiMediaTime);
899
900 /* Check if message fits in reported side */
901 if (nw_size > (uintptr_t) (message_end - start)) {
902 return NULL;
903 }
904
905 /* Validated extents and calculated size */
906 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
907 if (SPICE_UNLIKELY(data == NULL)) {
908 goto error;
909 }
910 end = data + sizeof(SpiceMsgMainMultiMediaTime);
911 in = start;
912
913 out = (SpiceMsgMainMultiMediaTime *)data;
914
915 out->time = consume_uint32(&in);
916
917 assert(in <= message_end);
918 assert(end <= data + mem_size);
919
920 *size = end - data;
921 *free_message = (message_destructor_t) free;
922 return data;
923
924 error:
925 free(data);
926 return NULL;
927 }
928
parse_msg_main_agent_disconnected(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)929 static uint8_t * parse_msg_main_agent_disconnected(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
930 {
931 SPICE_GNUC_UNUSED uint8_t *pos;
932 uint8_t *start = message_start;
933 uint8_t *data = NULL;
934 uint64_t nw_size;
935 uint64_t mem_size;
936 uint8_t *in, *end;
937 SpiceMsgMainAgentDisconnect *out;
938
939 nw_size = 4;
940 mem_size = sizeof(SpiceMsgMainAgentDisconnect);
941
942 /* Check if message fits in reported side */
943 if (nw_size > (uintptr_t) (message_end - start)) {
944 return NULL;
945 }
946
947 /* Validated extents and calculated size */
948 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
949 if (SPICE_UNLIKELY(data == NULL)) {
950 goto error;
951 }
952 end = data + sizeof(SpiceMsgMainAgentDisconnect);
953 in = start;
954
955 out = (SpiceMsgMainAgentDisconnect *)data;
956
957 out->error_code = consume_uint32(&in);
958
959 assert(in <= message_end);
960 assert(end <= data + mem_size);
961
962 *size = end - data;
963 *free_message = (message_destructor_t) free;
964 return data;
965
966 error:
967 free(data);
968 return NULL;
969 }
970
parse_msg_main_agent_token(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)971 static uint8_t * parse_msg_main_agent_token(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
972 {
973 SPICE_GNUC_UNUSED uint8_t *pos;
974 uint8_t *start = message_start;
975 uint8_t *data = NULL;
976 uint64_t nw_size;
977 uint64_t mem_size;
978 uint8_t *in, *end;
979 SpiceMsgMainAgentTokens *out;
980
981 nw_size = 4;
982 mem_size = sizeof(SpiceMsgMainAgentTokens);
983
984 /* Check if message fits in reported side */
985 if (nw_size > (uintptr_t) (message_end - start)) {
986 return NULL;
987 }
988
989 /* Validated extents and calculated size */
990 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
991 if (SPICE_UNLIKELY(data == NULL)) {
992 goto error;
993 }
994 end = data + sizeof(SpiceMsgMainAgentTokens);
995 in = start;
996
997 out = (SpiceMsgMainAgentTokens *)data;
998
999 out->num_tokens = consume_uint32(&in);
1000
1001 assert(in <= message_end);
1002 assert(end <= data + mem_size);
1003
1004 *size = end - data;
1005 *free_message = (message_destructor_t) free;
1006 return data;
1007
1008 error:
1009 free(data);
1010 return NULL;
1011 }
1012
parse_msg_main_migrate_switch_host(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1013 static uint8_t * parse_msg_main_migrate_switch_host(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1014 {
1015 SPICE_GNUC_UNUSED uint8_t *pos;
1016 uint8_t *start = message_start;
1017 uint8_t *data = NULL;
1018 uint64_t nw_size;
1019 uint64_t mem_size;
1020 uint8_t *in, *end;
1021 SPICE_GNUC_UNUSED intptr_t ptr_size;
1022 uint32_t n_ptr=0;
1023 PointerInfo ptr_info[2];
1024 uint64_t host_data__extra_size;
1025 uint64_t host_data__array__nelements;
1026 uint64_t cert_subject_data__extra_size;
1027 uint64_t cert_subject_data__array__nelements;
1028 SpiceMsgMainMigrationSwitchHost *out;
1029 uint32_t i;
1030
1031 { /* host_data */
1032 uint32_t host_data__value;
1033 uint64_t host_data__array__nw_size;
1034 uint64_t host_data__array__mem_size;
1035 uint32_t host_size__value;
1036 pos = (start + 8);
1037 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1038 goto error;
1039 }
1040 host_data__value = read_uint32(pos);
1041 if (SPICE_UNLIKELY(host_data__value >= (uintptr_t) (message_end - message_start))) {
1042 goto error;
1043 }
1044 pos = start + 4;
1045 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1046 goto error;
1047 }
1048 host_size__value = read_uint32(pos);
1049 host_data__array__nelements = host_size__value;
1050
1051 host_data__array__nw_size = host_data__array__nelements;
1052 host_data__array__mem_size = sizeof(uint8_t) * host_data__array__nelements;
1053 if (SPICE_UNLIKELY(host_data__value + host_data__array__nw_size > (uintptr_t) (message_end - message_start))) {
1054 goto error;
1055 }
1056 host_data__extra_size = host_data__array__mem_size + /* for alignment */ 3;
1057 }
1058
1059 { /* cert_subject_data */
1060 uint32_t cert_subject_data__value;
1061 uint64_t cert_subject_data__array__nw_size;
1062 uint64_t cert_subject_data__array__mem_size;
1063 uint32_t cert_subject_size__value;
1064 pos = (start + 16);
1065 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1066 goto error;
1067 }
1068 cert_subject_data__value = read_uint32(pos);
1069 if (SPICE_UNLIKELY(cert_subject_data__value >= (uintptr_t) (message_end - message_start))) {
1070 goto error;
1071 }
1072 pos = start + 12;
1073 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1074 goto error;
1075 }
1076 cert_subject_size__value = read_uint32(pos);
1077 cert_subject_data__array__nelements = cert_subject_size__value;
1078
1079 cert_subject_data__array__nw_size = cert_subject_data__array__nelements;
1080 cert_subject_data__array__mem_size = sizeof(uint8_t) * cert_subject_data__array__nelements;
1081 if (SPICE_UNLIKELY(cert_subject_data__value + cert_subject_data__array__nw_size > (uintptr_t) (message_end - message_start))) {
1082 goto error;
1083 }
1084 cert_subject_data__extra_size = cert_subject_data__array__mem_size + /* for alignment */ 3;
1085 }
1086
1087 nw_size = 20;
1088 mem_size = sizeof(SpiceMsgMainMigrationSwitchHost) + host_data__extra_size + cert_subject_data__extra_size;
1089
1090 /* Check if message fits in reported side */
1091 if (nw_size > (uintptr_t) (message_end - start)) {
1092 return NULL;
1093 }
1094
1095 /* Validated extents and calculated size */
1096 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1097 if (SPICE_UNLIKELY(data == NULL)) {
1098 goto error;
1099 }
1100 end = data + sizeof(SpiceMsgMainMigrationSwitchHost);
1101 in = start;
1102
1103 out = (SpiceMsgMainMigrationSwitchHost *)data;
1104
1105 out->port = consume_uint16(&in);
1106 out->sport = consume_uint16(&in);
1107 out->host_size = consume_uint32(&in);
1108 ptr_info[n_ptr].offset = consume_uint32(&in);
1109 ptr_info[n_ptr].parse = parse_array_uint8;
1110 ptr_info[n_ptr].dest = (void **)&out->host_data;
1111 ptr_info[n_ptr].nelements = host_data__array__nelements;
1112 n_ptr++;
1113 out->cert_subject_size = consume_uint32(&in);
1114 ptr_info[n_ptr].offset = consume_uint32(&in);
1115 ptr_info[n_ptr].parse = parse_array_uint8;
1116 ptr_info[n_ptr].dest = (void **)&out->cert_subject_data;
1117 ptr_info[n_ptr].nelements = cert_subject_data__array__nelements;
1118 n_ptr++;
1119
1120 assert(in <= message_end);
1121
1122 for (i = 0; i < n_ptr; i++) {
1123 if (ptr_info[i].offset == 0) {
1124 *ptr_info[i].dest = NULL;
1125 } else {
1126 /* Align to 32 bit */
1127 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
1128 *ptr_info[i].dest = (void *)end;
1129 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
1130 if (SPICE_UNLIKELY(end == NULL)) {
1131 goto error;
1132 }
1133 }
1134 }
1135
1136 assert(end <= data + mem_size);
1137
1138 *size = end - data;
1139 *free_message = (message_destructor_t) free;
1140 return data;
1141
1142 error:
1143 free(data);
1144 return NULL;
1145 }
1146
parse_msg_main_name(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1147 static uint8_t * parse_msg_main_name(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1148 {
1149 SPICE_GNUC_UNUSED uint8_t *pos;
1150 uint8_t *start = message_start;
1151 uint8_t *data = NULL;
1152 uint64_t nw_size;
1153 uint64_t mem_size;
1154 uint8_t *in, *end;
1155 uint64_t name__nw_size, name__mem_size;
1156 uint64_t name__nelements;
1157 SpiceMsgMainName *out;
1158
1159 { /* name */
1160 uint32_t name_len__value;
1161 pos = start + 0;
1162 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1163 goto error;
1164 }
1165 name_len__value = read_uint32(pos);
1166 name__nelements = name_len__value;
1167
1168 name__nw_size = name__nelements;
1169 name__mem_size = sizeof(uint8_t) * name__nelements;
1170 }
1171
1172 nw_size = 4 + name__nw_size;
1173 mem_size = sizeof(SpiceMsgMainName) + name__mem_size;
1174
1175 /* Check if message fits in reported side */
1176 if (nw_size > (uintptr_t) (message_end - start)) {
1177 return NULL;
1178 }
1179
1180 /* Validated extents and calculated size */
1181 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1182 if (SPICE_UNLIKELY(data == NULL)) {
1183 goto error;
1184 }
1185 end = data + sizeof(SpiceMsgMainName);
1186 in = start;
1187
1188 out = (SpiceMsgMainName *)data;
1189
1190 out->name_len = consume_uint32(&in);
1191 memcpy(out->name, in, name__nelements);
1192 in += name__nelements;
1193 end += name__nelements;
1194
1195 assert(in <= message_end);
1196 assert(end <= data + mem_size);
1197
1198 *size = end - data;
1199 *free_message = (message_destructor_t) free;
1200 return data;
1201
1202 error:
1203 free(data);
1204 return NULL;
1205 }
1206
parse_msg_main_uuid(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1207 static uint8_t * parse_msg_main_uuid(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1208 {
1209 SPICE_GNUC_UNUSED uint8_t *pos;
1210 uint8_t *start = message_start;
1211 uint8_t *data = NULL;
1212 uint64_t nw_size;
1213 uint64_t mem_size;
1214 uint8_t *in, *end;
1215 SpiceMsgMainUuid *out;
1216 uint64_t uuid__nelements;
1217
1218 nw_size = 16;
1219 mem_size = sizeof(SpiceMsgMainUuid);
1220
1221 /* Check if message fits in reported side */
1222 if (nw_size > (uintptr_t) (message_end - start)) {
1223 return NULL;
1224 }
1225
1226 /* Validated extents and calculated size */
1227 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1228 if (SPICE_UNLIKELY(data == NULL)) {
1229 goto error;
1230 }
1231 end = data + sizeof(SpiceMsgMainUuid);
1232 in = start;
1233
1234 out = (SpiceMsgMainUuid *)data;
1235
1236 uuid__nelements = 16;
1237 memcpy(out->uuid, in, uuid__nelements);
1238 in += uuid__nelements;
1239
1240 assert(in <= message_end);
1241 assert(end <= data + mem_size);
1242
1243 *size = end - data;
1244 *free_message = (message_destructor_t) free;
1245 return data;
1246
1247 error:
1248 free(data);
1249 return NULL;
1250 }
1251
parse_msg_main_agent_connected_tokens(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1252 static uint8_t * parse_msg_main_agent_connected_tokens(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1253 {
1254 SPICE_GNUC_UNUSED uint8_t *pos;
1255 uint8_t *start = message_start;
1256 uint8_t *data = NULL;
1257 uint64_t nw_size;
1258 uint64_t mem_size;
1259 uint8_t *in, *end;
1260 SpiceMsgMainAgentConnectedTokens *out;
1261
1262 nw_size = 4;
1263 mem_size = sizeof(SpiceMsgMainAgentConnectedTokens);
1264
1265 /* Check if message fits in reported side */
1266 if (nw_size > (uintptr_t) (message_end - start)) {
1267 return NULL;
1268 }
1269
1270 /* Validated extents and calculated size */
1271 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1272 if (SPICE_UNLIKELY(data == NULL)) {
1273 goto error;
1274 }
1275 end = data + sizeof(SpiceMsgMainAgentConnectedTokens);
1276 in = start;
1277
1278 out = (SpiceMsgMainAgentConnectedTokens *)data;
1279
1280 out->num_tokens = consume_uint32(&in);
1281
1282 assert(in <= message_end);
1283 assert(end <= data + mem_size);
1284
1285 *size = end - data;
1286 *free_message = (message_destructor_t) free;
1287 return data;
1288
1289 error:
1290 free(data);
1291 return NULL;
1292 }
1293
parse_msg_main_migrate_begin_seamless(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1294 static uint8_t * parse_msg_main_migrate_begin_seamless(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1295 {
1296 SPICE_GNUC_UNUSED uint8_t *pos;
1297 uint8_t *start = message_start;
1298 uint8_t *data = NULL;
1299 uint64_t nw_size;
1300 uint64_t mem_size;
1301 uint8_t *in, *end;
1302 SPICE_GNUC_UNUSED intptr_t ptr_size;
1303 uint32_t n_ptr=0;
1304 PointerInfo ptr_info[2];
1305 uint64_t dst_info__extra_size;
1306 SpiceMsgMainMigrateBeginSeamless *out;
1307 uint32_t i;
1308
1309 { /* dst_info */
1310 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
1311 uint64_t dst_info_host_data__extra_size;
1312 uint64_t dst_info_host_data__array__nelements;
1313 uint64_t dst_info_cert_subject_data__extra_size;
1314 uint64_t dst_info_cert_subject_data__array__nelements;
1315 { /* host_data */
1316 uint32_t host_data__value;
1317 uint64_t dst_info_host_data__array__nw_size;
1318 uint64_t dst_info_host_data__array__mem_size;
1319 uint32_t host_size__value;
1320 pos = (start2 + 8);
1321 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1322 goto error;
1323 }
1324 host_data__value = read_uint32(pos);
1325 if (SPICE_UNLIKELY(host_data__value == 0)) {
1326 goto error;
1327 }
1328 if (SPICE_UNLIKELY(host_data__value >= (uintptr_t) (message_end - message_start))) {
1329 goto error;
1330 }
1331 pos = start2 + 4;
1332 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1333 goto error;
1334 }
1335 host_size__value = read_uint32(pos);
1336 dst_info_host_data__array__nelements = host_size__value;
1337
1338 dst_info_host_data__array__nw_size = dst_info_host_data__array__nelements;
1339 dst_info_host_data__array__mem_size = sizeof(uint8_t) * dst_info_host_data__array__nelements;
1340 if (SPICE_UNLIKELY(host_data__value + dst_info_host_data__array__nw_size > (uintptr_t) (message_end - message_start))) {
1341 goto error;
1342 }
1343 dst_info_host_data__extra_size = dst_info_host_data__array__mem_size + /* for alignment */ 3;
1344 }
1345
1346 { /* cert_subject_data */
1347 uint32_t cert_subject_data__value;
1348 uint64_t dst_info_cert_subject_data__array__nw_size;
1349 uint64_t dst_info_cert_subject_data__array__mem_size;
1350 uint32_t cert_subject_size__value;
1351 pos = (start2 + 16);
1352 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1353 goto error;
1354 }
1355 cert_subject_data__value = read_uint32(pos);
1356 if (SPICE_UNLIKELY(cert_subject_data__value >= (uintptr_t) (message_end - message_start))) {
1357 goto error;
1358 }
1359 pos = start2 + 12;
1360 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1361 goto error;
1362 }
1363 cert_subject_size__value = read_uint32(pos);
1364 dst_info_cert_subject_data__array__nelements = cert_subject_size__value;
1365
1366 dst_info_cert_subject_data__array__nw_size = dst_info_cert_subject_data__array__nelements;
1367 dst_info_cert_subject_data__array__mem_size = sizeof(uint8_t) * dst_info_cert_subject_data__array__nelements;
1368 if (SPICE_UNLIKELY(cert_subject_data__value + dst_info_cert_subject_data__array__nw_size > (uintptr_t) (message_end - message_start))) {
1369 goto error;
1370 }
1371 dst_info_cert_subject_data__extra_size = dst_info_cert_subject_data__array__mem_size + /* for alignment */ 3;
1372 }
1373
1374 dst_info__extra_size = dst_info_host_data__extra_size + dst_info_cert_subject_data__extra_size;
1375 }
1376
1377 nw_size = 24;
1378 mem_size = sizeof(SpiceMsgMainMigrateBeginSeamless) + dst_info__extra_size;
1379
1380 /* Check if message fits in reported side */
1381 if (nw_size > (uintptr_t) (message_end - start)) {
1382 return NULL;
1383 }
1384
1385 /* Validated extents and calculated size */
1386 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1387 if (SPICE_UNLIKELY(data == NULL)) {
1388 goto error;
1389 }
1390 end = data + sizeof(SpiceMsgMainMigrateBeginSeamless);
1391 in = start;
1392
1393 out = (SpiceMsgMainMigrateBeginSeamless *)data;
1394
1395 /* dst_info */ {
1396 uint64_t host_data__array__nelements;
1397 uint64_t cert_subject_data__array__nelements;
1398 out->dst_info.port = consume_uint16(&in);
1399 out->dst_info.sport = consume_uint16(&in);
1400 out->dst_info.host_size = consume_uint32(&in);
1401 ptr_info[n_ptr].offset = consume_uint32(&in);
1402 ptr_info[n_ptr].parse = parse_array_uint8;
1403 ptr_info[n_ptr].dest = (void **)&out->dst_info.host_data;
1404 host_data__array__nelements = out->dst_info.host_size;
1405 ptr_info[n_ptr].nelements = host_data__array__nelements;
1406 n_ptr++;
1407 out->dst_info.cert_subject_size = consume_uint32(&in);
1408 ptr_info[n_ptr].offset = consume_uint32(&in);
1409 ptr_info[n_ptr].parse = parse_array_uint8;
1410 ptr_info[n_ptr].dest = (void **)&out->dst_info.cert_subject_data;
1411 cert_subject_data__array__nelements = out->dst_info.cert_subject_size;
1412 ptr_info[n_ptr].nelements = cert_subject_data__array__nelements;
1413 n_ptr++;
1414 }
1415 out->src_mig_version = consume_uint32(&in);
1416
1417 assert(in <= message_end);
1418
1419 for (i = 0; i < n_ptr; i++) {
1420 if (ptr_info[i].offset == 0) {
1421 *ptr_info[i].dest = NULL;
1422 } else {
1423 /* Align to 32 bit */
1424 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
1425 *ptr_info[i].dest = (void *)end;
1426 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
1427 if (SPICE_UNLIKELY(end == NULL)) {
1428 goto error;
1429 }
1430 }
1431 }
1432
1433 assert(end <= data + mem_size);
1434
1435 *size = end - data;
1436 *free_message = (message_destructor_t) free;
1437 return data;
1438
1439 error:
1440 free(data);
1441 return NULL;
1442 }
1443
parse_MainChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)1444 static uint8_t * parse_MainChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
1445 {
1446 static parse_msg_func_t funcs1[8] = {
1447 parse_msg_migrate,
1448 parse_SpiceMsgData,
1449 parse_msg_set_ack,
1450 parse_msg_ping,
1451 parse_msg_wait_for_channels,
1452 parse_msg_disconnecting,
1453 parse_msg_notify,
1454 parse_SpiceMsgData
1455 };
1456 static parse_msg_func_t funcs2[19] = {
1457 parse_SpiceMsgEmpty,
1458 parse_msg_main_migrate_begin,
1459 parse_SpiceMsgEmpty,
1460 parse_msg_main_init,
1461 parse_msg_main_channels_list,
1462 parse_msg_main_mouse_mode,
1463 parse_msg_main_multi_media_time,
1464 parse_SpiceMsgEmpty,
1465 parse_msg_main_agent_disconnected,
1466 parse_SpiceMsgData,
1467 parse_msg_main_agent_token,
1468 parse_msg_main_migrate_switch_host,
1469 parse_SpiceMsgEmpty,
1470 parse_msg_main_name,
1471 parse_msg_main_uuid,
1472 parse_msg_main_agent_connected_tokens,
1473 parse_msg_main_migrate_begin_seamless,
1474 parse_SpiceMsgEmpty,
1475 parse_SpiceMsgEmpty
1476 };
1477 if (message_type >= 1 && message_type < 9) {
1478 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
1479 } else if (message_type >= 100 && message_type < 119) {
1480 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
1481 }
1482 return NULL;
1483 }
1484
1485
1486
parse_msg_display_mode(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1487 static uint8_t * parse_msg_display_mode(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1488 {
1489 SPICE_GNUC_UNUSED uint8_t *pos;
1490 uint8_t *start = message_start;
1491 uint8_t *data = NULL;
1492 uint64_t nw_size;
1493 uint64_t mem_size;
1494 uint8_t *in, *end;
1495 SpiceMsgDisplayMode *out;
1496
1497 nw_size = 12;
1498 mem_size = sizeof(SpiceMsgDisplayMode);
1499
1500 /* Check if message fits in reported side */
1501 if (nw_size > (uintptr_t) (message_end - start)) {
1502 return NULL;
1503 }
1504
1505 /* Validated extents and calculated size */
1506 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1507 if (SPICE_UNLIKELY(data == NULL)) {
1508 goto error;
1509 }
1510 end = data + sizeof(SpiceMsgDisplayMode);
1511 in = start;
1512
1513 out = (SpiceMsgDisplayMode *)data;
1514
1515 out->x_res = consume_uint32(&in);
1516 out->y_res = consume_uint32(&in);
1517 out->bits = consume_uint32(&in);
1518
1519 assert(in <= message_end);
1520 assert(end <= data + mem_size);
1521
1522 *size = end - data;
1523 *free_message = (message_destructor_t) free;
1524 return data;
1525
1526 error:
1527 free(data);
1528 return NULL;
1529 }
1530
parse_struct_SpiceClipRects(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)1531 static uint8_t * parse_struct_SpiceClipRects(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
1532 {
1533 uint8_t *in = message_start + this_ptr_info->offset;
1534 uint8_t *end;
1535 SpiceClipRects *out;
1536 uint64_t rects__nelements;
1537 uint32_t i;
1538
1539 end = struct_data + sizeof(SpiceClipRects);
1540 out = (SpiceClipRects *)struct_data;
1541
1542 out->num_rects = consume_uint32(&in);
1543 rects__nelements = out->num_rects;
1544 for (i = 0; i < rects__nelements; i++) {
1545 SpiceRect *out2;
1546 out2 = (SpiceRect *)end;
1547 end += sizeof(SpiceRect);
1548
1549 out2->top = consume_int32(&in);
1550 out2->left = consume_int32(&in);
1551 out2->bottom = consume_int32(&in);
1552 out2->right = consume_int32(&in);
1553 }
1554 return end;
1555 }
1556
parse_msg_display_copy_bits(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1557 static uint8_t * parse_msg_display_copy_bits(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1558 {
1559 SPICE_GNUC_UNUSED uint8_t *pos;
1560 uint8_t *start = message_start;
1561 uint8_t *data = NULL;
1562 uint64_t nw_size;
1563 uint64_t mem_size;
1564 uint8_t *in, *end;
1565 SPICE_GNUC_UNUSED intptr_t ptr_size;
1566 uint32_t n_ptr=0;
1567 PointerInfo ptr_info[1];
1568 uint64_t base__nw_size, base__extra_size;
1569 uint32_t rects__saved_size = 0;
1570 SpiceMsgDisplayCopyBits *out;
1571 uint32_t i;
1572
1573 { /* base */
1574 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
1575 uint64_t base_clip__nw_size, base_clip__extra_size;
1576 { /* clip */
1577 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
1578 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
1579 uint8_t type__value;
1580 { /* u */
1581 uint64_t base_clip_u__mem_size;
1582 pos = start3 + 0;
1583 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
1584 goto error;
1585 }
1586 type__value = read_uint8(pos);
1587 if (type__value == SPICE_CLIP_TYPE_RECTS) {
1588 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
1589 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
1590 uint64_t base_clip_u_rects__nelements;
1591 { /* rects */
1592 uint32_t num_rects__value;
1593 pos = start4 + 0;
1594 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1595 goto error;
1596 }
1597 num_rects__value = read_uint32(pos);
1598 base_clip_u_rects__nelements = num_rects__value;
1599
1600 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
1601 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
1602 }
1603
1604 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
1605 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
1606 rects__saved_size = base_clip_u__nw_size;
1607 base_clip_u__extra_size = base_clip_u__mem_size;
1608 } else {
1609 base_clip_u__nw_size = 0;
1610 base_clip_u__extra_size = 0;
1611 }
1612
1613 }
1614
1615 base_clip__nw_size = 1 + base_clip_u__nw_size;
1616 base_clip__extra_size = base_clip_u__extra_size;
1617 }
1618
1619 base__nw_size = 20 + base_clip__nw_size;
1620 base__extra_size = base_clip__extra_size;
1621 }
1622
1623 nw_size = 8 + base__nw_size;
1624 mem_size = sizeof(SpiceMsgDisplayCopyBits) + base__extra_size;
1625
1626 /* Check if message fits in reported side */
1627 if (nw_size > (uintptr_t) (message_end - start)) {
1628 return NULL;
1629 }
1630
1631 /* Validated extents and calculated size */
1632 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1633 if (SPICE_UNLIKELY(data == NULL)) {
1634 goto error;
1635 }
1636 end = data + sizeof(SpiceMsgDisplayCopyBits);
1637 in = start;
1638
1639 out = (SpiceMsgDisplayCopyBits *)data;
1640
1641 /* base */ {
1642 out->base.surface_id = consume_uint32(&in);
1643 /* box */ {
1644 out->base.box.top = consume_int32(&in);
1645 out->base.box.left = consume_int32(&in);
1646 out->base.box.bottom = consume_int32(&in);
1647 out->base.box.right = consume_int32(&in);
1648 }
1649 /* clip */ {
1650 out->base.clip.type = consume_uint8(&in);
1651 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
1652 ptr_info[n_ptr].offset = in - start;
1653 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
1654 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
1655 n_ptr++;
1656 in += rects__saved_size;
1657 }
1658 }
1659 }
1660 /* src_pos */ {
1661 out->src_pos.x = consume_int32(&in);
1662 out->src_pos.y = consume_int32(&in);
1663 }
1664
1665 assert(in <= message_end);
1666
1667 for (i = 0; i < n_ptr; i++) {
1668 if (ptr_info[i].offset == 0) {
1669 *ptr_info[i].dest = NULL;
1670 } else {
1671 /* Align to 32 bit */
1672 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
1673 *ptr_info[i].dest = (void *)end;
1674 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
1675 if (SPICE_UNLIKELY(end == NULL)) {
1676 goto error;
1677 }
1678 }
1679 }
1680
1681 assert(end <= data + mem_size);
1682
1683 *size = end - data;
1684 *free_message = (message_destructor_t) free;
1685 return data;
1686
1687 error:
1688 free(data);
1689 return NULL;
1690 }
1691
parse_msg_display_inval_list(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1692 static uint8_t * parse_msg_display_inval_list(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1693 {
1694 SPICE_GNUC_UNUSED uint8_t *pos;
1695 uint8_t *start = message_start;
1696 uint8_t *data = NULL;
1697 uint64_t nw_size;
1698 uint64_t mem_size;
1699 uint8_t *in, *end;
1700 uint64_t resources__nw_size, resources__mem_size;
1701 uint64_t resources__nelements;
1702 SpiceResourceList *out;
1703 uint32_t i;
1704
1705 { /* resources */
1706 uint16_t count__value;
1707 pos = start + 0;
1708 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
1709 goto error;
1710 }
1711 count__value = read_uint16(pos);
1712 resources__nelements = count__value;
1713
1714 resources__nw_size = (9) * resources__nelements;
1715 resources__mem_size = sizeof(SpiceResourceID) * resources__nelements;
1716 }
1717
1718 nw_size = 2 + resources__nw_size;
1719 mem_size = sizeof(SpiceResourceList) + resources__mem_size;
1720
1721 /* Check if message fits in reported side */
1722 if (nw_size > (uintptr_t) (message_end - start)) {
1723 return NULL;
1724 }
1725
1726 /* Validated extents and calculated size */
1727 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1728 if (SPICE_UNLIKELY(data == NULL)) {
1729 goto error;
1730 }
1731 end = data + sizeof(SpiceResourceList);
1732 in = start;
1733
1734 out = (SpiceResourceList *)data;
1735
1736 out->count = consume_uint16(&in);
1737 for (i = 0; i < resources__nelements; i++) {
1738 SpiceResourceID *out2;
1739 out2 = (SpiceResourceID *)end;
1740 end += sizeof(SpiceResourceID);
1741
1742 out2->type = consume_uint8(&in);
1743 out2->id = consume_uint64(&in);
1744 }
1745
1746 assert(in <= message_end);
1747 assert(end <= data + mem_size);
1748
1749 *size = end - data;
1750 *free_message = (message_destructor_t) free;
1751 return data;
1752
1753 error:
1754 free(data);
1755 return NULL;
1756 }
1757
parse_msg_display_inval_all_pixmaps(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1758 static uint8_t * parse_msg_display_inval_all_pixmaps(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1759 {
1760 SPICE_GNUC_UNUSED uint8_t *pos;
1761 uint8_t *start = message_start;
1762 uint8_t *data = NULL;
1763 uint64_t nw_size;
1764 uint64_t mem_size;
1765 uint8_t *in, *end;
1766 uint64_t wait_list__nw_size, wait_list__mem_size;
1767 uint64_t wait_list__nelements;
1768 SpiceMsgWaitForChannels *out;
1769 uint32_t i;
1770
1771 { /* wait_list */
1772 uint8_t wait_count__value;
1773 pos = start + 0;
1774 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
1775 goto error;
1776 }
1777 wait_count__value = read_uint8(pos);
1778 wait_list__nelements = wait_count__value;
1779
1780 wait_list__nw_size = (10) * wait_list__nelements;
1781 wait_list__mem_size = sizeof(SpiceWaitForChannel) * wait_list__nelements;
1782 }
1783
1784 nw_size = 1 + wait_list__nw_size;
1785 mem_size = sizeof(SpiceMsgWaitForChannels) + wait_list__mem_size;
1786
1787 /* Check if message fits in reported side */
1788 if (nw_size > (uintptr_t) (message_end - start)) {
1789 return NULL;
1790 }
1791
1792 /* Validated extents and calculated size */
1793 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1794 if (SPICE_UNLIKELY(data == NULL)) {
1795 goto error;
1796 }
1797 end = data + sizeof(SpiceMsgWaitForChannels);
1798 in = start;
1799
1800 out = (SpiceMsgWaitForChannels *)data;
1801
1802 out->wait_count = consume_uint8(&in);
1803 for (i = 0; i < wait_list__nelements; i++) {
1804 SpiceWaitForChannel *out2;
1805 out2 = (SpiceWaitForChannel *)end;
1806 end += sizeof(SpiceWaitForChannel);
1807
1808 out2->channel_type = consume_uint8(&in);
1809 out2->channel_id = consume_uint8(&in);
1810 out2->message_serial = consume_uint64(&in);
1811 }
1812
1813 assert(in <= message_end);
1814 assert(end <= data + mem_size);
1815
1816 *size = end - data;
1817 *free_message = (message_destructor_t) free;
1818 return data;
1819
1820 error:
1821 free(data);
1822 return NULL;
1823 }
1824
parse_msg_display_inval_palette(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1825 static uint8_t * parse_msg_display_inval_palette(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1826 {
1827 SPICE_GNUC_UNUSED uint8_t *pos;
1828 uint8_t *start = message_start;
1829 uint8_t *data = NULL;
1830 uint64_t nw_size;
1831 uint64_t mem_size;
1832 uint8_t *in, *end;
1833 SpiceMsgDisplayInvalOne *out;
1834
1835 nw_size = 8;
1836 mem_size = sizeof(SpiceMsgDisplayInvalOne);
1837
1838 /* Check if message fits in reported side */
1839 if (nw_size > (uintptr_t) (message_end - start)) {
1840 return NULL;
1841 }
1842
1843 /* Validated extents and calculated size */
1844 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1845 if (SPICE_UNLIKELY(data == NULL)) {
1846 goto error;
1847 }
1848 end = data + sizeof(SpiceMsgDisplayInvalOne);
1849 in = start;
1850
1851 out = (SpiceMsgDisplayInvalOne *)data;
1852
1853 out->id = consume_uint64(&in);
1854
1855 assert(in <= message_end);
1856 assert(end <= data + mem_size);
1857
1858 *size = end - data;
1859 *free_message = (message_destructor_t) free;
1860 return data;
1861
1862 error:
1863 free(data);
1864 return NULL;
1865 }
1866
parse_msg_display_stream_create(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1867 static uint8_t * parse_msg_display_stream_create(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1868 {
1869 SPICE_GNUC_UNUSED uint8_t *pos;
1870 uint8_t *start = message_start;
1871 uint8_t *data = NULL;
1872 uint64_t nw_size;
1873 uint64_t mem_size;
1874 uint8_t *in, *end;
1875 SPICE_GNUC_UNUSED intptr_t ptr_size;
1876 uint32_t n_ptr=0;
1877 PointerInfo ptr_info[1];
1878 uint64_t clip__nw_size, clip__extra_size;
1879 uint32_t rects__saved_size = 0;
1880 SpiceMsgDisplayStreamCreate *out;
1881 uint32_t i;
1882
1883 { /* clip */
1884 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 50);
1885 uint64_t clip_u__nw_size, clip_u__extra_size;
1886 uint8_t type__value;
1887 { /* u */
1888 uint64_t clip_u__mem_size;
1889 pos = start2 + 0;
1890 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
1891 goto error;
1892 }
1893 type__value = read_uint8(pos);
1894 if (type__value == SPICE_CLIP_TYPE_RECTS) {
1895 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 1);
1896 uint64_t clip_u_rects__nw_size, clip_u_rects__mem_size;
1897 uint64_t clip_u_rects__nelements;
1898 { /* rects */
1899 uint32_t num_rects__value;
1900 pos = start3 + 0;
1901 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
1902 goto error;
1903 }
1904 num_rects__value = read_uint32(pos);
1905 clip_u_rects__nelements = num_rects__value;
1906
1907 clip_u_rects__nw_size = (16) * clip_u_rects__nelements;
1908 clip_u_rects__mem_size = sizeof(SpiceRect) * clip_u_rects__nelements;
1909 }
1910
1911 clip_u__nw_size = 4 + clip_u_rects__nw_size;
1912 clip_u__mem_size = sizeof(SpiceClipRects) + clip_u_rects__mem_size;
1913 rects__saved_size = clip_u__nw_size;
1914 clip_u__extra_size = clip_u__mem_size;
1915 } else {
1916 clip_u__nw_size = 0;
1917 clip_u__extra_size = 0;
1918 }
1919
1920 }
1921
1922 clip__nw_size = 1 + clip_u__nw_size;
1923 clip__extra_size = clip_u__extra_size;
1924 }
1925
1926 nw_size = 50 + clip__nw_size;
1927 mem_size = sizeof(SpiceMsgDisplayStreamCreate) + clip__extra_size;
1928
1929 /* Check if message fits in reported side */
1930 if (nw_size > (uintptr_t) (message_end - start)) {
1931 return NULL;
1932 }
1933
1934 /* Validated extents and calculated size */
1935 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
1936 if (SPICE_UNLIKELY(data == NULL)) {
1937 goto error;
1938 }
1939 end = data + sizeof(SpiceMsgDisplayStreamCreate);
1940 in = start;
1941
1942 out = (SpiceMsgDisplayStreamCreate *)data;
1943
1944 out->surface_id = consume_uint32(&in);
1945 out->id = consume_uint32(&in);
1946 out->flags = consume_uint8(&in);
1947 out->codec_type = consume_uint8(&in);
1948 out->stamp = consume_uint64(&in);
1949 out->stream_width = consume_uint32(&in);
1950 out->stream_height = consume_uint32(&in);
1951 out->src_width = consume_uint32(&in);
1952 out->src_height = consume_uint32(&in);
1953 /* dest */ {
1954 out->dest.top = consume_int32(&in);
1955 out->dest.left = consume_int32(&in);
1956 out->dest.bottom = consume_int32(&in);
1957 out->dest.right = consume_int32(&in);
1958 }
1959 /* clip */ {
1960 out->clip.type = consume_uint8(&in);
1961 if (out->clip.type == SPICE_CLIP_TYPE_RECTS) {
1962 ptr_info[n_ptr].offset = in - start;
1963 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
1964 ptr_info[n_ptr].dest = (void **)&out->clip.rects;
1965 n_ptr++;
1966 in += rects__saved_size;
1967 }
1968 }
1969
1970 assert(in <= message_end);
1971
1972 for (i = 0; i < n_ptr; i++) {
1973 if (ptr_info[i].offset == 0) {
1974 *ptr_info[i].dest = NULL;
1975 } else {
1976 /* Align to 32 bit */
1977 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
1978 *ptr_info[i].dest = (void *)end;
1979 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
1980 if (SPICE_UNLIKELY(end == NULL)) {
1981 goto error;
1982 }
1983 }
1984 }
1985
1986 assert(end <= data + mem_size);
1987
1988 *size = end - data;
1989 *free_message = (message_destructor_t) free;
1990 return data;
1991
1992 error:
1993 free(data);
1994 return NULL;
1995 }
1996
parse_msg_display_stream_data(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)1997 static uint8_t * parse_msg_display_stream_data(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
1998 {
1999 SPICE_GNUC_UNUSED uint8_t *pos;
2000 uint8_t *start = message_start;
2001 uint8_t *data = NULL;
2002 uint64_t nw_size;
2003 uint64_t mem_size;
2004 uint8_t *in, *end;
2005 uint64_t data__nw_size, data__mem_size;
2006 uint64_t data__nelements;
2007 SpiceMsgDisplayStreamData *out;
2008
2009 { /* data */
2010 uint32_t data_size__value;
2011 pos = start + 8;
2012 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2013 goto error;
2014 }
2015 data_size__value = read_uint32(pos);
2016 data__nelements = data_size__value;
2017
2018 data__nw_size = data__nelements;
2019 data__mem_size = sizeof(uint8_t) * data__nelements;
2020 }
2021
2022 nw_size = 12 + data__nw_size;
2023 mem_size = sizeof(SpiceMsgDisplayStreamData) + data__mem_size;
2024
2025 /* Check if message fits in reported side */
2026 if (nw_size > (uintptr_t) (message_end - start)) {
2027 return NULL;
2028 }
2029
2030 /* Validated extents and calculated size */
2031 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
2032 if (SPICE_UNLIKELY(data == NULL)) {
2033 goto error;
2034 }
2035 end = data + sizeof(SpiceMsgDisplayStreamData);
2036 in = start;
2037
2038 out = (SpiceMsgDisplayStreamData *)data;
2039
2040 /* base */ {
2041 out->base.id = consume_uint32(&in);
2042 out->base.multi_media_time = consume_uint32(&in);
2043 }
2044 out->data_size = consume_uint32(&in);
2045 memcpy(out->data, in, data__nelements);
2046 in += data__nelements;
2047 end += data__nelements;
2048
2049 assert(in <= message_end);
2050 assert(end <= data + mem_size);
2051
2052 *size = end - data;
2053 *free_message = (message_destructor_t) free;
2054 return data;
2055
2056 error:
2057 free(data);
2058 return NULL;
2059 }
2060
parse_msg_display_stream_clip(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)2061 static uint8_t * parse_msg_display_stream_clip(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
2062 {
2063 SPICE_GNUC_UNUSED uint8_t *pos;
2064 uint8_t *start = message_start;
2065 uint8_t *data = NULL;
2066 uint64_t nw_size;
2067 uint64_t mem_size;
2068 uint8_t *in, *end;
2069 SPICE_GNUC_UNUSED intptr_t ptr_size;
2070 uint32_t n_ptr=0;
2071 PointerInfo ptr_info[1];
2072 uint64_t clip__nw_size, clip__extra_size;
2073 uint32_t rects__saved_size = 0;
2074 SpiceMsgDisplayStreamClip *out;
2075 uint32_t i;
2076
2077 { /* clip */
2078 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 4);
2079 uint64_t clip_u__nw_size, clip_u__extra_size;
2080 uint8_t type__value;
2081 { /* u */
2082 uint64_t clip_u__mem_size;
2083 pos = start2 + 0;
2084 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
2085 goto error;
2086 }
2087 type__value = read_uint8(pos);
2088 if (type__value == SPICE_CLIP_TYPE_RECTS) {
2089 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 1);
2090 uint64_t clip_u_rects__nw_size, clip_u_rects__mem_size;
2091 uint64_t clip_u_rects__nelements;
2092 { /* rects */
2093 uint32_t num_rects__value;
2094 pos = start3 + 0;
2095 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2096 goto error;
2097 }
2098 num_rects__value = read_uint32(pos);
2099 clip_u_rects__nelements = num_rects__value;
2100
2101 clip_u_rects__nw_size = (16) * clip_u_rects__nelements;
2102 clip_u_rects__mem_size = sizeof(SpiceRect) * clip_u_rects__nelements;
2103 }
2104
2105 clip_u__nw_size = 4 + clip_u_rects__nw_size;
2106 clip_u__mem_size = sizeof(SpiceClipRects) + clip_u_rects__mem_size;
2107 rects__saved_size = clip_u__nw_size;
2108 clip_u__extra_size = clip_u__mem_size;
2109 } else {
2110 clip_u__nw_size = 0;
2111 clip_u__extra_size = 0;
2112 }
2113
2114 }
2115
2116 clip__nw_size = 1 + clip_u__nw_size;
2117 clip__extra_size = clip_u__extra_size;
2118 }
2119
2120 nw_size = 4 + clip__nw_size;
2121 mem_size = sizeof(SpiceMsgDisplayStreamClip) + clip__extra_size;
2122
2123 /* Check if message fits in reported side */
2124 if (nw_size > (uintptr_t) (message_end - start)) {
2125 return NULL;
2126 }
2127
2128 /* Validated extents and calculated size */
2129 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
2130 if (SPICE_UNLIKELY(data == NULL)) {
2131 goto error;
2132 }
2133 end = data + sizeof(SpiceMsgDisplayStreamClip);
2134 in = start;
2135
2136 out = (SpiceMsgDisplayStreamClip *)data;
2137
2138 out->id = consume_uint32(&in);
2139 /* clip */ {
2140 out->clip.type = consume_uint8(&in);
2141 if (out->clip.type == SPICE_CLIP_TYPE_RECTS) {
2142 ptr_info[n_ptr].offset = in - start;
2143 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
2144 ptr_info[n_ptr].dest = (void **)&out->clip.rects;
2145 n_ptr++;
2146 in += rects__saved_size;
2147 }
2148 }
2149
2150 assert(in <= message_end);
2151
2152 for (i = 0; i < n_ptr; i++) {
2153 if (ptr_info[i].offset == 0) {
2154 *ptr_info[i].dest = NULL;
2155 } else {
2156 /* Align to 32 bit */
2157 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
2158 *ptr_info[i].dest = (void *)end;
2159 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
2160 if (SPICE_UNLIKELY(end == NULL)) {
2161 goto error;
2162 }
2163 }
2164 }
2165
2166 assert(end <= data + mem_size);
2167
2168 *size = end - data;
2169 *free_message = (message_destructor_t) free;
2170 return data;
2171
2172 error:
2173 free(data);
2174 return NULL;
2175 }
2176
parse_msg_display_stream_destroy(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)2177 static uint8_t * parse_msg_display_stream_destroy(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
2178 {
2179 SPICE_GNUC_UNUSED uint8_t *pos;
2180 uint8_t *start = message_start;
2181 uint8_t *data = NULL;
2182 uint64_t nw_size;
2183 uint64_t mem_size;
2184 uint8_t *in, *end;
2185 SpiceMsgDisplayStreamDestroy *out;
2186
2187 nw_size = 4;
2188 mem_size = sizeof(SpiceMsgDisplayStreamDestroy);
2189
2190 /* Check if message fits in reported side */
2191 if (nw_size > (uintptr_t) (message_end - start)) {
2192 return NULL;
2193 }
2194
2195 /* Validated extents and calculated size */
2196 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
2197 if (SPICE_UNLIKELY(data == NULL)) {
2198 goto error;
2199 }
2200 end = data + sizeof(SpiceMsgDisplayStreamDestroy);
2201 in = start;
2202
2203 out = (SpiceMsgDisplayStreamDestroy *)data;
2204
2205 out->id = consume_uint32(&in);
2206
2207 assert(in <= message_end);
2208 assert(end <= data + mem_size);
2209
2210 *size = end - data;
2211 *free_message = (message_destructor_t) free;
2212 return data;
2213
2214 error:
2215 free(data);
2216 return NULL;
2217 }
2218
validate_SpicePalette(uint8_t * message_start,uint8_t * message_end,uint64_t offset)2219 static intptr_t validate_SpicePalette(uint8_t *message_start, uint8_t *message_end, uint64_t offset)
2220 {
2221 uint8_t *start = message_start + offset;
2222 SPICE_GNUC_UNUSED uint8_t *pos;
2223 uint64_t mem_size, nw_size;
2224 uint64_t ents__nw_size, ents__mem_size;
2225 uint64_t ents__nelements;
2226
2227 if (offset == 0) {
2228 return 0;
2229 }
2230
2231 if (SPICE_UNLIKELY(start >= message_end)) {
2232 goto error;
2233 }
2234
2235 { /* ents */
2236 uint16_t num_ents__value;
2237 pos = start + 8;
2238 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
2239 goto error;
2240 }
2241 num_ents__value = read_uint16(pos);
2242 ents__nelements = num_ents__value;
2243
2244 ents__nw_size = (4) * ents__nelements;
2245 ents__mem_size = sizeof(uint32_t) * ents__nelements;
2246 }
2247
2248 nw_size = 10 + ents__nw_size;
2249 mem_size = sizeof(SpicePalette) + ents__mem_size;
2250
2251 /* Check if struct fits in reported side */
2252 if (SPICE_UNLIKELY(nw_size > (uintptr_t) (message_end - start))) {
2253 goto error;
2254 }
2255 return mem_size;
2256
2257 error:
2258 return -1;
2259 }
2260
validate_SpiceImage(uint8_t * message_start,uint8_t * message_end,uint64_t offset)2261 static intptr_t validate_SpiceImage(uint8_t *message_start, uint8_t *message_end, uint64_t offset)
2262 {
2263 uint8_t *start = message_start + offset;
2264 SPICE_GNUC_UNUSED uint8_t *pos;
2265 uint64_t mem_size, nw_size;
2266 SPICE_GNUC_UNUSED intptr_t ptr_size;
2267 uint64_t u__nw_size, u__extra_size;
2268 uint8_t descriptor_type__value;
2269
2270 if (offset == 0) {
2271 return 0;
2272 }
2273
2274 if (SPICE_UNLIKELY(start >= message_end)) {
2275 goto error;
2276 }
2277
2278 { /* u */
2279 pos = start + 8;
2280 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
2281 goto error;
2282 }
2283 descriptor_type__value = read_uint8(pos);
2284 if (descriptor_type__value == SPICE_IMAGE_TYPE_BITMAP) {
2285 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2286 uint64_t u_pal__nw_size, u_pal__extra_size;
2287 uint8_t flags__value;
2288 uint64_t u_data__nw_size, u_data__extra_size;
2289 uint64_t u_data__nelements;
2290 { /* pal */
2291 pos = start2 + 1;
2292 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
2293 goto error;
2294 }
2295 flags__value = read_uint8(pos);
2296 if ((flags__value & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
2297 u_pal__nw_size = 8;
2298 u_pal__extra_size = 0;
2299 } else if (1) {
2300 uint32_t u_pal_palette__value;
2301 u_pal__nw_size = 4;
2302 pos = (start2 + 14);
2303 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2304 goto error;
2305 }
2306 u_pal_palette__value = read_uint32(pos);
2307 ptr_size = validate_SpicePalette(message_start, message_end, u_pal_palette__value);
2308 if (SPICE_UNLIKELY(ptr_size < 0)) {
2309 goto error;
2310 }
2311 u_pal__extra_size = ptr_size + /* for alignment */ 3;
2312 } else {
2313 u_pal__nw_size = 0;
2314 u_pal__extra_size = 0;
2315 }
2316
2317 }
2318
2319 { /* data */
2320 uint32_t stride__value;
2321 uint32_t y__value;
2322 pos = start2 + 10;
2323 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2324 goto error;
2325 }
2326 stride__value = read_uint32(pos);
2327 pos = start2 + 6;
2328 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2329 goto error;
2330 }
2331 y__value = read_uint32(pos);
2332 u_data__nelements = (uint64_t) stride__value * y__value;
2333
2334 u_data__nw_size = u_data__nelements;
2335 u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
2336 }
2337
2338 u__nw_size = 14 + u_pal__nw_size + u_data__nw_size;
2339 u__extra_size = u_pal__extra_size + u_data__extra_size;
2340 } else if (descriptor_type__value == SPICE_IMAGE_TYPE_QUIC) {
2341 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2342 uint64_t u_data__nw_size, u_data__extra_size;
2343 uint64_t u_data__nelements;
2344 { /* data */
2345 uint32_t data_size__value;
2346 pos = start2 + 0;
2347 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2348 goto error;
2349 }
2350 data_size__value = read_uint32(pos);
2351 u_data__nelements = data_size__value;
2352
2353 u_data__nw_size = u_data__nelements;
2354 u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
2355 }
2356
2357 u__nw_size = 4 + u_data__nw_size;
2358 u__extra_size = u_data__extra_size;
2359 } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ_RGB || descriptor_type__value == SPICE_IMAGE_TYPE_GLZ_RGB) {
2360 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2361 uint64_t u_data__nw_size, u_data__extra_size;
2362 uint64_t u_data__nelements;
2363 { /* data */
2364 uint32_t data_size__value;
2365 pos = start2 + 0;
2366 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2367 goto error;
2368 }
2369 data_size__value = read_uint32(pos);
2370 u_data__nelements = data_size__value;
2371
2372 u_data__nw_size = u_data__nelements;
2373 u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
2374 }
2375
2376 u__nw_size = 4 + u_data__nw_size;
2377 u__extra_size = u_data__extra_size;
2378 } else if (descriptor_type__value == SPICE_IMAGE_TYPE_JPEG) {
2379 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2380 uint64_t u_data__nw_size, u_data__extra_size;
2381 uint64_t u_data__nelements;
2382 { /* data */
2383 uint32_t data_size__value;
2384 pos = start2 + 0;
2385 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2386 goto error;
2387 }
2388 data_size__value = read_uint32(pos);
2389 u_data__nelements = data_size__value;
2390
2391 u_data__nw_size = u_data__nelements;
2392 u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
2393 }
2394
2395 u__nw_size = 4 + u_data__nw_size;
2396 u__extra_size = u_data__extra_size;
2397 } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ4) {
2398 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2399 uint64_t u_data__nw_size, u_data__extra_size;
2400 uint64_t u_data__nelements;
2401 { /* data */
2402 uint32_t data_size__value;
2403 pos = start2 + 0;
2404 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2405 goto error;
2406 }
2407 data_size__value = read_uint32(pos);
2408 u_data__nelements = data_size__value;
2409
2410 u_data__nw_size = u_data__nelements;
2411 u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
2412 }
2413
2414 u__nw_size = 4 + u_data__nw_size;
2415 u__extra_size = u_data__extra_size;
2416 } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ_PLT) {
2417 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2418 uint64_t u_pal__nw_size, u_pal__extra_size;
2419 uint8_t flags__value;
2420 uint64_t u_data__nw_size, u_data__extra_size;
2421 uint64_t u_data__nelements;
2422 { /* pal */
2423 pos = start2 + 0;
2424 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
2425 goto error;
2426 }
2427 flags__value = read_uint8(pos);
2428 if ((flags__value & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
2429 u_pal__nw_size = 8;
2430 u_pal__extra_size = 0;
2431 } else if (1) {
2432 uint32_t u_pal_palette__value;
2433 u_pal__nw_size = 4;
2434 pos = (start2 + 5);
2435 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2436 goto error;
2437 }
2438 u_pal_palette__value = read_uint32(pos);
2439 if (SPICE_UNLIKELY(u_pal_palette__value == 0)) {
2440 goto error;
2441 }
2442 ptr_size = validate_SpicePalette(message_start, message_end, u_pal_palette__value);
2443 if (SPICE_UNLIKELY(ptr_size < 0)) {
2444 goto error;
2445 }
2446 u_pal__extra_size = ptr_size + /* for alignment */ 3;
2447 } else {
2448 u_pal__nw_size = 0;
2449 u_pal__extra_size = 0;
2450 }
2451
2452 }
2453
2454 { /* data */
2455 uint32_t data_size__value;
2456 pos = start2 + 1;
2457 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2458 goto error;
2459 }
2460 data_size__value = read_uint32(pos);
2461 u_data__nelements = data_size__value;
2462
2463 u_data__nw_size = u_data__nelements;
2464 u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
2465 }
2466
2467 u__nw_size = 5 + u_pal__nw_size + u_data__nw_size;
2468 u__extra_size = u_pal__extra_size + u_data__extra_size;
2469 } else if (descriptor_type__value == SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB) {
2470 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2471 uint64_t u_data__nw_size, u_data__extra_size;
2472 uint64_t u_data__nelements;
2473 { /* data */
2474 uint32_t data_size__value;
2475 pos = start2 + 4;
2476 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2477 goto error;
2478 }
2479 data_size__value = read_uint32(pos);
2480 u_data__nelements = data_size__value;
2481
2482 u_data__nw_size = u_data__nelements;
2483 u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
2484 }
2485
2486 u__nw_size = 8 + u_data__nw_size;
2487 u__extra_size = u_data__extra_size;
2488 } else if (descriptor_type__value == SPICE_IMAGE_TYPE_JPEG_ALPHA) {
2489 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2490 uint64_t u_data__nw_size, u_data__extra_size;
2491 uint64_t u_data__nelements;
2492 { /* data */
2493 uint32_t data_size__value;
2494 pos = start2 + 5;
2495 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2496 goto error;
2497 }
2498 data_size__value = read_uint32(pos);
2499 u_data__nelements = data_size__value;
2500
2501 u_data__nw_size = u_data__nelements;
2502 u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
2503 }
2504
2505 u__nw_size = 9 + u_data__nw_size;
2506 u__extra_size = u_data__extra_size;
2507 } else if (descriptor_type__value == SPICE_IMAGE_TYPE_SURFACE) {
2508 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
2509 u__nw_size = 4;
2510 u__extra_size = 0;
2511 } else {
2512 u__nw_size = 0;
2513 u__extra_size = 0;
2514 }
2515
2516 }
2517
2518 nw_size = 18 + u__nw_size;
2519 mem_size = sizeof(SpiceImage) + u__extra_size;
2520
2521 /* Check if struct fits in reported side */
2522 if (SPICE_UNLIKELY(nw_size > (uintptr_t) (message_end - start))) {
2523 goto error;
2524 }
2525 return mem_size;
2526
2527 error:
2528 return -1;
2529 }
2530
parse_struct_SpicePalette(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)2531 static uint8_t * parse_struct_SpicePalette(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
2532 {
2533 uint8_t *in = message_start + this_ptr_info->offset;
2534 uint8_t *end;
2535 SpicePalette *out;
2536 uint64_t ents__nelements;
2537 uint32_t i;
2538
2539 end = struct_data + sizeof(SpicePalette);
2540 out = (SpicePalette *)struct_data;
2541
2542 out->unique = consume_uint64(&in);
2543 out->num_ents = consume_uint16(&in);
2544 ents__nelements = out->num_ents;
2545 for (i = 0; i < ents__nelements; i++) {
2546 out->ents[i] = consume_uint32(&in);
2547 end += sizeof(uint32_t);
2548 }
2549 return end;
2550 }
2551
parse_struct_SpiceImage(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)2552 static uint8_t * parse_struct_SpiceImage(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
2553 {
2554 uint8_t *in = message_start + this_ptr_info->offset;
2555 uint8_t *end;
2556 SPICE_GNUC_UNUSED intptr_t ptr_size;
2557 uint32_t n_ptr=0;
2558 PointerInfo ptr_info[1];
2559 SpiceImage *out;
2560 uint32_t i;
2561
2562 end = struct_data + sizeof(SpiceImage);
2563 out = (SpiceImage *)struct_data;
2564
2565 /* descriptor */ {
2566 out->descriptor.id = consume_uint64(&in);
2567 out->descriptor.type = consume_uint8(&in);
2568 out->descriptor.flags = consume_uint8(&in);
2569 out->descriptor.width = consume_uint32(&in);
2570 out->descriptor.height = consume_uint32(&in);
2571 }
2572 if (out->descriptor.type == SPICE_IMAGE_TYPE_BITMAP) {
2573 uint64_t data__nelements;
2574 SpiceChunks *chunks;
2575 out->u.bitmap.format = consume_uint8(&in);
2576 out->u.bitmap.flags = consume_uint8(&in);
2577 out->u.bitmap.x = consume_uint32(&in);
2578 out->u.bitmap.y = consume_uint32(&in);
2579 out->u.bitmap.stride = consume_uint32(&in);
2580 if ((out->u.bitmap.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
2581 out->u.bitmap.palette_id = consume_uint64(&in);
2582 } else if (1) {
2583 ptr_info[n_ptr].offset = consume_uint32(&in);
2584 ptr_info[n_ptr].parse = parse_struct_SpicePalette;
2585 ptr_info[n_ptr].dest = (void **)&out->u.bitmap.palette;
2586 n_ptr++;
2587 }
2588 data__nelements = ((uint64_t) out->u.bitmap.stride * out->u.bitmap.y);
2589 /* use array as chunk */
2590 chunks = (SpiceChunks *)end;
2591 end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
2592 out->u.bitmap.data = chunks;
2593 chunks->data_size = data__nelements;
2594 chunks->flags = 0;
2595 chunks->num_chunks = 1;
2596 chunks->chunk[0].len = data__nelements;
2597 chunks->chunk[0].data = in;
2598 in += data__nelements;
2599 } else if (out->descriptor.type == SPICE_IMAGE_TYPE_QUIC) {
2600 uint64_t data__nelements;
2601 SpiceChunks *chunks;
2602 out->u.quic.data_size = consume_uint32(&in);
2603 data__nelements = out->u.quic.data_size;
2604 /* use array as chunk */
2605 chunks = (SpiceChunks *)end;
2606 end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
2607 out->u.quic.data = chunks;
2608 chunks->data_size = data__nelements;
2609 chunks->flags = 0;
2610 chunks->num_chunks = 1;
2611 chunks->chunk[0].len = data__nelements;
2612 chunks->chunk[0].data = in;
2613 in += data__nelements;
2614 } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB || out->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB) {
2615 uint64_t data__nelements;
2616 SpiceChunks *chunks;
2617 out->u.lz_rgb.data_size = consume_uint32(&in);
2618 data__nelements = out->u.lz_rgb.data_size;
2619 /* use array as chunk */
2620 chunks = (SpiceChunks *)end;
2621 end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
2622 out->u.lz_rgb.data = chunks;
2623 chunks->data_size = data__nelements;
2624 chunks->flags = 0;
2625 chunks->num_chunks = 1;
2626 chunks->chunk[0].len = data__nelements;
2627 chunks->chunk[0].data = in;
2628 in += data__nelements;
2629 } else if (out->descriptor.type == SPICE_IMAGE_TYPE_JPEG) {
2630 uint64_t data__nelements;
2631 SpiceChunks *chunks;
2632 out->u.jpeg.data_size = consume_uint32(&in);
2633 data__nelements = out->u.jpeg.data_size;
2634 /* use array as chunk */
2635 chunks = (SpiceChunks *)end;
2636 end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
2637 out->u.jpeg.data = chunks;
2638 chunks->data_size = data__nelements;
2639 chunks->flags = 0;
2640 chunks->num_chunks = 1;
2641 chunks->chunk[0].len = data__nelements;
2642 chunks->chunk[0].data = in;
2643 in += data__nelements;
2644 } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ4) {
2645 uint64_t data__nelements;
2646 SpiceChunks *chunks;
2647 out->u.lz4.data_size = consume_uint32(&in);
2648 data__nelements = out->u.lz4.data_size;
2649 /* use array as chunk */
2650 chunks = (SpiceChunks *)end;
2651 end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
2652 out->u.lz4.data = chunks;
2653 chunks->data_size = data__nelements;
2654 chunks->flags = 0;
2655 chunks->num_chunks = 1;
2656 chunks->chunk[0].len = data__nelements;
2657 chunks->chunk[0].data = in;
2658 in += data__nelements;
2659 } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
2660 uint64_t data__nelements;
2661 SpiceChunks *chunks;
2662 out->u.lz_plt.flags = consume_uint8(&in);
2663 out->u.lz_plt.data_size = consume_uint32(&in);
2664 if ((out->u.lz_plt.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
2665 out->u.lz_plt.palette_id = consume_uint64(&in);
2666 } else if (1) {
2667 ptr_info[n_ptr].offset = consume_uint32(&in);
2668 ptr_info[n_ptr].parse = parse_struct_SpicePalette;
2669 ptr_info[n_ptr].dest = (void **)&out->u.lz_plt.palette;
2670 n_ptr++;
2671 }
2672 data__nelements = out->u.lz_plt.data_size;
2673 /* use array as chunk */
2674 chunks = (SpiceChunks *)end;
2675 end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
2676 out->u.lz_plt.data = chunks;
2677 chunks->data_size = data__nelements;
2678 chunks->flags = 0;
2679 chunks->num_chunks = 1;
2680 chunks->chunk[0].len = data__nelements;
2681 chunks->chunk[0].data = in;
2682 in += data__nelements;
2683 } else if (out->descriptor.type == SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB) {
2684 uint64_t data__nelements;
2685 SpiceChunks *chunks;
2686 out->u.zlib_glz.glz_data_size = consume_uint32(&in);
2687 out->u.zlib_glz.data_size = consume_uint32(&in);
2688 data__nelements = out->u.zlib_glz.data_size;
2689 /* use array as chunk */
2690 chunks = (SpiceChunks *)end;
2691 end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
2692 out->u.zlib_glz.data = chunks;
2693 chunks->data_size = data__nelements;
2694 chunks->flags = 0;
2695 chunks->num_chunks = 1;
2696 chunks->chunk[0].len = data__nelements;
2697 chunks->chunk[0].data = in;
2698 in += data__nelements;
2699 } else if (out->descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA) {
2700 uint64_t data__nelements;
2701 SpiceChunks *chunks;
2702 out->u.jpeg_alpha.flags = consume_uint8(&in);
2703 out->u.jpeg_alpha.jpeg_size = consume_uint32(&in);
2704 out->u.jpeg_alpha.data_size = consume_uint32(&in);
2705 data__nelements = out->u.jpeg_alpha.data_size;
2706 /* use array as chunk */
2707 chunks = (SpiceChunks *)end;
2708 end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
2709 out->u.jpeg_alpha.data = chunks;
2710 chunks->data_size = data__nelements;
2711 chunks->flags = 0;
2712 chunks->num_chunks = 1;
2713 chunks->chunk[0].len = data__nelements;
2714 chunks->chunk[0].data = in;
2715 in += data__nelements;
2716 } else if (out->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
2717 out->u.surface.surface_id = consume_uint32(&in);
2718 }
2719
2720 for (i = 0; i < n_ptr; i++) {
2721 if (ptr_info[i].offset == 0) {
2722 *ptr_info[i].dest = NULL;
2723 } else {
2724 /* Align to 32 bit */
2725 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
2726 *ptr_info[i].dest = (void *)end;
2727 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
2728 if (SPICE_UNLIKELY(end == NULL)) {
2729 goto error;
2730 }
2731 }
2732 }
2733
2734 return end;
2735
2736 error:
2737 return NULL;
2738 }
2739
parse_msg_display_draw_fill(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)2740 static uint8_t * parse_msg_display_draw_fill(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
2741 {
2742 SPICE_GNUC_UNUSED uint8_t *pos;
2743 uint8_t *start = message_start;
2744 uint8_t *data = NULL;
2745 uint64_t nw_size;
2746 uint64_t mem_size;
2747 uint8_t *in, *end;
2748 SPICE_GNUC_UNUSED intptr_t ptr_size;
2749 uint32_t n_ptr=0;
2750 PointerInfo ptr_info[3];
2751 uint64_t base__nw_size, base__extra_size;
2752 uint32_t rects__saved_size = 0;
2753 uint64_t data__nw_size, data__extra_size;
2754 SpiceMsgDisplayDrawFill *out;
2755 uint32_t i;
2756
2757 { /* base */
2758 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
2759 uint64_t base_clip__nw_size, base_clip__extra_size;
2760 { /* clip */
2761 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
2762 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
2763 uint8_t type__value;
2764 { /* u */
2765 uint64_t base_clip_u__mem_size;
2766 pos = start3 + 0;
2767 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
2768 goto error;
2769 }
2770 type__value = read_uint8(pos);
2771 if (type__value == SPICE_CLIP_TYPE_RECTS) {
2772 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
2773 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
2774 uint64_t base_clip_u_rects__nelements;
2775 { /* rects */
2776 uint32_t num_rects__value;
2777 pos = start4 + 0;
2778 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2779 goto error;
2780 }
2781 num_rects__value = read_uint32(pos);
2782 base_clip_u_rects__nelements = num_rects__value;
2783
2784 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
2785 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
2786 }
2787
2788 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
2789 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
2790 rects__saved_size = base_clip_u__nw_size;
2791 base_clip_u__extra_size = base_clip_u__mem_size;
2792 } else {
2793 base_clip_u__nw_size = 0;
2794 base_clip_u__extra_size = 0;
2795 }
2796
2797 }
2798
2799 base_clip__nw_size = 1 + base_clip_u__nw_size;
2800 base_clip__extra_size = base_clip_u__extra_size;
2801 }
2802
2803 base__nw_size = 20 + base_clip__nw_size;
2804 base__extra_size = base_clip__extra_size;
2805 }
2806
2807 { /* data */
2808 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
2809 uint64_t data_brush__nw_size, data_brush__extra_size;
2810 uint64_t data_mask__extra_size;
2811 { /* brush */
2812 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
2813 uint64_t data_brush_u__nw_size, data_brush_u__extra_size;
2814 uint8_t type__value;
2815 { /* u */
2816 pos = start3 + 0;
2817 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
2818 goto error;
2819 }
2820 type__value = read_uint8(pos);
2821 if (type__value == SPICE_BRUSH_TYPE_SOLID) {
2822 data_brush_u__nw_size = 4;
2823 data_brush_u__extra_size = 0;
2824 } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
2825 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
2826 uint64_t data_brush_u_pat__extra_size;
2827 { /* pat */
2828 uint32_t pat__value;
2829 pos = (start4 + 0);
2830 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2831 goto error;
2832 }
2833 pat__value = read_uint32(pos);
2834 if (SPICE_UNLIKELY(pat__value == 0)) {
2835 goto error;
2836 }
2837 ptr_size = validate_SpiceImage(message_start, message_end, pat__value);
2838 if (SPICE_UNLIKELY(ptr_size < 0)) {
2839 goto error;
2840 }
2841 data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
2842 }
2843
2844 data_brush_u__nw_size = 12;
2845 data_brush_u__extra_size = data_brush_u_pat__extra_size;
2846 } else {
2847 data_brush_u__nw_size = 0;
2848 data_brush_u__extra_size = 0;
2849 }
2850
2851 }
2852
2853 data_brush__nw_size = 1 + data_brush_u__nw_size;
2854 data_brush__extra_size = data_brush_u__extra_size;
2855 }
2856
2857 { /* mask */
2858 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 2 + data_brush__nw_size);
2859 uint64_t data_mask_bitmap__extra_size;
2860 { /* bitmap */
2861 uint32_t bitmap__value;
2862 pos = (start3 + 9);
2863 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
2864 goto error;
2865 }
2866 bitmap__value = read_uint32(pos);
2867 ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value);
2868 if (SPICE_UNLIKELY(ptr_size < 0)) {
2869 goto error;
2870 }
2871 data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
2872 }
2873
2874 data_mask__extra_size = data_mask_bitmap__extra_size;
2875 }
2876
2877 data__nw_size = 15 + data_brush__nw_size;
2878 data__extra_size = data_brush__extra_size + data_mask__extra_size;
2879 }
2880
2881 nw_size = 0 + base__nw_size + data__nw_size;
2882 mem_size = sizeof(SpiceMsgDisplayDrawFill) + base__extra_size + data__extra_size;
2883
2884 /* Check if message fits in reported side */
2885 if (nw_size > (uintptr_t) (message_end - start)) {
2886 return NULL;
2887 }
2888
2889 /* Validated extents and calculated size */
2890 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
2891 if (SPICE_UNLIKELY(data == NULL)) {
2892 goto error;
2893 }
2894 end = data + sizeof(SpiceMsgDisplayDrawFill);
2895 in = start;
2896
2897 out = (SpiceMsgDisplayDrawFill *)data;
2898
2899 /* base */ {
2900 out->base.surface_id = consume_uint32(&in);
2901 /* box */ {
2902 out->base.box.top = consume_int32(&in);
2903 out->base.box.left = consume_int32(&in);
2904 out->base.box.bottom = consume_int32(&in);
2905 out->base.box.right = consume_int32(&in);
2906 }
2907 /* clip */ {
2908 out->base.clip.type = consume_uint8(&in);
2909 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
2910 ptr_info[n_ptr].offset = in - start;
2911 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
2912 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
2913 n_ptr++;
2914 in += rects__saved_size;
2915 }
2916 }
2917 }
2918 /* data */ {
2919 /* brush */ {
2920 out->data.brush.type = consume_uint8(&in);
2921 if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
2922 out->data.brush.u.color = consume_uint32(&in);
2923 } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
2924 ptr_info[n_ptr].offset = consume_uint32(&in);
2925 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
2926 ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
2927 n_ptr++;
2928 /* pos */ {
2929 out->data.brush.u.pattern.pos.x = consume_int32(&in);
2930 out->data.brush.u.pattern.pos.y = consume_int32(&in);
2931 }
2932 }
2933 }
2934 out->data.rop_descriptor = consume_uint16(&in);
2935 /* mask */ {
2936 out->data.mask.flags = consume_uint8(&in);
2937 /* pos */ {
2938 out->data.mask.pos.x = consume_int32(&in);
2939 out->data.mask.pos.y = consume_int32(&in);
2940 }
2941 ptr_info[n_ptr].offset = consume_uint32(&in);
2942 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
2943 ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
2944 n_ptr++;
2945 }
2946 }
2947
2948 assert(in <= message_end);
2949
2950 for (i = 0; i < n_ptr; i++) {
2951 if (ptr_info[i].offset == 0) {
2952 *ptr_info[i].dest = NULL;
2953 } else {
2954 /* Align to 32 bit */
2955 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
2956 *ptr_info[i].dest = (void *)end;
2957 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
2958 if (SPICE_UNLIKELY(end == NULL)) {
2959 goto error;
2960 }
2961 }
2962 }
2963
2964 assert(end <= data + mem_size);
2965
2966 *size = end - data;
2967 *free_message = (message_destructor_t) free;
2968 return data;
2969
2970 error:
2971 free(data);
2972 return NULL;
2973 }
2974
parse_msg_display_draw_opaque(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)2975 static uint8_t * parse_msg_display_draw_opaque(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
2976 {
2977 SPICE_GNUC_UNUSED uint8_t *pos;
2978 uint8_t *start = message_start;
2979 uint8_t *data = NULL;
2980 uint64_t nw_size;
2981 uint64_t mem_size;
2982 uint8_t *in, *end;
2983 SPICE_GNUC_UNUSED intptr_t ptr_size;
2984 uint32_t n_ptr=0;
2985 PointerInfo ptr_info[4];
2986 uint64_t base__nw_size, base__extra_size;
2987 uint32_t rects__saved_size = 0;
2988 uint64_t data__nw_size, data__extra_size;
2989 SpiceMsgDisplayDrawOpaque *out;
2990 uint32_t i;
2991
2992 { /* base */
2993 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
2994 uint64_t base_clip__nw_size, base_clip__extra_size;
2995 { /* clip */
2996 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
2997 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
2998 uint8_t type__value;
2999 { /* u */
3000 uint64_t base_clip_u__mem_size;
3001 pos = start3 + 0;
3002 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
3003 goto error;
3004 }
3005 type__value = read_uint8(pos);
3006 if (type__value == SPICE_CLIP_TYPE_RECTS) {
3007 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
3008 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
3009 uint64_t base_clip_u_rects__nelements;
3010 { /* rects */
3011 uint32_t num_rects__value;
3012 pos = start4 + 0;
3013 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3014 goto error;
3015 }
3016 num_rects__value = read_uint32(pos);
3017 base_clip_u_rects__nelements = num_rects__value;
3018
3019 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
3020 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
3021 }
3022
3023 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
3024 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
3025 rects__saved_size = base_clip_u__nw_size;
3026 base_clip_u__extra_size = base_clip_u__mem_size;
3027 } else {
3028 base_clip_u__nw_size = 0;
3029 base_clip_u__extra_size = 0;
3030 }
3031
3032 }
3033
3034 base_clip__nw_size = 1 + base_clip_u__nw_size;
3035 base_clip__extra_size = base_clip_u__extra_size;
3036 }
3037
3038 base__nw_size = 20 + base_clip__nw_size;
3039 base__extra_size = base_clip__extra_size;
3040 }
3041
3042 { /* data */
3043 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
3044 uint64_t data_src_bitmap__extra_size;
3045 uint64_t data_brush__nw_size, data_brush__extra_size;
3046 uint64_t data_mask__extra_size;
3047 { /* src_bitmap */
3048 uint32_t src_bitmap__value;
3049 pos = (start2 + 0);
3050 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3051 goto error;
3052 }
3053 src_bitmap__value = read_uint32(pos);
3054 ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value);
3055 if (SPICE_UNLIKELY(ptr_size < 0)) {
3056 goto error;
3057 }
3058 data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
3059 }
3060
3061 { /* brush */
3062 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
3063 uint64_t data_brush_u__nw_size, data_brush_u__extra_size;
3064 uint8_t type__value;
3065 { /* u */
3066 pos = start3 + 0;
3067 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
3068 goto error;
3069 }
3070 type__value = read_uint8(pos);
3071 if (type__value == SPICE_BRUSH_TYPE_SOLID) {
3072 data_brush_u__nw_size = 4;
3073 data_brush_u__extra_size = 0;
3074 } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
3075 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
3076 uint64_t data_brush_u_pat__extra_size;
3077 { /* pat */
3078 uint32_t pat__value;
3079 pos = (start4 + 0);
3080 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3081 goto error;
3082 }
3083 pat__value = read_uint32(pos);
3084 if (SPICE_UNLIKELY(pat__value == 0)) {
3085 goto error;
3086 }
3087 ptr_size = validate_SpiceImage(message_start, message_end, pat__value);
3088 if (SPICE_UNLIKELY(ptr_size < 0)) {
3089 goto error;
3090 }
3091 data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
3092 }
3093
3094 data_brush_u__nw_size = 12;
3095 data_brush_u__extra_size = data_brush_u_pat__extra_size;
3096 } else {
3097 data_brush_u__nw_size = 0;
3098 data_brush_u__extra_size = 0;
3099 }
3100
3101 }
3102
3103 data_brush__nw_size = 1 + data_brush_u__nw_size;
3104 data_brush__extra_size = data_brush_u__extra_size;
3105 }
3106
3107 { /* mask */
3108 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 23 + data_brush__nw_size);
3109 uint64_t data_mask_bitmap__extra_size;
3110 { /* bitmap */
3111 uint32_t bitmap__value;
3112 pos = (start3 + 9);
3113 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3114 goto error;
3115 }
3116 bitmap__value = read_uint32(pos);
3117 ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value);
3118 if (SPICE_UNLIKELY(ptr_size < 0)) {
3119 goto error;
3120 }
3121 data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
3122 }
3123
3124 data_mask__extra_size = data_mask_bitmap__extra_size;
3125 }
3126
3127 data__nw_size = 36 + data_brush__nw_size;
3128 data__extra_size = data_src_bitmap__extra_size + data_brush__extra_size + data_mask__extra_size;
3129 }
3130
3131 nw_size = 0 + base__nw_size + data__nw_size;
3132 mem_size = sizeof(SpiceMsgDisplayDrawOpaque) + base__extra_size + data__extra_size;
3133
3134 /* Check if message fits in reported side */
3135 if (nw_size > (uintptr_t) (message_end - start)) {
3136 return NULL;
3137 }
3138
3139 /* Validated extents and calculated size */
3140 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
3141 if (SPICE_UNLIKELY(data == NULL)) {
3142 goto error;
3143 }
3144 end = data + sizeof(SpiceMsgDisplayDrawOpaque);
3145 in = start;
3146
3147 out = (SpiceMsgDisplayDrawOpaque *)data;
3148
3149 /* base */ {
3150 out->base.surface_id = consume_uint32(&in);
3151 /* box */ {
3152 out->base.box.top = consume_int32(&in);
3153 out->base.box.left = consume_int32(&in);
3154 out->base.box.bottom = consume_int32(&in);
3155 out->base.box.right = consume_int32(&in);
3156 }
3157 /* clip */ {
3158 out->base.clip.type = consume_uint8(&in);
3159 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
3160 ptr_info[n_ptr].offset = in - start;
3161 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
3162 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
3163 n_ptr++;
3164 in += rects__saved_size;
3165 }
3166 }
3167 }
3168 /* data */ {
3169 ptr_info[n_ptr].offset = consume_uint32(&in);
3170 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3171 ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
3172 n_ptr++;
3173 /* src_area */ {
3174 out->data.src_area.top = consume_int32(&in);
3175 out->data.src_area.left = consume_int32(&in);
3176 out->data.src_area.bottom = consume_int32(&in);
3177 out->data.src_area.right = consume_int32(&in);
3178 }
3179 /* brush */ {
3180 out->data.brush.type = consume_uint8(&in);
3181 if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
3182 out->data.brush.u.color = consume_uint32(&in);
3183 } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
3184 ptr_info[n_ptr].offset = consume_uint32(&in);
3185 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3186 ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
3187 n_ptr++;
3188 /* pos */ {
3189 out->data.brush.u.pattern.pos.x = consume_int32(&in);
3190 out->data.brush.u.pattern.pos.y = consume_int32(&in);
3191 }
3192 }
3193 }
3194 out->data.rop_descriptor = consume_uint16(&in);
3195 out->data.scale_mode = consume_uint8(&in);
3196 /* mask */ {
3197 out->data.mask.flags = consume_uint8(&in);
3198 /* pos */ {
3199 out->data.mask.pos.x = consume_int32(&in);
3200 out->data.mask.pos.y = consume_int32(&in);
3201 }
3202 ptr_info[n_ptr].offset = consume_uint32(&in);
3203 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3204 ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
3205 n_ptr++;
3206 }
3207 }
3208
3209 assert(in <= message_end);
3210
3211 for (i = 0; i < n_ptr; i++) {
3212 if (ptr_info[i].offset == 0) {
3213 *ptr_info[i].dest = NULL;
3214 } else {
3215 /* Align to 32 bit */
3216 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
3217 *ptr_info[i].dest = (void *)end;
3218 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
3219 if (SPICE_UNLIKELY(end == NULL)) {
3220 goto error;
3221 }
3222 }
3223 }
3224
3225 assert(end <= data + mem_size);
3226
3227 *size = end - data;
3228 *free_message = (message_destructor_t) free;
3229 return data;
3230
3231 error:
3232 free(data);
3233 return NULL;
3234 }
3235
parse_msg_display_draw_copy(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)3236 static uint8_t * parse_msg_display_draw_copy(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
3237 {
3238 SPICE_GNUC_UNUSED uint8_t *pos;
3239 uint8_t *start = message_start;
3240 uint8_t *data = NULL;
3241 uint64_t nw_size;
3242 uint64_t mem_size;
3243 uint8_t *in, *end;
3244 SPICE_GNUC_UNUSED intptr_t ptr_size;
3245 uint32_t n_ptr=0;
3246 PointerInfo ptr_info[3];
3247 uint64_t base__nw_size, base__extra_size;
3248 uint32_t rects__saved_size = 0;
3249 uint64_t data__extra_size;
3250 SpiceMsgDisplayDrawCopy *out;
3251 uint32_t i;
3252
3253 { /* base */
3254 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
3255 uint64_t base_clip__nw_size, base_clip__extra_size;
3256 { /* clip */
3257 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
3258 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
3259 uint8_t type__value;
3260 { /* u */
3261 uint64_t base_clip_u__mem_size;
3262 pos = start3 + 0;
3263 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
3264 goto error;
3265 }
3266 type__value = read_uint8(pos);
3267 if (type__value == SPICE_CLIP_TYPE_RECTS) {
3268 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
3269 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
3270 uint64_t base_clip_u_rects__nelements;
3271 { /* rects */
3272 uint32_t num_rects__value;
3273 pos = start4 + 0;
3274 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3275 goto error;
3276 }
3277 num_rects__value = read_uint32(pos);
3278 base_clip_u_rects__nelements = num_rects__value;
3279
3280 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
3281 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
3282 }
3283
3284 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
3285 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
3286 rects__saved_size = base_clip_u__nw_size;
3287 base_clip_u__extra_size = base_clip_u__mem_size;
3288 } else {
3289 base_clip_u__nw_size = 0;
3290 base_clip_u__extra_size = 0;
3291 }
3292
3293 }
3294
3295 base_clip__nw_size = 1 + base_clip_u__nw_size;
3296 base_clip__extra_size = base_clip_u__extra_size;
3297 }
3298
3299 base__nw_size = 20 + base_clip__nw_size;
3300 base__extra_size = base_clip__extra_size;
3301 }
3302
3303 { /* data */
3304 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
3305 uint64_t data_src_bitmap__extra_size;
3306 uint64_t data_mask__extra_size;
3307 { /* src_bitmap */
3308 uint32_t src_bitmap__value;
3309 pos = (start2 + 0);
3310 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3311 goto error;
3312 }
3313 src_bitmap__value = read_uint32(pos);
3314 ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value);
3315 if (SPICE_UNLIKELY(ptr_size < 0)) {
3316 goto error;
3317 }
3318 data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
3319 }
3320
3321 { /* mask */
3322 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 23);
3323 uint64_t data_mask_bitmap__extra_size;
3324 { /* bitmap */
3325 uint32_t bitmap__value;
3326 pos = (start3 + 9);
3327 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3328 goto error;
3329 }
3330 bitmap__value = read_uint32(pos);
3331 ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value);
3332 if (SPICE_UNLIKELY(ptr_size < 0)) {
3333 goto error;
3334 }
3335 data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
3336 }
3337
3338 data_mask__extra_size = data_mask_bitmap__extra_size;
3339 }
3340
3341 data__extra_size = data_src_bitmap__extra_size + data_mask__extra_size;
3342 }
3343
3344 nw_size = 36 + base__nw_size;
3345 mem_size = sizeof(SpiceMsgDisplayDrawCopy) + base__extra_size + data__extra_size;
3346
3347 /* Check if message fits in reported side */
3348 if (nw_size > (uintptr_t) (message_end - start)) {
3349 return NULL;
3350 }
3351
3352 /* Validated extents and calculated size */
3353 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
3354 if (SPICE_UNLIKELY(data == NULL)) {
3355 goto error;
3356 }
3357 end = data + sizeof(SpiceMsgDisplayDrawCopy);
3358 in = start;
3359
3360 out = (SpiceMsgDisplayDrawCopy *)data;
3361
3362 /* base */ {
3363 out->base.surface_id = consume_uint32(&in);
3364 /* box */ {
3365 out->base.box.top = consume_int32(&in);
3366 out->base.box.left = consume_int32(&in);
3367 out->base.box.bottom = consume_int32(&in);
3368 out->base.box.right = consume_int32(&in);
3369 }
3370 /* clip */ {
3371 out->base.clip.type = consume_uint8(&in);
3372 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
3373 ptr_info[n_ptr].offset = in - start;
3374 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
3375 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
3376 n_ptr++;
3377 in += rects__saved_size;
3378 }
3379 }
3380 }
3381 /* data */ {
3382 ptr_info[n_ptr].offset = consume_uint32(&in);
3383 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3384 ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
3385 n_ptr++;
3386 /* src_area */ {
3387 out->data.src_area.top = consume_int32(&in);
3388 out->data.src_area.left = consume_int32(&in);
3389 out->data.src_area.bottom = consume_int32(&in);
3390 out->data.src_area.right = consume_int32(&in);
3391 }
3392 out->data.rop_descriptor = consume_uint16(&in);
3393 out->data.scale_mode = consume_uint8(&in);
3394 /* mask */ {
3395 out->data.mask.flags = consume_uint8(&in);
3396 /* pos */ {
3397 out->data.mask.pos.x = consume_int32(&in);
3398 out->data.mask.pos.y = consume_int32(&in);
3399 }
3400 ptr_info[n_ptr].offset = consume_uint32(&in);
3401 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3402 ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
3403 n_ptr++;
3404 }
3405 }
3406
3407 assert(in <= message_end);
3408
3409 for (i = 0; i < n_ptr; i++) {
3410 if (ptr_info[i].offset == 0) {
3411 *ptr_info[i].dest = NULL;
3412 } else {
3413 /* Align to 32 bit */
3414 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
3415 *ptr_info[i].dest = (void *)end;
3416 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
3417 if (SPICE_UNLIKELY(end == NULL)) {
3418 goto error;
3419 }
3420 }
3421 }
3422
3423 assert(end <= data + mem_size);
3424
3425 *size = end - data;
3426 *free_message = (message_destructor_t) free;
3427 return data;
3428
3429 error:
3430 free(data);
3431 return NULL;
3432 }
3433
parse_msg_display_draw_blend(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)3434 static uint8_t * parse_msg_display_draw_blend(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
3435 {
3436 SPICE_GNUC_UNUSED uint8_t *pos;
3437 uint8_t *start = message_start;
3438 uint8_t *data = NULL;
3439 uint64_t nw_size;
3440 uint64_t mem_size;
3441 uint8_t *in, *end;
3442 SPICE_GNUC_UNUSED intptr_t ptr_size;
3443 uint32_t n_ptr=0;
3444 PointerInfo ptr_info[3];
3445 uint64_t base__nw_size, base__extra_size;
3446 uint32_t rects__saved_size = 0;
3447 uint64_t data__extra_size;
3448 SpiceMsgDisplayDrawCopy *out;
3449 uint32_t i;
3450
3451 { /* base */
3452 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
3453 uint64_t base_clip__nw_size, base_clip__extra_size;
3454 { /* clip */
3455 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
3456 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
3457 uint8_t type__value;
3458 { /* u */
3459 uint64_t base_clip_u__mem_size;
3460 pos = start3 + 0;
3461 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
3462 goto error;
3463 }
3464 type__value = read_uint8(pos);
3465 if (type__value == SPICE_CLIP_TYPE_RECTS) {
3466 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
3467 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
3468 uint64_t base_clip_u_rects__nelements;
3469 { /* rects */
3470 uint32_t num_rects__value;
3471 pos = start4 + 0;
3472 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3473 goto error;
3474 }
3475 num_rects__value = read_uint32(pos);
3476 base_clip_u_rects__nelements = num_rects__value;
3477
3478 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
3479 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
3480 }
3481
3482 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
3483 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
3484 rects__saved_size = base_clip_u__nw_size;
3485 base_clip_u__extra_size = base_clip_u__mem_size;
3486 } else {
3487 base_clip_u__nw_size = 0;
3488 base_clip_u__extra_size = 0;
3489 }
3490
3491 }
3492
3493 base_clip__nw_size = 1 + base_clip_u__nw_size;
3494 base_clip__extra_size = base_clip_u__extra_size;
3495 }
3496
3497 base__nw_size = 20 + base_clip__nw_size;
3498 base__extra_size = base_clip__extra_size;
3499 }
3500
3501 { /* data */
3502 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
3503 uint64_t data_src_bitmap__extra_size;
3504 uint64_t data_mask__extra_size;
3505 { /* src_bitmap */
3506 uint32_t src_bitmap__value;
3507 pos = (start2 + 0);
3508 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3509 goto error;
3510 }
3511 src_bitmap__value = read_uint32(pos);
3512 ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value);
3513 if (SPICE_UNLIKELY(ptr_size < 0)) {
3514 goto error;
3515 }
3516 data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
3517 }
3518
3519 { /* mask */
3520 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 23);
3521 uint64_t data_mask_bitmap__extra_size;
3522 { /* bitmap */
3523 uint32_t bitmap__value;
3524 pos = (start3 + 9);
3525 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3526 goto error;
3527 }
3528 bitmap__value = read_uint32(pos);
3529 ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value);
3530 if (SPICE_UNLIKELY(ptr_size < 0)) {
3531 goto error;
3532 }
3533 data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
3534 }
3535
3536 data_mask__extra_size = data_mask_bitmap__extra_size;
3537 }
3538
3539 data__extra_size = data_src_bitmap__extra_size + data_mask__extra_size;
3540 }
3541
3542 nw_size = 36 + base__nw_size;
3543 mem_size = sizeof(SpiceMsgDisplayDrawCopy) + base__extra_size + data__extra_size;
3544
3545 /* Check if message fits in reported side */
3546 if (nw_size > (uintptr_t) (message_end - start)) {
3547 return NULL;
3548 }
3549
3550 /* Validated extents and calculated size */
3551 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
3552 if (SPICE_UNLIKELY(data == NULL)) {
3553 goto error;
3554 }
3555 end = data + sizeof(SpiceMsgDisplayDrawCopy);
3556 in = start;
3557
3558 out = (SpiceMsgDisplayDrawCopy *)data;
3559
3560 /* base */ {
3561 out->base.surface_id = consume_uint32(&in);
3562 /* box */ {
3563 out->base.box.top = consume_int32(&in);
3564 out->base.box.left = consume_int32(&in);
3565 out->base.box.bottom = consume_int32(&in);
3566 out->base.box.right = consume_int32(&in);
3567 }
3568 /* clip */ {
3569 out->base.clip.type = consume_uint8(&in);
3570 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
3571 ptr_info[n_ptr].offset = in - start;
3572 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
3573 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
3574 n_ptr++;
3575 in += rects__saved_size;
3576 }
3577 }
3578 }
3579 /* data */ {
3580 ptr_info[n_ptr].offset = consume_uint32(&in);
3581 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3582 ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
3583 n_ptr++;
3584 /* src_area */ {
3585 out->data.src_area.top = consume_int32(&in);
3586 out->data.src_area.left = consume_int32(&in);
3587 out->data.src_area.bottom = consume_int32(&in);
3588 out->data.src_area.right = consume_int32(&in);
3589 }
3590 out->data.rop_descriptor = consume_uint16(&in);
3591 out->data.scale_mode = consume_uint8(&in);
3592 /* mask */ {
3593 out->data.mask.flags = consume_uint8(&in);
3594 /* pos */ {
3595 out->data.mask.pos.x = consume_int32(&in);
3596 out->data.mask.pos.y = consume_int32(&in);
3597 }
3598 ptr_info[n_ptr].offset = consume_uint32(&in);
3599 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3600 ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
3601 n_ptr++;
3602 }
3603 }
3604
3605 assert(in <= message_end);
3606
3607 for (i = 0; i < n_ptr; i++) {
3608 if (ptr_info[i].offset == 0) {
3609 *ptr_info[i].dest = NULL;
3610 } else {
3611 /* Align to 32 bit */
3612 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
3613 *ptr_info[i].dest = (void *)end;
3614 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
3615 if (SPICE_UNLIKELY(end == NULL)) {
3616 goto error;
3617 }
3618 }
3619 }
3620
3621 assert(end <= data + mem_size);
3622
3623 *size = end - data;
3624 *free_message = (message_destructor_t) free;
3625 return data;
3626
3627 error:
3628 free(data);
3629 return NULL;
3630 }
3631
parse_msg_display_draw_blackness(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)3632 static uint8_t * parse_msg_display_draw_blackness(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
3633 {
3634 SPICE_GNUC_UNUSED uint8_t *pos;
3635 uint8_t *start = message_start;
3636 uint8_t *data = NULL;
3637 uint64_t nw_size;
3638 uint64_t mem_size;
3639 uint8_t *in, *end;
3640 SPICE_GNUC_UNUSED intptr_t ptr_size;
3641 uint32_t n_ptr=0;
3642 PointerInfo ptr_info[2];
3643 uint64_t base__nw_size, base__extra_size;
3644 uint32_t rects__saved_size = 0;
3645 uint64_t data__extra_size;
3646 SpiceMsgDisplayDrawBlackness *out;
3647 uint32_t i;
3648
3649 { /* base */
3650 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
3651 uint64_t base_clip__nw_size, base_clip__extra_size;
3652 { /* clip */
3653 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
3654 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
3655 uint8_t type__value;
3656 { /* u */
3657 uint64_t base_clip_u__mem_size;
3658 pos = start3 + 0;
3659 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
3660 goto error;
3661 }
3662 type__value = read_uint8(pos);
3663 if (type__value == SPICE_CLIP_TYPE_RECTS) {
3664 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
3665 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
3666 uint64_t base_clip_u_rects__nelements;
3667 { /* rects */
3668 uint32_t num_rects__value;
3669 pos = start4 + 0;
3670 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3671 goto error;
3672 }
3673 num_rects__value = read_uint32(pos);
3674 base_clip_u_rects__nelements = num_rects__value;
3675
3676 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
3677 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
3678 }
3679
3680 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
3681 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
3682 rects__saved_size = base_clip_u__nw_size;
3683 base_clip_u__extra_size = base_clip_u__mem_size;
3684 } else {
3685 base_clip_u__nw_size = 0;
3686 base_clip_u__extra_size = 0;
3687 }
3688
3689 }
3690
3691 base_clip__nw_size = 1 + base_clip_u__nw_size;
3692 base_clip__extra_size = base_clip_u__extra_size;
3693 }
3694
3695 base__nw_size = 20 + base_clip__nw_size;
3696 base__extra_size = base_clip__extra_size;
3697 }
3698
3699 { /* data */
3700 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
3701 uint64_t data_mask__extra_size;
3702 { /* mask */
3703 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
3704 uint64_t data_mask_bitmap__extra_size;
3705 { /* bitmap */
3706 uint32_t bitmap__value;
3707 pos = (start3 + 9);
3708 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3709 goto error;
3710 }
3711 bitmap__value = read_uint32(pos);
3712 ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value);
3713 if (SPICE_UNLIKELY(ptr_size < 0)) {
3714 goto error;
3715 }
3716 data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
3717 }
3718
3719 data_mask__extra_size = data_mask_bitmap__extra_size;
3720 }
3721
3722 data__extra_size = data_mask__extra_size;
3723 }
3724
3725 nw_size = 13 + base__nw_size;
3726 mem_size = sizeof(SpiceMsgDisplayDrawBlackness) + base__extra_size + data__extra_size;
3727
3728 /* Check if message fits in reported side */
3729 if (nw_size > (uintptr_t) (message_end - start)) {
3730 return NULL;
3731 }
3732
3733 /* Validated extents and calculated size */
3734 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
3735 if (SPICE_UNLIKELY(data == NULL)) {
3736 goto error;
3737 }
3738 end = data + sizeof(SpiceMsgDisplayDrawBlackness);
3739 in = start;
3740
3741 out = (SpiceMsgDisplayDrawBlackness *)data;
3742
3743 /* base */ {
3744 out->base.surface_id = consume_uint32(&in);
3745 /* box */ {
3746 out->base.box.top = consume_int32(&in);
3747 out->base.box.left = consume_int32(&in);
3748 out->base.box.bottom = consume_int32(&in);
3749 out->base.box.right = consume_int32(&in);
3750 }
3751 /* clip */ {
3752 out->base.clip.type = consume_uint8(&in);
3753 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
3754 ptr_info[n_ptr].offset = in - start;
3755 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
3756 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
3757 n_ptr++;
3758 in += rects__saved_size;
3759 }
3760 }
3761 }
3762 /* data */ {
3763 /* mask */ {
3764 out->data.mask.flags = consume_uint8(&in);
3765 /* pos */ {
3766 out->data.mask.pos.x = consume_int32(&in);
3767 out->data.mask.pos.y = consume_int32(&in);
3768 }
3769 ptr_info[n_ptr].offset = consume_uint32(&in);
3770 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3771 ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
3772 n_ptr++;
3773 }
3774 }
3775
3776 assert(in <= message_end);
3777
3778 for (i = 0; i < n_ptr; i++) {
3779 if (ptr_info[i].offset == 0) {
3780 *ptr_info[i].dest = NULL;
3781 } else {
3782 /* Align to 32 bit */
3783 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
3784 *ptr_info[i].dest = (void *)end;
3785 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
3786 if (SPICE_UNLIKELY(end == NULL)) {
3787 goto error;
3788 }
3789 }
3790 }
3791
3792 assert(end <= data + mem_size);
3793
3794 *size = end - data;
3795 *free_message = (message_destructor_t) free;
3796 return data;
3797
3798 error:
3799 free(data);
3800 return NULL;
3801 }
3802
parse_msg_display_draw_whiteness(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)3803 static uint8_t * parse_msg_display_draw_whiteness(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
3804 {
3805 SPICE_GNUC_UNUSED uint8_t *pos;
3806 uint8_t *start = message_start;
3807 uint8_t *data = NULL;
3808 uint64_t nw_size;
3809 uint64_t mem_size;
3810 uint8_t *in, *end;
3811 SPICE_GNUC_UNUSED intptr_t ptr_size;
3812 uint32_t n_ptr=0;
3813 PointerInfo ptr_info[2];
3814 uint64_t base__nw_size, base__extra_size;
3815 uint32_t rects__saved_size = 0;
3816 uint64_t data__extra_size;
3817 SpiceMsgDisplayDrawWhiteness *out;
3818 uint32_t i;
3819
3820 { /* base */
3821 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
3822 uint64_t base_clip__nw_size, base_clip__extra_size;
3823 { /* clip */
3824 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
3825 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
3826 uint8_t type__value;
3827 { /* u */
3828 uint64_t base_clip_u__mem_size;
3829 pos = start3 + 0;
3830 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
3831 goto error;
3832 }
3833 type__value = read_uint8(pos);
3834 if (type__value == SPICE_CLIP_TYPE_RECTS) {
3835 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
3836 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
3837 uint64_t base_clip_u_rects__nelements;
3838 { /* rects */
3839 uint32_t num_rects__value;
3840 pos = start4 + 0;
3841 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3842 goto error;
3843 }
3844 num_rects__value = read_uint32(pos);
3845 base_clip_u_rects__nelements = num_rects__value;
3846
3847 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
3848 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
3849 }
3850
3851 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
3852 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
3853 rects__saved_size = base_clip_u__nw_size;
3854 base_clip_u__extra_size = base_clip_u__mem_size;
3855 } else {
3856 base_clip_u__nw_size = 0;
3857 base_clip_u__extra_size = 0;
3858 }
3859
3860 }
3861
3862 base_clip__nw_size = 1 + base_clip_u__nw_size;
3863 base_clip__extra_size = base_clip_u__extra_size;
3864 }
3865
3866 base__nw_size = 20 + base_clip__nw_size;
3867 base__extra_size = base_clip__extra_size;
3868 }
3869
3870 { /* data */
3871 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
3872 uint64_t data_mask__extra_size;
3873 { /* mask */
3874 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
3875 uint64_t data_mask_bitmap__extra_size;
3876 { /* bitmap */
3877 uint32_t bitmap__value;
3878 pos = (start3 + 9);
3879 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
3880 goto error;
3881 }
3882 bitmap__value = read_uint32(pos);
3883 ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value);
3884 if (SPICE_UNLIKELY(ptr_size < 0)) {
3885 goto error;
3886 }
3887 data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
3888 }
3889
3890 data_mask__extra_size = data_mask_bitmap__extra_size;
3891 }
3892
3893 data__extra_size = data_mask__extra_size;
3894 }
3895
3896 nw_size = 13 + base__nw_size;
3897 mem_size = sizeof(SpiceMsgDisplayDrawWhiteness) + base__extra_size + data__extra_size;
3898
3899 /* Check if message fits in reported side */
3900 if (nw_size > (uintptr_t) (message_end - start)) {
3901 return NULL;
3902 }
3903
3904 /* Validated extents and calculated size */
3905 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
3906 if (SPICE_UNLIKELY(data == NULL)) {
3907 goto error;
3908 }
3909 end = data + sizeof(SpiceMsgDisplayDrawWhiteness);
3910 in = start;
3911
3912 out = (SpiceMsgDisplayDrawWhiteness *)data;
3913
3914 /* base */ {
3915 out->base.surface_id = consume_uint32(&in);
3916 /* box */ {
3917 out->base.box.top = consume_int32(&in);
3918 out->base.box.left = consume_int32(&in);
3919 out->base.box.bottom = consume_int32(&in);
3920 out->base.box.right = consume_int32(&in);
3921 }
3922 /* clip */ {
3923 out->base.clip.type = consume_uint8(&in);
3924 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
3925 ptr_info[n_ptr].offset = in - start;
3926 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
3927 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
3928 n_ptr++;
3929 in += rects__saved_size;
3930 }
3931 }
3932 }
3933 /* data */ {
3934 /* mask */ {
3935 out->data.mask.flags = consume_uint8(&in);
3936 /* pos */ {
3937 out->data.mask.pos.x = consume_int32(&in);
3938 out->data.mask.pos.y = consume_int32(&in);
3939 }
3940 ptr_info[n_ptr].offset = consume_uint32(&in);
3941 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
3942 ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
3943 n_ptr++;
3944 }
3945 }
3946
3947 assert(in <= message_end);
3948
3949 for (i = 0; i < n_ptr; i++) {
3950 if (ptr_info[i].offset == 0) {
3951 *ptr_info[i].dest = NULL;
3952 } else {
3953 /* Align to 32 bit */
3954 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
3955 *ptr_info[i].dest = (void *)end;
3956 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
3957 if (SPICE_UNLIKELY(end == NULL)) {
3958 goto error;
3959 }
3960 }
3961 }
3962
3963 assert(end <= data + mem_size);
3964
3965 *size = end - data;
3966 *free_message = (message_destructor_t) free;
3967 return data;
3968
3969 error:
3970 free(data);
3971 return NULL;
3972 }
3973
parse_msg_display_draw_invers(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)3974 static uint8_t * parse_msg_display_draw_invers(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
3975 {
3976 SPICE_GNUC_UNUSED uint8_t *pos;
3977 uint8_t *start = message_start;
3978 uint8_t *data = NULL;
3979 uint64_t nw_size;
3980 uint64_t mem_size;
3981 uint8_t *in, *end;
3982 SPICE_GNUC_UNUSED intptr_t ptr_size;
3983 uint32_t n_ptr=0;
3984 PointerInfo ptr_info[2];
3985 uint64_t base__nw_size, base__extra_size;
3986 uint32_t rects__saved_size = 0;
3987 uint64_t data__extra_size;
3988 SpiceMsgDisplayDrawInvers *out;
3989 uint32_t i;
3990
3991 { /* base */
3992 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
3993 uint64_t base_clip__nw_size, base_clip__extra_size;
3994 { /* clip */
3995 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
3996 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
3997 uint8_t type__value;
3998 { /* u */
3999 uint64_t base_clip_u__mem_size;
4000 pos = start3 + 0;
4001 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4002 goto error;
4003 }
4004 type__value = read_uint8(pos);
4005 if (type__value == SPICE_CLIP_TYPE_RECTS) {
4006 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
4007 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
4008 uint64_t base_clip_u_rects__nelements;
4009 { /* rects */
4010 uint32_t num_rects__value;
4011 pos = start4 + 0;
4012 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4013 goto error;
4014 }
4015 num_rects__value = read_uint32(pos);
4016 base_clip_u_rects__nelements = num_rects__value;
4017
4018 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
4019 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
4020 }
4021
4022 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
4023 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
4024 rects__saved_size = base_clip_u__nw_size;
4025 base_clip_u__extra_size = base_clip_u__mem_size;
4026 } else {
4027 base_clip_u__nw_size = 0;
4028 base_clip_u__extra_size = 0;
4029 }
4030
4031 }
4032
4033 base_clip__nw_size = 1 + base_clip_u__nw_size;
4034 base_clip__extra_size = base_clip_u__extra_size;
4035 }
4036
4037 base__nw_size = 20 + base_clip__nw_size;
4038 base__extra_size = base_clip__extra_size;
4039 }
4040
4041 { /* data */
4042 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
4043 uint64_t data_mask__extra_size;
4044 { /* mask */
4045 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
4046 uint64_t data_mask_bitmap__extra_size;
4047 { /* bitmap */
4048 uint32_t bitmap__value;
4049 pos = (start3 + 9);
4050 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4051 goto error;
4052 }
4053 bitmap__value = read_uint32(pos);
4054 ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value);
4055 if (SPICE_UNLIKELY(ptr_size < 0)) {
4056 goto error;
4057 }
4058 data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
4059 }
4060
4061 data_mask__extra_size = data_mask_bitmap__extra_size;
4062 }
4063
4064 data__extra_size = data_mask__extra_size;
4065 }
4066
4067 nw_size = 13 + base__nw_size;
4068 mem_size = sizeof(SpiceMsgDisplayDrawInvers) + base__extra_size + data__extra_size;
4069
4070 /* Check if message fits in reported side */
4071 if (nw_size > (uintptr_t) (message_end - start)) {
4072 return NULL;
4073 }
4074
4075 /* Validated extents and calculated size */
4076 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
4077 if (SPICE_UNLIKELY(data == NULL)) {
4078 goto error;
4079 }
4080 end = data + sizeof(SpiceMsgDisplayDrawInvers);
4081 in = start;
4082
4083 out = (SpiceMsgDisplayDrawInvers *)data;
4084
4085 /* base */ {
4086 out->base.surface_id = consume_uint32(&in);
4087 /* box */ {
4088 out->base.box.top = consume_int32(&in);
4089 out->base.box.left = consume_int32(&in);
4090 out->base.box.bottom = consume_int32(&in);
4091 out->base.box.right = consume_int32(&in);
4092 }
4093 /* clip */ {
4094 out->base.clip.type = consume_uint8(&in);
4095 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
4096 ptr_info[n_ptr].offset = in - start;
4097 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
4098 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
4099 n_ptr++;
4100 in += rects__saved_size;
4101 }
4102 }
4103 }
4104 /* data */ {
4105 /* mask */ {
4106 out->data.mask.flags = consume_uint8(&in);
4107 /* pos */ {
4108 out->data.mask.pos.x = consume_int32(&in);
4109 out->data.mask.pos.y = consume_int32(&in);
4110 }
4111 ptr_info[n_ptr].offset = consume_uint32(&in);
4112 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
4113 ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
4114 n_ptr++;
4115 }
4116 }
4117
4118 assert(in <= message_end);
4119
4120 for (i = 0; i < n_ptr; i++) {
4121 if (ptr_info[i].offset == 0) {
4122 *ptr_info[i].dest = NULL;
4123 } else {
4124 /* Align to 32 bit */
4125 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
4126 *ptr_info[i].dest = (void *)end;
4127 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
4128 if (SPICE_UNLIKELY(end == NULL)) {
4129 goto error;
4130 }
4131 }
4132 }
4133
4134 assert(end <= data + mem_size);
4135
4136 *size = end - data;
4137 *free_message = (message_destructor_t) free;
4138 return data;
4139
4140 error:
4141 free(data);
4142 return NULL;
4143 }
4144
parse_msg_display_draw_rop3(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)4145 static uint8_t * parse_msg_display_draw_rop3(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
4146 {
4147 SPICE_GNUC_UNUSED uint8_t *pos;
4148 uint8_t *start = message_start;
4149 uint8_t *data = NULL;
4150 uint64_t nw_size;
4151 uint64_t mem_size;
4152 uint8_t *in, *end;
4153 SPICE_GNUC_UNUSED intptr_t ptr_size;
4154 uint32_t n_ptr=0;
4155 PointerInfo ptr_info[4];
4156 uint64_t base__nw_size, base__extra_size;
4157 uint32_t rects__saved_size = 0;
4158 uint64_t data__nw_size, data__extra_size;
4159 SpiceMsgDisplayDrawRop3 *out;
4160 uint32_t i;
4161
4162 { /* base */
4163 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
4164 uint64_t base_clip__nw_size, base_clip__extra_size;
4165 { /* clip */
4166 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
4167 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
4168 uint8_t type__value;
4169 { /* u */
4170 uint64_t base_clip_u__mem_size;
4171 pos = start3 + 0;
4172 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4173 goto error;
4174 }
4175 type__value = read_uint8(pos);
4176 if (type__value == SPICE_CLIP_TYPE_RECTS) {
4177 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
4178 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
4179 uint64_t base_clip_u_rects__nelements;
4180 { /* rects */
4181 uint32_t num_rects__value;
4182 pos = start4 + 0;
4183 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4184 goto error;
4185 }
4186 num_rects__value = read_uint32(pos);
4187 base_clip_u_rects__nelements = num_rects__value;
4188
4189 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
4190 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
4191 }
4192
4193 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
4194 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
4195 rects__saved_size = base_clip_u__nw_size;
4196 base_clip_u__extra_size = base_clip_u__mem_size;
4197 } else {
4198 base_clip_u__nw_size = 0;
4199 base_clip_u__extra_size = 0;
4200 }
4201
4202 }
4203
4204 base_clip__nw_size = 1 + base_clip_u__nw_size;
4205 base_clip__extra_size = base_clip_u__extra_size;
4206 }
4207
4208 base__nw_size = 20 + base_clip__nw_size;
4209 base__extra_size = base_clip__extra_size;
4210 }
4211
4212 { /* data */
4213 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
4214 uint64_t data_src_bitmap__extra_size;
4215 uint64_t data_brush__nw_size, data_brush__extra_size;
4216 uint64_t data_mask__extra_size;
4217 { /* src_bitmap */
4218 uint32_t src_bitmap__value;
4219 pos = (start2 + 0);
4220 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4221 goto error;
4222 }
4223 src_bitmap__value = read_uint32(pos);
4224 ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value);
4225 if (SPICE_UNLIKELY(ptr_size < 0)) {
4226 goto error;
4227 }
4228 data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
4229 }
4230
4231 { /* brush */
4232 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
4233 uint64_t data_brush_u__nw_size, data_brush_u__extra_size;
4234 uint8_t type__value;
4235 { /* u */
4236 pos = start3 + 0;
4237 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4238 goto error;
4239 }
4240 type__value = read_uint8(pos);
4241 if (type__value == SPICE_BRUSH_TYPE_SOLID) {
4242 data_brush_u__nw_size = 4;
4243 data_brush_u__extra_size = 0;
4244 } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
4245 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
4246 uint64_t data_brush_u_pat__extra_size;
4247 { /* pat */
4248 uint32_t pat__value;
4249 pos = (start4 + 0);
4250 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4251 goto error;
4252 }
4253 pat__value = read_uint32(pos);
4254 if (SPICE_UNLIKELY(pat__value == 0)) {
4255 goto error;
4256 }
4257 ptr_size = validate_SpiceImage(message_start, message_end, pat__value);
4258 if (SPICE_UNLIKELY(ptr_size < 0)) {
4259 goto error;
4260 }
4261 data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
4262 }
4263
4264 data_brush_u__nw_size = 12;
4265 data_brush_u__extra_size = data_brush_u_pat__extra_size;
4266 } else {
4267 data_brush_u__nw_size = 0;
4268 data_brush_u__extra_size = 0;
4269 }
4270
4271 }
4272
4273 data_brush__nw_size = 1 + data_brush_u__nw_size;
4274 data_brush__extra_size = data_brush_u__extra_size;
4275 }
4276
4277 { /* mask */
4278 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 22 + data_brush__nw_size);
4279 uint64_t data_mask_bitmap__extra_size;
4280 { /* bitmap */
4281 uint32_t bitmap__value;
4282 pos = (start3 + 9);
4283 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4284 goto error;
4285 }
4286 bitmap__value = read_uint32(pos);
4287 ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value);
4288 if (SPICE_UNLIKELY(ptr_size < 0)) {
4289 goto error;
4290 }
4291 data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
4292 }
4293
4294 data_mask__extra_size = data_mask_bitmap__extra_size;
4295 }
4296
4297 data__nw_size = 35 + data_brush__nw_size;
4298 data__extra_size = data_src_bitmap__extra_size + data_brush__extra_size + data_mask__extra_size;
4299 }
4300
4301 nw_size = 0 + base__nw_size + data__nw_size;
4302 mem_size = sizeof(SpiceMsgDisplayDrawRop3) + base__extra_size + data__extra_size;
4303
4304 /* Check if message fits in reported side */
4305 if (nw_size > (uintptr_t) (message_end - start)) {
4306 return NULL;
4307 }
4308
4309 /* Validated extents and calculated size */
4310 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
4311 if (SPICE_UNLIKELY(data == NULL)) {
4312 goto error;
4313 }
4314 end = data + sizeof(SpiceMsgDisplayDrawRop3);
4315 in = start;
4316
4317 out = (SpiceMsgDisplayDrawRop3 *)data;
4318
4319 /* base */ {
4320 out->base.surface_id = consume_uint32(&in);
4321 /* box */ {
4322 out->base.box.top = consume_int32(&in);
4323 out->base.box.left = consume_int32(&in);
4324 out->base.box.bottom = consume_int32(&in);
4325 out->base.box.right = consume_int32(&in);
4326 }
4327 /* clip */ {
4328 out->base.clip.type = consume_uint8(&in);
4329 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
4330 ptr_info[n_ptr].offset = in - start;
4331 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
4332 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
4333 n_ptr++;
4334 in += rects__saved_size;
4335 }
4336 }
4337 }
4338 /* data */ {
4339 ptr_info[n_ptr].offset = consume_uint32(&in);
4340 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
4341 ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
4342 n_ptr++;
4343 /* src_area */ {
4344 out->data.src_area.top = consume_int32(&in);
4345 out->data.src_area.left = consume_int32(&in);
4346 out->data.src_area.bottom = consume_int32(&in);
4347 out->data.src_area.right = consume_int32(&in);
4348 }
4349 /* brush */ {
4350 out->data.brush.type = consume_uint8(&in);
4351 if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
4352 out->data.brush.u.color = consume_uint32(&in);
4353 } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
4354 ptr_info[n_ptr].offset = consume_uint32(&in);
4355 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
4356 ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
4357 n_ptr++;
4358 /* pos */ {
4359 out->data.brush.u.pattern.pos.x = consume_int32(&in);
4360 out->data.brush.u.pattern.pos.y = consume_int32(&in);
4361 }
4362 }
4363 }
4364 out->data.rop3 = consume_uint8(&in);
4365 out->data.scale_mode = consume_uint8(&in);
4366 /* mask */ {
4367 out->data.mask.flags = consume_uint8(&in);
4368 /* pos */ {
4369 out->data.mask.pos.x = consume_int32(&in);
4370 out->data.mask.pos.y = consume_int32(&in);
4371 }
4372 ptr_info[n_ptr].offset = consume_uint32(&in);
4373 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
4374 ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
4375 n_ptr++;
4376 }
4377 }
4378
4379 assert(in <= message_end);
4380
4381 for (i = 0; i < n_ptr; i++) {
4382 if (ptr_info[i].offset == 0) {
4383 *ptr_info[i].dest = NULL;
4384 } else {
4385 /* Align to 32 bit */
4386 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
4387 *ptr_info[i].dest = (void *)end;
4388 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
4389 if (SPICE_UNLIKELY(end == NULL)) {
4390 goto error;
4391 }
4392 }
4393 }
4394
4395 assert(end <= data + mem_size);
4396
4397 *size = end - data;
4398 *free_message = (message_destructor_t) free;
4399 return data;
4400
4401 error:
4402 free(data);
4403 return NULL;
4404 }
4405
validate_SpicePath(uint8_t * message_start,uint8_t * message_end,uint64_t offset)4406 static intptr_t validate_SpicePath(uint8_t *message_start, uint8_t *message_end, uint64_t offset)
4407 {
4408 uint8_t *start = message_start + offset;
4409 SPICE_GNUC_UNUSED uint8_t *pos;
4410 uint64_t mem_size, nw_size;
4411 uint64_t segments__nw_size, segments__mem_size;
4412 uint64_t segments__nelements;
4413 uint32_t i;
4414
4415 if (offset == 0) {
4416 return 0;
4417 }
4418
4419 if (SPICE_UNLIKELY(start >= message_end)) {
4420 goto error;
4421 }
4422
4423 { /* segments */
4424 uint32_t num_segments__value;
4425 uint8_t *start2 = (start + 4);
4426 uint64_t segments__element__nw_size;
4427 uint64_t segments__element__mem_size;
4428 pos = start + 0;
4429 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4430 goto error;
4431 }
4432 num_segments__value = read_uint32(pos);
4433 segments__nelements = num_segments__value;
4434
4435 segments__nw_size = 0;
4436 segments__mem_size = 0;
4437 for (i = 0; i < segments__nelements; i++) {
4438 SPICE_GNUC_UNUSED uint8_t *start3 = start2;
4439 uint64_t segments__element_points__nw_size, segments__element_points__mem_size;
4440 uint64_t segments__element_points__nelements;
4441 { /* points */
4442 uint32_t count__value;
4443 pos = start3 + 1;
4444 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4445 goto error;
4446 }
4447 count__value = read_uint32(pos);
4448 segments__element_points__nelements = count__value;
4449
4450 segments__element_points__nw_size = (8) * segments__element_points__nelements;
4451 segments__element_points__mem_size = sizeof(SpicePointFix) * segments__element_points__nelements;
4452 }
4453
4454 segments__element__nw_size = 5 + segments__element_points__nw_size;
4455 segments__element__mem_size = sizeof(SpicePathSeg) + segments__element_points__mem_size;
4456 segments__nw_size += segments__element__nw_size;
4457 segments__mem_size += sizeof(void *) + SPICE_ALIGN(segments__element__mem_size, 4);
4458 start2 += segments__element__nw_size;
4459 }
4460 }
4461
4462 nw_size = 4 + segments__nw_size;
4463 mem_size = sizeof(SpicePath) + segments__mem_size;
4464
4465 /* Check if struct fits in reported side */
4466 if (SPICE_UNLIKELY(nw_size > (uintptr_t) (message_end - start))) {
4467 goto error;
4468 }
4469 return mem_size;
4470
4471 error:
4472 return -1;
4473 }
4474
parse_struct_SpicePath(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)4475 static uint8_t * parse_struct_SpicePath(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
4476 {
4477 uint8_t *in = message_start + this_ptr_info->offset;
4478 uint8_t *end;
4479 SpicePath *out;
4480 uint64_t segments__nelements;
4481 uint32_t i;
4482 void * *ptr_array;
4483 int ptr_array_index;
4484 uint32_t j;
4485
4486 end = struct_data + sizeof(SpicePath);
4487 out = (SpicePath *)struct_data;
4488
4489 out->num_segments = consume_uint32(&in);
4490 segments__nelements = out->num_segments;
4491 ptr_array_index = 0;
4492 ptr_array = (void **)out->segments;
4493 end += sizeof(void *) * segments__nelements;
4494 for (i = 0; i < segments__nelements; i++) {
4495 SpicePathSeg *out2;
4496 uint64_t points__nelements;
4497 ptr_array[ptr_array_index++] = end;
4498 out2 = (SpicePathSeg *)end;
4499 end += sizeof(SpicePathSeg);
4500
4501 out2->flags = consume_uint8(&in);
4502 out2->count = consume_uint32(&in);
4503 points__nelements = out2->count;
4504 for (j = 0; j < points__nelements; j++) {
4505 SpicePointFix *out3;
4506 out3 = (SpicePointFix *)end;
4507 end += sizeof(SpicePointFix);
4508
4509 out3->x = consume_int32(&in);
4510 out3->y = consume_int32(&in);
4511 }
4512 /* Align ptr_array element to 4 bytes */
4513 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
4514 }
4515 return end;
4516 }
4517
parse_array_int32(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)4518 static uint8_t * parse_array_int32(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
4519 {
4520 uint8_t *in = message_start + this_ptr_info->offset;
4521 uint8_t *end;
4522 uint32_t i;
4523
4524 end = struct_data;
4525 for (i = 0; i < this_ptr_info->nelements; i++) {
4526 *(SPICE_FIXED28_4 *)end = consume_int32(&in);
4527 end += sizeof(SPICE_FIXED28_4);
4528 }
4529 return end;
4530 }
4531
parse_msg_display_draw_stroke(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)4532 static uint8_t * parse_msg_display_draw_stroke(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
4533 {
4534 SPICE_GNUC_UNUSED uint8_t *pos;
4535 uint8_t *start = message_start;
4536 uint8_t *data = NULL;
4537 uint64_t nw_size;
4538 uint64_t mem_size;
4539 uint8_t *in, *end;
4540 SPICE_GNUC_UNUSED intptr_t ptr_size;
4541 uint32_t n_ptr=0;
4542 PointerInfo ptr_info[4];
4543 uint64_t base__nw_size, base__extra_size;
4544 uint32_t rects__saved_size = 0;
4545 uint64_t data__nw_size, data__extra_size;
4546 SpiceMsgDisplayDrawStroke *out;
4547 uint32_t i;
4548
4549 { /* base */
4550 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
4551 uint64_t base_clip__nw_size, base_clip__extra_size;
4552 { /* clip */
4553 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
4554 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
4555 uint8_t type__value;
4556 { /* u */
4557 uint64_t base_clip_u__mem_size;
4558 pos = start3 + 0;
4559 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4560 goto error;
4561 }
4562 type__value = read_uint8(pos);
4563 if (type__value == SPICE_CLIP_TYPE_RECTS) {
4564 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
4565 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
4566 uint64_t base_clip_u_rects__nelements;
4567 { /* rects */
4568 uint32_t num_rects__value;
4569 pos = start4 + 0;
4570 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4571 goto error;
4572 }
4573 num_rects__value = read_uint32(pos);
4574 base_clip_u_rects__nelements = num_rects__value;
4575
4576 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
4577 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
4578 }
4579
4580 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
4581 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
4582 rects__saved_size = base_clip_u__nw_size;
4583 base_clip_u__extra_size = base_clip_u__mem_size;
4584 } else {
4585 base_clip_u__nw_size = 0;
4586 base_clip_u__extra_size = 0;
4587 }
4588
4589 }
4590
4591 base_clip__nw_size = 1 + base_clip_u__nw_size;
4592 base_clip__extra_size = base_clip_u__extra_size;
4593 }
4594
4595 base__nw_size = 20 + base_clip__nw_size;
4596 base__extra_size = base_clip__extra_size;
4597 }
4598
4599 { /* data */
4600 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
4601 uint64_t data_path__extra_size;
4602 uint64_t data_attr__nw_size, data_attr__extra_size;
4603 uint64_t data_brush__nw_size, data_brush__extra_size;
4604 { /* path */
4605 uint32_t path__value;
4606 pos = (start2 + 0);
4607 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4608 goto error;
4609 }
4610 path__value = read_uint32(pos);
4611 if (SPICE_UNLIKELY(path__value == 0)) {
4612 goto error;
4613 }
4614 ptr_size = validate_SpicePath(message_start, message_end, path__value);
4615 if (SPICE_UNLIKELY(ptr_size < 0)) {
4616 goto error;
4617 }
4618 data_path__extra_size = ptr_size + /* for alignment */ 3;
4619 }
4620
4621 { /* attr */
4622 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 4);
4623 uint64_t data_attr_u1__nw_size;
4624 uint8_t flags__value;
4625 uint64_t data_attr_u2__nw_size, data_attr_u2__extra_size;
4626 { /* u1 */
4627 pos = start3 + 0;
4628 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4629 goto error;
4630 }
4631 flags__value = read_uint8(pos);
4632 if ((flags__value & SPICE_LINE_FLAGS_STYLED)) {
4633 data_attr_u1__nw_size = 1;
4634 } else {
4635 data_attr_u1__nw_size = 0;
4636 }
4637
4638 }
4639
4640 { /* u2 */
4641 uint64_t data_attr_u2__array__nelements;
4642 pos = start3 + 0;
4643 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4644 goto error;
4645 }
4646 flags__value = read_uint8(pos);
4647 if ((flags__value & SPICE_LINE_FLAGS_STYLED)) {
4648 uint32_t data_attr_u2_style__value;
4649 uint64_t data_attr_u2__array__nw_size;
4650 uint64_t data_attr_u2__array__mem_size;
4651 uint8_t style_nseg__value;
4652 data_attr_u2__nw_size = 4;
4653 pos = (start3 + 1 + data_attr_u1__nw_size);
4654 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4655 goto error;
4656 }
4657 data_attr_u2_style__value = read_uint32(pos);
4658 if (SPICE_UNLIKELY(data_attr_u2_style__value >= (uintptr_t) (message_end - message_start))) {
4659 goto error;
4660 }
4661 pos = start3 + 1;
4662 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4663 goto error;
4664 }
4665 style_nseg__value = read_uint8(pos);
4666 data_attr_u2__array__nelements = style_nseg__value;
4667
4668 data_attr_u2__array__nw_size = (4) * data_attr_u2__array__nelements;
4669 data_attr_u2__array__mem_size = sizeof(SPICE_FIXED28_4) * data_attr_u2__array__nelements;
4670 if (SPICE_UNLIKELY(data_attr_u2_style__value + data_attr_u2__array__nw_size > (uintptr_t) (message_end - message_start))) {
4671 goto error;
4672 }
4673 data_attr_u2__extra_size = data_attr_u2__array__mem_size + /* for alignment */ 3;
4674 } else {
4675 data_attr_u2__nw_size = 0;
4676 data_attr_u2__extra_size = 0;
4677 }
4678
4679 }
4680
4681 data_attr__nw_size = 1 + data_attr_u1__nw_size + data_attr_u2__nw_size;
4682 data_attr__extra_size = data_attr_u2__extra_size;
4683 }
4684
4685 { /* brush */
4686 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 4 + data_attr__nw_size);
4687 uint64_t data_brush_u__nw_size, data_brush_u__extra_size;
4688 uint8_t type__value;
4689 { /* u */
4690 pos = start3 + 0;
4691 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4692 goto error;
4693 }
4694 type__value = read_uint8(pos);
4695 if (type__value == SPICE_BRUSH_TYPE_SOLID) {
4696 data_brush_u__nw_size = 4;
4697 data_brush_u__extra_size = 0;
4698 } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
4699 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
4700 uint64_t data_brush_u_pat__extra_size;
4701 { /* pat */
4702 uint32_t pat__value;
4703 pos = (start4 + 0);
4704 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
4705 goto error;
4706 }
4707 pat__value = read_uint32(pos);
4708 if (SPICE_UNLIKELY(pat__value == 0)) {
4709 goto error;
4710 }
4711 ptr_size = validate_SpiceImage(message_start, message_end, pat__value);
4712 if (SPICE_UNLIKELY(ptr_size < 0)) {
4713 goto error;
4714 }
4715 data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
4716 }
4717
4718 data_brush_u__nw_size = 12;
4719 data_brush_u__extra_size = data_brush_u_pat__extra_size;
4720 } else {
4721 data_brush_u__nw_size = 0;
4722 data_brush_u__extra_size = 0;
4723 }
4724
4725 }
4726
4727 data_brush__nw_size = 1 + data_brush_u__nw_size;
4728 data_brush__extra_size = data_brush_u__extra_size;
4729 }
4730
4731 data__nw_size = 8 + data_attr__nw_size + data_brush__nw_size;
4732 data__extra_size = data_path__extra_size + data_attr__extra_size + data_brush__extra_size;
4733 }
4734
4735 nw_size = 0 + base__nw_size + data__nw_size;
4736 mem_size = sizeof(SpiceMsgDisplayDrawStroke) + base__extra_size + data__extra_size;
4737
4738 /* Check if message fits in reported side */
4739 if (nw_size > (uintptr_t) (message_end - start)) {
4740 return NULL;
4741 }
4742
4743 /* Validated extents and calculated size */
4744 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
4745 if (SPICE_UNLIKELY(data == NULL)) {
4746 goto error;
4747 }
4748 end = data + sizeof(SpiceMsgDisplayDrawStroke);
4749 in = start;
4750
4751 out = (SpiceMsgDisplayDrawStroke *)data;
4752
4753 /* base */ {
4754 out->base.surface_id = consume_uint32(&in);
4755 /* box */ {
4756 out->base.box.top = consume_int32(&in);
4757 out->base.box.left = consume_int32(&in);
4758 out->base.box.bottom = consume_int32(&in);
4759 out->base.box.right = consume_int32(&in);
4760 }
4761 /* clip */ {
4762 out->base.clip.type = consume_uint8(&in);
4763 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
4764 ptr_info[n_ptr].offset = in - start;
4765 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
4766 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
4767 n_ptr++;
4768 in += rects__saved_size;
4769 }
4770 }
4771 }
4772 /* data */ {
4773 ptr_info[n_ptr].offset = consume_uint32(&in);
4774 ptr_info[n_ptr].parse = parse_struct_SpicePath;
4775 ptr_info[n_ptr].dest = (void **)&out->data.path;
4776 n_ptr++;
4777 /* attr */ {
4778 out->data.attr.flags = consume_uint8(&in);
4779 if ((out->data.attr.flags & SPICE_LINE_FLAGS_STYLED)) {
4780 out->data.attr.style_nseg = consume_uint8(&in);
4781 }
4782 if ((out->data.attr.flags & SPICE_LINE_FLAGS_STYLED)) {
4783 uint64_t style__array__nelements;
4784 ptr_info[n_ptr].offset = consume_uint32(&in);
4785 ptr_info[n_ptr].parse = parse_array_int32;
4786 ptr_info[n_ptr].dest = (void **)&out->data.attr.style;
4787 style__array__nelements = out->data.attr.style_nseg;
4788 ptr_info[n_ptr].nelements = style__array__nelements;
4789 n_ptr++;
4790 }
4791 }
4792 /* brush */ {
4793 out->data.brush.type = consume_uint8(&in);
4794 if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
4795 out->data.brush.u.color = consume_uint32(&in);
4796 } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
4797 ptr_info[n_ptr].offset = consume_uint32(&in);
4798 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
4799 ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
4800 n_ptr++;
4801 /* pos */ {
4802 out->data.brush.u.pattern.pos.x = consume_int32(&in);
4803 out->data.brush.u.pattern.pos.y = consume_int32(&in);
4804 }
4805 }
4806 }
4807 out->data.fore_mode = consume_uint16(&in);
4808 out->data.back_mode = consume_uint16(&in);
4809 }
4810
4811 assert(in <= message_end);
4812
4813 for (i = 0; i < n_ptr; i++) {
4814 if (ptr_info[i].offset == 0) {
4815 *ptr_info[i].dest = NULL;
4816 } else {
4817 /* Align to 32 bit */
4818 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
4819 *ptr_info[i].dest = (void *)end;
4820 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
4821 if (SPICE_UNLIKELY(end == NULL)) {
4822 goto error;
4823 }
4824 }
4825 }
4826
4827 assert(end <= data + mem_size);
4828
4829 *size = end - data;
4830 *free_message = (message_destructor_t) free;
4831 return data;
4832
4833 error:
4834 free(data);
4835 return NULL;
4836 }
4837
validate_SpiceString(uint8_t * message_start,uint8_t * message_end,uint64_t offset)4838 static intptr_t validate_SpiceString(uint8_t *message_start, uint8_t *message_end, uint64_t offset)
4839 {
4840 uint8_t *start = message_start + offset;
4841 SPICE_GNUC_UNUSED uint8_t *pos;
4842 uint64_t mem_size, nw_size;
4843 uint64_t u__nw_size, u__extra_size;
4844 uint8_t flags__value;
4845 uint32_t i;
4846
4847 if (offset == 0) {
4848 return 0;
4849 }
4850
4851 if (SPICE_UNLIKELY(start >= message_end)) {
4852 goto error;
4853 }
4854
4855 { /* u */
4856 uint64_t u__mem_size;
4857 uint64_t u__nelements;
4858 pos = start + 2;
4859 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
4860 goto error;
4861 }
4862 flags__value = read_uint8(pos);
4863 if ((flags__value & SPICE_STRING_FLAGS_RASTER_A1)) {
4864 uint16_t length__value;
4865 uint8_t *start2 = (start + 3);
4866 uint64_t u__element__nw_size;
4867 uint64_t u__element__mem_size;
4868 pos = start + 0;
4869 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4870 goto error;
4871 }
4872 length__value = read_uint16(pos);
4873 u__nelements = length__value;
4874
4875 u__nw_size = 0;
4876 u__mem_size = 0;
4877 for (i = 0; i < u__nelements; i++) {
4878 SPICE_GNUC_UNUSED uint8_t *start3 = start2;
4879 uint64_t u__element_data__nw_size, u__element_data__mem_size;
4880 uint64_t u__element_data__nelements;
4881 { /* data */
4882 uint16_t width__value;
4883 uint16_t height__value;
4884 pos = start3 + 16;
4885 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4886 goto error;
4887 }
4888 width__value = read_uint16(pos);
4889 pos = start3 + 18;
4890 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4891 goto error;
4892 }
4893 height__value = read_uint16(pos);
4894 u__element_data__nelements = (((uint64_t) width__value + 7U) / 8U ) * height__value;
4895
4896 u__element_data__nw_size = u__element_data__nelements;
4897 u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
4898 }
4899
4900 u__element__nw_size = 20 + u__element_data__nw_size;
4901 u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
4902 u__nw_size += u__element__nw_size;
4903 u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
4904 start2 += u__element__nw_size;
4905 }
4906 u__extra_size = u__mem_size;
4907 } else if ((flags__value & SPICE_STRING_FLAGS_RASTER_A4)) {
4908 uint16_t length__value;
4909 uint8_t *start2 = (start + 3);
4910 uint64_t u__element__nw_size;
4911 uint64_t u__element__mem_size;
4912 pos = start + 0;
4913 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4914 goto error;
4915 }
4916 length__value = read_uint16(pos);
4917 u__nelements = length__value;
4918
4919 u__nw_size = 0;
4920 u__mem_size = 0;
4921 for (i = 0; i < u__nelements; i++) {
4922 SPICE_GNUC_UNUSED uint8_t *start3 = start2;
4923 uint64_t u__element_data__nw_size, u__element_data__mem_size;
4924 uint64_t u__element_data__nelements;
4925 { /* data */
4926 uint16_t width__value;
4927 uint16_t height__value;
4928 pos = start3 + 16;
4929 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4930 goto error;
4931 }
4932 width__value = read_uint16(pos);
4933 pos = start3 + 18;
4934 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4935 goto error;
4936 }
4937 height__value = read_uint16(pos);
4938 u__element_data__nelements = ((4U * (uint64_t) width__value + 7U) / 8U ) * height__value;
4939
4940 u__element_data__nw_size = u__element_data__nelements;
4941 u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
4942 }
4943
4944 u__element__nw_size = 20 + u__element_data__nw_size;
4945 u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
4946 u__nw_size += u__element__nw_size;
4947 u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
4948 start2 += u__element__nw_size;
4949 }
4950 u__extra_size = u__mem_size;
4951 } else if ((flags__value & SPICE_STRING_FLAGS_RASTER_A8)) {
4952 uint16_t length__value;
4953 uint8_t *start2 = (start + 3);
4954 uint64_t u__element__nw_size;
4955 uint64_t u__element__mem_size;
4956 pos = start + 0;
4957 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4958 goto error;
4959 }
4960 length__value = read_uint16(pos);
4961 u__nelements = length__value;
4962
4963 u__nw_size = 0;
4964 u__mem_size = 0;
4965 for (i = 0; i < u__nelements; i++) {
4966 SPICE_GNUC_UNUSED uint8_t *start3 = start2;
4967 uint64_t u__element_data__nw_size, u__element_data__mem_size;
4968 uint64_t u__element_data__nelements;
4969 { /* data */
4970 uint16_t width__value;
4971 uint16_t height__value;
4972 pos = start3 + 16;
4973 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4974 goto error;
4975 }
4976 width__value = read_uint16(pos);
4977 pos = start3 + 18;
4978 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
4979 goto error;
4980 }
4981 height__value = read_uint16(pos);
4982 u__element_data__nelements = (uint64_t) width__value * height__value;
4983
4984 u__element_data__nw_size = u__element_data__nelements;
4985 u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
4986 }
4987
4988 u__element__nw_size = 20 + u__element_data__nw_size;
4989 u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
4990 u__nw_size += u__element__nw_size;
4991 u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
4992 start2 += u__element__nw_size;
4993 }
4994 u__extra_size = u__mem_size;
4995 } else {
4996 u__nw_size = 0;
4997 u__extra_size = 0;
4998 }
4999
5000 }
5001
5002 nw_size = 3 + u__nw_size;
5003 mem_size = sizeof(SpiceString) + u__extra_size;
5004
5005 /* Check if struct fits in reported side */
5006 if (SPICE_UNLIKELY(nw_size > (uintptr_t) (message_end - start))) {
5007 goto error;
5008 }
5009 return mem_size;
5010
5011 error:
5012 return -1;
5013 }
5014
parse_struct_SpiceString(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)5015 static uint8_t * parse_struct_SpiceString(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
5016 {
5017 uint8_t *in = message_start + this_ptr_info->offset;
5018 uint8_t *end;
5019 SpiceString *out;
5020 uint32_t i;
5021
5022 end = struct_data + sizeof(SpiceString);
5023 out = (SpiceString *)struct_data;
5024
5025 out->length = consume_uint16(&in);
5026 out->flags = consume_uint8(&in);
5027 if ((out->flags & SPICE_STRING_FLAGS_RASTER_A1)) {
5028 uint64_t glyphs__nelements;
5029 void * *ptr_array;
5030 int ptr_array_index;
5031 glyphs__nelements = out->length;
5032 ptr_array_index = 0;
5033 ptr_array = (void **)out->glyphs;
5034 end += sizeof(void *) * glyphs__nelements;
5035 for (i = 0; i < glyphs__nelements; i++) {
5036 SpiceRasterGlyph *out2;
5037 uint64_t data__nelements;
5038 ptr_array[ptr_array_index++] = end;
5039 out2 = (SpiceRasterGlyph *)end;
5040 end += sizeof(SpiceRasterGlyph);
5041
5042 /* render_pos */ {
5043 out2->render_pos.x = consume_int32(&in);
5044 out2->render_pos.y = consume_int32(&in);
5045 }
5046 /* glyph_origin */ {
5047 out2->glyph_origin.x = consume_int32(&in);
5048 out2->glyph_origin.y = consume_int32(&in);
5049 }
5050 out2->width = consume_uint16(&in);
5051 out2->height = consume_uint16(&in);
5052 data__nelements = (((uint64_t) out2->width + 7U) / 8U ) * out2->height;
5053 memcpy(out2->data, in, data__nelements);
5054 in += data__nelements;
5055 end += data__nelements;
5056 /* Align ptr_array element to 4 bytes */
5057 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
5058 }
5059 } else if ((out->flags & SPICE_STRING_FLAGS_RASTER_A4)) {
5060 uint64_t glyphs__nelements;
5061 void * *ptr_array;
5062 int ptr_array_index;
5063 glyphs__nelements = out->length;
5064 ptr_array_index = 0;
5065 ptr_array = (void **)out->glyphs;
5066 end += sizeof(void *) * glyphs__nelements;
5067 for (i = 0; i < glyphs__nelements; i++) {
5068 SpiceRasterGlyph *out2;
5069 uint64_t data__nelements;
5070 ptr_array[ptr_array_index++] = end;
5071 out2 = (SpiceRasterGlyph *)end;
5072 end += sizeof(SpiceRasterGlyph);
5073
5074 /* render_pos */ {
5075 out2->render_pos.x = consume_int32(&in);
5076 out2->render_pos.y = consume_int32(&in);
5077 }
5078 /* glyph_origin */ {
5079 out2->glyph_origin.x = consume_int32(&in);
5080 out2->glyph_origin.y = consume_int32(&in);
5081 }
5082 out2->width = consume_uint16(&in);
5083 out2->height = consume_uint16(&in);
5084 data__nelements = ((4U * (uint64_t) out2->width + 7U) / 8U ) * out2->height;
5085 memcpy(out2->data, in, data__nelements);
5086 in += data__nelements;
5087 end += data__nelements;
5088 /* Align ptr_array element to 4 bytes */
5089 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
5090 }
5091 } else if ((out->flags & SPICE_STRING_FLAGS_RASTER_A8)) {
5092 uint64_t glyphs__nelements;
5093 void * *ptr_array;
5094 int ptr_array_index;
5095 glyphs__nelements = out->length;
5096 ptr_array_index = 0;
5097 ptr_array = (void **)out->glyphs;
5098 end += sizeof(void *) * glyphs__nelements;
5099 for (i = 0; i < glyphs__nelements; i++) {
5100 SpiceRasterGlyph *out2;
5101 uint64_t data__nelements;
5102 ptr_array[ptr_array_index++] = end;
5103 out2 = (SpiceRasterGlyph *)end;
5104 end += sizeof(SpiceRasterGlyph);
5105
5106 /* render_pos */ {
5107 out2->render_pos.x = consume_int32(&in);
5108 out2->render_pos.y = consume_int32(&in);
5109 }
5110 /* glyph_origin */ {
5111 out2->glyph_origin.x = consume_int32(&in);
5112 out2->glyph_origin.y = consume_int32(&in);
5113 }
5114 out2->width = consume_uint16(&in);
5115 out2->height = consume_uint16(&in);
5116 data__nelements = ((uint64_t) out2->width * out2->height);
5117 memcpy(out2->data, in, data__nelements);
5118 in += data__nelements;
5119 end += data__nelements;
5120 /* Align ptr_array element to 4 bytes */
5121 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
5122 }
5123 }
5124 return end;
5125 }
5126
parse_msg_display_draw_text(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)5127 static uint8_t * parse_msg_display_draw_text(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
5128 {
5129 SPICE_GNUC_UNUSED uint8_t *pos;
5130 uint8_t *start = message_start;
5131 uint8_t *data = NULL;
5132 uint64_t nw_size;
5133 uint64_t mem_size;
5134 uint8_t *in, *end;
5135 SPICE_GNUC_UNUSED intptr_t ptr_size;
5136 uint32_t n_ptr=0;
5137 PointerInfo ptr_info[4];
5138 uint64_t base__nw_size, base__extra_size;
5139 uint32_t rects__saved_size = 0;
5140 uint64_t data__nw_size, data__extra_size;
5141 SpiceMsgDisplayDrawText *out;
5142 uint32_t i;
5143
5144 { /* base */
5145 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
5146 uint64_t base_clip__nw_size, base_clip__extra_size;
5147 { /* clip */
5148 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
5149 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
5150 uint8_t type__value;
5151 { /* u */
5152 uint64_t base_clip_u__mem_size;
5153 pos = start3 + 0;
5154 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
5155 goto error;
5156 }
5157 type__value = read_uint8(pos);
5158 if (type__value == SPICE_CLIP_TYPE_RECTS) {
5159 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
5160 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
5161 uint64_t base_clip_u_rects__nelements;
5162 { /* rects */
5163 uint32_t num_rects__value;
5164 pos = start4 + 0;
5165 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5166 goto error;
5167 }
5168 num_rects__value = read_uint32(pos);
5169 base_clip_u_rects__nelements = num_rects__value;
5170
5171 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
5172 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
5173 }
5174
5175 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
5176 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
5177 rects__saved_size = base_clip_u__nw_size;
5178 base_clip_u__extra_size = base_clip_u__mem_size;
5179 } else {
5180 base_clip_u__nw_size = 0;
5181 base_clip_u__extra_size = 0;
5182 }
5183
5184 }
5185
5186 base_clip__nw_size = 1 + base_clip_u__nw_size;
5187 base_clip__extra_size = base_clip_u__extra_size;
5188 }
5189
5190 base__nw_size = 20 + base_clip__nw_size;
5191 base__extra_size = base_clip__extra_size;
5192 }
5193
5194 { /* data */
5195 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
5196 uint64_t data_str__extra_size;
5197 uint64_t data_fore_brush__nw_size, data_fore_brush__extra_size;
5198 uint64_t data_back_brush__nw_size, data_back_brush__extra_size;
5199 { /* str */
5200 uint32_t str__value;
5201 pos = (start2 + 0);
5202 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5203 goto error;
5204 }
5205 str__value = read_uint32(pos);
5206 if (SPICE_UNLIKELY(str__value == 0)) {
5207 goto error;
5208 }
5209 ptr_size = validate_SpiceString(message_start, message_end, str__value);
5210 if (SPICE_UNLIKELY(ptr_size < 0)) {
5211 goto error;
5212 }
5213 data_str__extra_size = ptr_size + /* for alignment */ 3;
5214 }
5215
5216 { /* fore_brush */
5217 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
5218 uint64_t data_fore_brush_u__nw_size, data_fore_brush_u__extra_size;
5219 uint8_t type__value;
5220 { /* u */
5221 pos = start3 + 0;
5222 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
5223 goto error;
5224 }
5225 type__value = read_uint8(pos);
5226 if (type__value == SPICE_BRUSH_TYPE_SOLID) {
5227 data_fore_brush_u__nw_size = 4;
5228 data_fore_brush_u__extra_size = 0;
5229 } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
5230 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
5231 uint64_t data_fore_brush_u_pat__extra_size;
5232 { /* pat */
5233 uint32_t pat__value;
5234 pos = (start4 + 0);
5235 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5236 goto error;
5237 }
5238 pat__value = read_uint32(pos);
5239 if (SPICE_UNLIKELY(pat__value == 0)) {
5240 goto error;
5241 }
5242 ptr_size = validate_SpiceImage(message_start, message_end, pat__value);
5243 if (SPICE_UNLIKELY(ptr_size < 0)) {
5244 goto error;
5245 }
5246 data_fore_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
5247 }
5248
5249 data_fore_brush_u__nw_size = 12;
5250 data_fore_brush_u__extra_size = data_fore_brush_u_pat__extra_size;
5251 } else {
5252 data_fore_brush_u__nw_size = 0;
5253 data_fore_brush_u__extra_size = 0;
5254 }
5255
5256 }
5257
5258 data_fore_brush__nw_size = 1 + data_fore_brush_u__nw_size;
5259 data_fore_brush__extra_size = data_fore_brush_u__extra_size;
5260 }
5261
5262 { /* back_brush */
5263 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20 + data_fore_brush__nw_size);
5264 uint64_t data_back_brush_u__nw_size, data_back_brush_u__extra_size;
5265 uint8_t type__value;
5266 { /* u */
5267 pos = start3 + 0;
5268 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
5269 goto error;
5270 }
5271 type__value = read_uint8(pos);
5272 if (type__value == SPICE_BRUSH_TYPE_SOLID) {
5273 data_back_brush_u__nw_size = 4;
5274 data_back_brush_u__extra_size = 0;
5275 } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
5276 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
5277 uint64_t data_back_brush_u_pat__extra_size;
5278 { /* pat */
5279 uint32_t pat__value;
5280 pos = (start4 + 0);
5281 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5282 goto error;
5283 }
5284 pat__value = read_uint32(pos);
5285 if (SPICE_UNLIKELY(pat__value == 0)) {
5286 goto error;
5287 }
5288 ptr_size = validate_SpiceImage(message_start, message_end, pat__value);
5289 if (SPICE_UNLIKELY(ptr_size < 0)) {
5290 goto error;
5291 }
5292 data_back_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
5293 }
5294
5295 data_back_brush_u__nw_size = 12;
5296 data_back_brush_u__extra_size = data_back_brush_u_pat__extra_size;
5297 } else {
5298 data_back_brush_u__nw_size = 0;
5299 data_back_brush_u__extra_size = 0;
5300 }
5301
5302 }
5303
5304 data_back_brush__nw_size = 1 + data_back_brush_u__nw_size;
5305 data_back_brush__extra_size = data_back_brush_u__extra_size;
5306 }
5307
5308 data__nw_size = 24 + data_fore_brush__nw_size + data_back_brush__nw_size;
5309 data__extra_size = data_str__extra_size + data_fore_brush__extra_size + data_back_brush__extra_size;
5310 }
5311
5312 nw_size = 0 + base__nw_size + data__nw_size;
5313 mem_size = sizeof(SpiceMsgDisplayDrawText) + base__extra_size + data__extra_size;
5314
5315 /* Check if message fits in reported side */
5316 if (nw_size > (uintptr_t) (message_end - start)) {
5317 return NULL;
5318 }
5319
5320 /* Validated extents and calculated size */
5321 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
5322 if (SPICE_UNLIKELY(data == NULL)) {
5323 goto error;
5324 }
5325 end = data + sizeof(SpiceMsgDisplayDrawText);
5326 in = start;
5327
5328 out = (SpiceMsgDisplayDrawText *)data;
5329
5330 /* base */ {
5331 out->base.surface_id = consume_uint32(&in);
5332 /* box */ {
5333 out->base.box.top = consume_int32(&in);
5334 out->base.box.left = consume_int32(&in);
5335 out->base.box.bottom = consume_int32(&in);
5336 out->base.box.right = consume_int32(&in);
5337 }
5338 /* clip */ {
5339 out->base.clip.type = consume_uint8(&in);
5340 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
5341 ptr_info[n_ptr].offset = in - start;
5342 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
5343 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
5344 n_ptr++;
5345 in += rects__saved_size;
5346 }
5347 }
5348 }
5349 /* data */ {
5350 ptr_info[n_ptr].offset = consume_uint32(&in);
5351 ptr_info[n_ptr].parse = parse_struct_SpiceString;
5352 ptr_info[n_ptr].dest = (void **)&out->data.str;
5353 n_ptr++;
5354 /* back_area */ {
5355 out->data.back_area.top = consume_int32(&in);
5356 out->data.back_area.left = consume_int32(&in);
5357 out->data.back_area.bottom = consume_int32(&in);
5358 out->data.back_area.right = consume_int32(&in);
5359 }
5360 /* fore_brush */ {
5361 out->data.fore_brush.type = consume_uint8(&in);
5362 if (out->data.fore_brush.type == SPICE_BRUSH_TYPE_SOLID) {
5363 out->data.fore_brush.u.color = consume_uint32(&in);
5364 } else if (out->data.fore_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
5365 ptr_info[n_ptr].offset = consume_uint32(&in);
5366 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
5367 ptr_info[n_ptr].dest = (void **)&out->data.fore_brush.u.pattern.pat;
5368 n_ptr++;
5369 /* pos */ {
5370 out->data.fore_brush.u.pattern.pos.x = consume_int32(&in);
5371 out->data.fore_brush.u.pattern.pos.y = consume_int32(&in);
5372 }
5373 }
5374 }
5375 /* back_brush */ {
5376 out->data.back_brush.type = consume_uint8(&in);
5377 if (out->data.back_brush.type == SPICE_BRUSH_TYPE_SOLID) {
5378 out->data.back_brush.u.color = consume_uint32(&in);
5379 } else if (out->data.back_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
5380 ptr_info[n_ptr].offset = consume_uint32(&in);
5381 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
5382 ptr_info[n_ptr].dest = (void **)&out->data.back_brush.u.pattern.pat;
5383 n_ptr++;
5384 /* pos */ {
5385 out->data.back_brush.u.pattern.pos.x = consume_int32(&in);
5386 out->data.back_brush.u.pattern.pos.y = consume_int32(&in);
5387 }
5388 }
5389 }
5390 out->data.fore_mode = consume_uint16(&in);
5391 out->data.back_mode = consume_uint16(&in);
5392 }
5393
5394 assert(in <= message_end);
5395
5396 for (i = 0; i < n_ptr; i++) {
5397 if (ptr_info[i].offset == 0) {
5398 *ptr_info[i].dest = NULL;
5399 } else {
5400 /* Align to 32 bit */
5401 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
5402 *ptr_info[i].dest = (void *)end;
5403 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
5404 if (SPICE_UNLIKELY(end == NULL)) {
5405 goto error;
5406 }
5407 }
5408 }
5409
5410 assert(end <= data + mem_size);
5411
5412 *size = end - data;
5413 *free_message = (message_destructor_t) free;
5414 return data;
5415
5416 error:
5417 free(data);
5418 return NULL;
5419 }
5420
parse_msg_display_draw_transparent(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)5421 static uint8_t * parse_msg_display_draw_transparent(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
5422 {
5423 SPICE_GNUC_UNUSED uint8_t *pos;
5424 uint8_t *start = message_start;
5425 uint8_t *data = NULL;
5426 uint64_t nw_size;
5427 uint64_t mem_size;
5428 uint8_t *in, *end;
5429 SPICE_GNUC_UNUSED intptr_t ptr_size;
5430 uint32_t n_ptr=0;
5431 PointerInfo ptr_info[2];
5432 uint64_t base__nw_size, base__extra_size;
5433 uint32_t rects__saved_size = 0;
5434 uint64_t data__extra_size;
5435 SpiceMsgDisplayDrawTransparent *out;
5436 uint32_t i;
5437
5438 { /* base */
5439 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
5440 uint64_t base_clip__nw_size, base_clip__extra_size;
5441 { /* clip */
5442 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
5443 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
5444 uint8_t type__value;
5445 { /* u */
5446 uint64_t base_clip_u__mem_size;
5447 pos = start3 + 0;
5448 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
5449 goto error;
5450 }
5451 type__value = read_uint8(pos);
5452 if (type__value == SPICE_CLIP_TYPE_RECTS) {
5453 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
5454 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
5455 uint64_t base_clip_u_rects__nelements;
5456 { /* rects */
5457 uint32_t num_rects__value;
5458 pos = start4 + 0;
5459 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5460 goto error;
5461 }
5462 num_rects__value = read_uint32(pos);
5463 base_clip_u_rects__nelements = num_rects__value;
5464
5465 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
5466 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
5467 }
5468
5469 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
5470 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
5471 rects__saved_size = base_clip_u__nw_size;
5472 base_clip_u__extra_size = base_clip_u__mem_size;
5473 } else {
5474 base_clip_u__nw_size = 0;
5475 base_clip_u__extra_size = 0;
5476 }
5477
5478 }
5479
5480 base_clip__nw_size = 1 + base_clip_u__nw_size;
5481 base_clip__extra_size = base_clip_u__extra_size;
5482 }
5483
5484 base__nw_size = 20 + base_clip__nw_size;
5485 base__extra_size = base_clip__extra_size;
5486 }
5487
5488 { /* data */
5489 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
5490 uint64_t data_src_bitmap__extra_size;
5491 { /* src_bitmap */
5492 uint32_t src_bitmap__value;
5493 pos = (start2 + 0);
5494 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5495 goto error;
5496 }
5497 src_bitmap__value = read_uint32(pos);
5498 ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value);
5499 if (SPICE_UNLIKELY(ptr_size < 0)) {
5500 goto error;
5501 }
5502 data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
5503 }
5504
5505 data__extra_size = data_src_bitmap__extra_size;
5506 }
5507
5508 nw_size = 28 + base__nw_size;
5509 mem_size = sizeof(SpiceMsgDisplayDrawTransparent) + base__extra_size + data__extra_size;
5510
5511 /* Check if message fits in reported side */
5512 if (nw_size > (uintptr_t) (message_end - start)) {
5513 return NULL;
5514 }
5515
5516 /* Validated extents and calculated size */
5517 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
5518 if (SPICE_UNLIKELY(data == NULL)) {
5519 goto error;
5520 }
5521 end = data + sizeof(SpiceMsgDisplayDrawTransparent);
5522 in = start;
5523
5524 out = (SpiceMsgDisplayDrawTransparent *)data;
5525
5526 /* base */ {
5527 out->base.surface_id = consume_uint32(&in);
5528 /* box */ {
5529 out->base.box.top = consume_int32(&in);
5530 out->base.box.left = consume_int32(&in);
5531 out->base.box.bottom = consume_int32(&in);
5532 out->base.box.right = consume_int32(&in);
5533 }
5534 /* clip */ {
5535 out->base.clip.type = consume_uint8(&in);
5536 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
5537 ptr_info[n_ptr].offset = in - start;
5538 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
5539 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
5540 n_ptr++;
5541 in += rects__saved_size;
5542 }
5543 }
5544 }
5545 /* data */ {
5546 ptr_info[n_ptr].offset = consume_uint32(&in);
5547 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
5548 ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
5549 n_ptr++;
5550 /* src_area */ {
5551 out->data.src_area.top = consume_int32(&in);
5552 out->data.src_area.left = consume_int32(&in);
5553 out->data.src_area.bottom = consume_int32(&in);
5554 out->data.src_area.right = consume_int32(&in);
5555 }
5556 out->data.src_color = consume_uint32(&in);
5557 out->data.true_color = consume_uint32(&in);
5558 }
5559
5560 assert(in <= message_end);
5561
5562 for (i = 0; i < n_ptr; i++) {
5563 if (ptr_info[i].offset == 0) {
5564 *ptr_info[i].dest = NULL;
5565 } else {
5566 /* Align to 32 bit */
5567 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
5568 *ptr_info[i].dest = (void *)end;
5569 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
5570 if (SPICE_UNLIKELY(end == NULL)) {
5571 goto error;
5572 }
5573 }
5574 }
5575
5576 assert(end <= data + mem_size);
5577
5578 *size = end - data;
5579 *free_message = (message_destructor_t) free;
5580 return data;
5581
5582 error:
5583 free(data);
5584 return NULL;
5585 }
5586
parse_msg_display_draw_alpha_blend(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)5587 static uint8_t * parse_msg_display_draw_alpha_blend(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
5588 {
5589 SPICE_GNUC_UNUSED uint8_t *pos;
5590 uint8_t *start = message_start;
5591 uint8_t *data = NULL;
5592 uint64_t nw_size;
5593 uint64_t mem_size;
5594 uint8_t *in, *end;
5595 SPICE_GNUC_UNUSED intptr_t ptr_size;
5596 uint32_t n_ptr=0;
5597 PointerInfo ptr_info[2];
5598 uint64_t base__nw_size, base__extra_size;
5599 uint32_t rects__saved_size = 0;
5600 uint64_t data__extra_size;
5601 SpiceMsgDisplayDrawAlphaBlend *out;
5602 uint32_t i;
5603
5604 { /* base */
5605 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
5606 uint64_t base_clip__nw_size, base_clip__extra_size;
5607 { /* clip */
5608 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
5609 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
5610 uint8_t type__value;
5611 { /* u */
5612 uint64_t base_clip_u__mem_size;
5613 pos = start3 + 0;
5614 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
5615 goto error;
5616 }
5617 type__value = read_uint8(pos);
5618 if (type__value == SPICE_CLIP_TYPE_RECTS) {
5619 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
5620 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
5621 uint64_t base_clip_u_rects__nelements;
5622 { /* rects */
5623 uint32_t num_rects__value;
5624 pos = start4 + 0;
5625 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5626 goto error;
5627 }
5628 num_rects__value = read_uint32(pos);
5629 base_clip_u_rects__nelements = num_rects__value;
5630
5631 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
5632 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
5633 }
5634
5635 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
5636 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
5637 rects__saved_size = base_clip_u__nw_size;
5638 base_clip_u__extra_size = base_clip_u__mem_size;
5639 } else {
5640 base_clip_u__nw_size = 0;
5641 base_clip_u__extra_size = 0;
5642 }
5643
5644 }
5645
5646 base_clip__nw_size = 1 + base_clip_u__nw_size;
5647 base_clip__extra_size = base_clip_u__extra_size;
5648 }
5649
5650 base__nw_size = 20 + base_clip__nw_size;
5651 base__extra_size = base_clip__extra_size;
5652 }
5653
5654 { /* data */
5655 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
5656 uint64_t data_src_bitmap__extra_size;
5657 { /* src_bitmap */
5658 uint32_t src_bitmap__value;
5659 pos = (start2 + 2);
5660 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5661 goto error;
5662 }
5663 src_bitmap__value = read_uint32(pos);
5664 ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value);
5665 if (SPICE_UNLIKELY(ptr_size < 0)) {
5666 goto error;
5667 }
5668 data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
5669 }
5670
5671 data__extra_size = data_src_bitmap__extra_size;
5672 }
5673
5674 nw_size = 22 + base__nw_size;
5675 mem_size = sizeof(SpiceMsgDisplayDrawAlphaBlend) + base__extra_size + data__extra_size;
5676
5677 /* Check if message fits in reported side */
5678 if (nw_size > (uintptr_t) (message_end - start)) {
5679 return NULL;
5680 }
5681
5682 /* Validated extents and calculated size */
5683 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
5684 if (SPICE_UNLIKELY(data == NULL)) {
5685 goto error;
5686 }
5687 end = data + sizeof(SpiceMsgDisplayDrawAlphaBlend);
5688 in = start;
5689
5690 out = (SpiceMsgDisplayDrawAlphaBlend *)data;
5691
5692 /* base */ {
5693 out->base.surface_id = consume_uint32(&in);
5694 /* box */ {
5695 out->base.box.top = consume_int32(&in);
5696 out->base.box.left = consume_int32(&in);
5697 out->base.box.bottom = consume_int32(&in);
5698 out->base.box.right = consume_int32(&in);
5699 }
5700 /* clip */ {
5701 out->base.clip.type = consume_uint8(&in);
5702 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
5703 ptr_info[n_ptr].offset = in - start;
5704 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
5705 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
5706 n_ptr++;
5707 in += rects__saved_size;
5708 }
5709 }
5710 }
5711 /* data */ {
5712 out->data.alpha_flags = consume_uint8(&in);
5713 out->data.alpha = consume_uint8(&in);
5714 ptr_info[n_ptr].offset = consume_uint32(&in);
5715 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
5716 ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
5717 n_ptr++;
5718 /* src_area */ {
5719 out->data.src_area.top = consume_int32(&in);
5720 out->data.src_area.left = consume_int32(&in);
5721 out->data.src_area.bottom = consume_int32(&in);
5722 out->data.src_area.right = consume_int32(&in);
5723 }
5724 }
5725
5726 assert(in <= message_end);
5727
5728 for (i = 0; i < n_ptr; i++) {
5729 if (ptr_info[i].offset == 0) {
5730 *ptr_info[i].dest = NULL;
5731 } else {
5732 /* Align to 32 bit */
5733 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
5734 *ptr_info[i].dest = (void *)end;
5735 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
5736 if (SPICE_UNLIKELY(end == NULL)) {
5737 goto error;
5738 }
5739 }
5740 }
5741
5742 assert(end <= data + mem_size);
5743
5744 *size = end - data;
5745 *free_message = (message_destructor_t) free;
5746 return data;
5747
5748 error:
5749 free(data);
5750 return NULL;
5751 }
5752
parse_msg_display_surface_create(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)5753 static uint8_t * parse_msg_display_surface_create(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
5754 {
5755 SPICE_GNUC_UNUSED uint8_t *pos;
5756 uint8_t *start = message_start;
5757 uint8_t *data = NULL;
5758 uint64_t nw_size;
5759 uint64_t mem_size;
5760 uint8_t *in, *end;
5761 SpiceMsgSurfaceCreate *out;
5762
5763 nw_size = 20;
5764 mem_size = sizeof(SpiceMsgSurfaceCreate);
5765
5766 /* Check if message fits in reported side */
5767 if (nw_size > (uintptr_t) (message_end - start)) {
5768 return NULL;
5769 }
5770
5771 /* Validated extents and calculated size */
5772 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
5773 if (SPICE_UNLIKELY(data == NULL)) {
5774 goto error;
5775 }
5776 end = data + sizeof(SpiceMsgSurfaceCreate);
5777 in = start;
5778
5779 out = (SpiceMsgSurfaceCreate *)data;
5780
5781 out->surface_id = consume_uint32(&in);
5782 out->width = consume_uint32(&in);
5783 out->height = consume_uint32(&in);
5784 out->format = consume_uint32(&in);
5785 out->flags = consume_uint32(&in);
5786
5787 assert(in <= message_end);
5788 assert(end <= data + mem_size);
5789
5790 *size = end - data;
5791 *free_message = (message_destructor_t) free;
5792 return data;
5793
5794 error:
5795 free(data);
5796 return NULL;
5797 }
5798
parse_msg_display_surface_destroy(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)5799 static uint8_t * parse_msg_display_surface_destroy(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
5800 {
5801 SPICE_GNUC_UNUSED uint8_t *pos;
5802 uint8_t *start = message_start;
5803 uint8_t *data = NULL;
5804 uint64_t nw_size;
5805 uint64_t mem_size;
5806 uint8_t *in, *end;
5807 SpiceMsgSurfaceDestroy *out;
5808
5809 nw_size = 4;
5810 mem_size = sizeof(SpiceMsgSurfaceDestroy);
5811
5812 /* Check if message fits in reported side */
5813 if (nw_size > (uintptr_t) (message_end - start)) {
5814 return NULL;
5815 }
5816
5817 /* Validated extents and calculated size */
5818 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
5819 if (SPICE_UNLIKELY(data == NULL)) {
5820 goto error;
5821 }
5822 end = data + sizeof(SpiceMsgSurfaceDestroy);
5823 in = start;
5824
5825 out = (SpiceMsgSurfaceDestroy *)data;
5826
5827 out->surface_id = consume_uint32(&in);
5828
5829 assert(in <= message_end);
5830 assert(end <= data + mem_size);
5831
5832 *size = end - data;
5833 *free_message = (message_destructor_t) free;
5834 return data;
5835
5836 error:
5837 free(data);
5838 return NULL;
5839 }
5840
parse_msg_display_stream_data_sized(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)5841 static uint8_t * parse_msg_display_stream_data_sized(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
5842 {
5843 SPICE_GNUC_UNUSED uint8_t *pos;
5844 uint8_t *start = message_start;
5845 uint8_t *data = NULL;
5846 uint64_t nw_size;
5847 uint64_t mem_size;
5848 uint8_t *in, *end;
5849 uint64_t data__nw_size, data__mem_size;
5850 uint64_t data__nelements;
5851 SpiceMsgDisplayStreamDataSized *out;
5852
5853 { /* data */
5854 uint32_t data_size__value;
5855 pos = start + 32;
5856 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
5857 goto error;
5858 }
5859 data_size__value = read_uint32(pos);
5860 data__nelements = data_size__value;
5861
5862 data__nw_size = data__nelements;
5863 data__mem_size = sizeof(uint8_t) * data__nelements;
5864 }
5865
5866 nw_size = 36 + data__nw_size;
5867 mem_size = sizeof(SpiceMsgDisplayStreamDataSized) + data__mem_size;
5868
5869 /* Check if message fits in reported side */
5870 if (nw_size > (uintptr_t) (message_end - start)) {
5871 return NULL;
5872 }
5873
5874 /* Validated extents and calculated size */
5875 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
5876 if (SPICE_UNLIKELY(data == NULL)) {
5877 goto error;
5878 }
5879 end = data + sizeof(SpiceMsgDisplayStreamDataSized);
5880 in = start;
5881
5882 out = (SpiceMsgDisplayStreamDataSized *)data;
5883
5884 /* base */ {
5885 out->base.id = consume_uint32(&in);
5886 out->base.multi_media_time = consume_uint32(&in);
5887 }
5888 out->width = consume_uint32(&in);
5889 out->height = consume_uint32(&in);
5890 /* dest */ {
5891 out->dest.top = consume_int32(&in);
5892 out->dest.left = consume_int32(&in);
5893 out->dest.bottom = consume_int32(&in);
5894 out->dest.right = consume_int32(&in);
5895 }
5896 out->data_size = consume_uint32(&in);
5897 memcpy(out->data, in, data__nelements);
5898 in += data__nelements;
5899 end += data__nelements;
5900
5901 assert(in <= message_end);
5902 assert(end <= data + mem_size);
5903
5904 *size = end - data;
5905 *free_message = (message_destructor_t) free;
5906 return data;
5907
5908 error:
5909 free(data);
5910 return NULL;
5911 }
5912
parse_msg_display_monitors_config(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)5913 static uint8_t * parse_msg_display_monitors_config(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
5914 {
5915 SPICE_GNUC_UNUSED uint8_t *pos;
5916 uint8_t *start = message_start;
5917 uint8_t *data = NULL;
5918 uint64_t nw_size;
5919 uint64_t mem_size;
5920 uint8_t *in, *end;
5921 uint64_t heads__nw_size, heads__mem_size;
5922 uint64_t heads__nelements;
5923 SpiceMsgDisplayMonitorsConfig *out;
5924 uint32_t i;
5925
5926 { /* heads */
5927 uint16_t count__value;
5928 pos = start + 0;
5929 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
5930 goto error;
5931 }
5932 count__value = read_uint16(pos);
5933 heads__nelements = count__value;
5934
5935 heads__nw_size = (28) * heads__nelements;
5936 heads__mem_size = sizeof(SpiceHead) * heads__nelements;
5937 }
5938
5939 nw_size = 4 + heads__nw_size;
5940 mem_size = sizeof(SpiceMsgDisplayMonitorsConfig) + heads__mem_size;
5941
5942 /* Check if message fits in reported side */
5943 if (nw_size > (uintptr_t) (message_end - start)) {
5944 return NULL;
5945 }
5946
5947 /* Validated extents and calculated size */
5948 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
5949 if (SPICE_UNLIKELY(data == NULL)) {
5950 goto error;
5951 }
5952 end = data + sizeof(SpiceMsgDisplayMonitorsConfig);
5953 in = start;
5954
5955 out = (SpiceMsgDisplayMonitorsConfig *)data;
5956
5957 out->count = consume_uint16(&in);
5958 out->max_allowed = consume_uint16(&in);
5959 for (i = 0; i < heads__nelements; i++) {
5960 SpiceHead *out2;
5961 out2 = (SpiceHead *)end;
5962 end += sizeof(SpiceHead);
5963
5964 out2->monitor_id = consume_uint32(&in);
5965 out2->surface_id = consume_uint32(&in);
5966 out2->width = consume_uint32(&in);
5967 out2->height = consume_uint32(&in);
5968 out2->x = consume_uint32(&in);
5969 out2->y = consume_uint32(&in);
5970 out2->flags = consume_uint32(&in);
5971 }
5972
5973 assert(in <= message_end);
5974 assert(end <= data + mem_size);
5975
5976 *size = end - data;
5977 *free_message = (message_destructor_t) free;
5978 return data;
5979
5980 error:
5981 free(data);
5982 return NULL;
5983 }
5984
parse_msg_display_draw_composite(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)5985 static uint8_t * parse_msg_display_draw_composite(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
5986 {
5987 SPICE_GNUC_UNUSED uint8_t *pos;
5988 uint8_t *start = message_start;
5989 uint8_t *data = NULL;
5990 uint64_t nw_size;
5991 uint64_t mem_size;
5992 uint8_t *in, *end;
5993 SPICE_GNUC_UNUSED intptr_t ptr_size;
5994 uint32_t n_ptr=0;
5995 PointerInfo ptr_info[3];
5996 uint64_t base__nw_size, base__extra_size;
5997 uint32_t rects__saved_size = 0;
5998 uint64_t data__nw_size, data__extra_size;
5999 SpiceMsgDisplayDrawComposite *out;
6000 uint32_t i;
6001
6002 { /* base */
6003 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
6004 uint64_t base_clip__nw_size, base_clip__extra_size;
6005 { /* clip */
6006 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
6007 uint64_t base_clip_u__nw_size, base_clip_u__extra_size;
6008 uint8_t type__value;
6009 { /* u */
6010 uint64_t base_clip_u__mem_size;
6011 pos = start3 + 0;
6012 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
6013 goto error;
6014 }
6015 type__value = read_uint8(pos);
6016 if (type__value == SPICE_CLIP_TYPE_RECTS) {
6017 SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
6018 uint64_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
6019 uint64_t base_clip_u_rects__nelements;
6020 { /* rects */
6021 uint32_t num_rects__value;
6022 pos = start4 + 0;
6023 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
6024 goto error;
6025 }
6026 num_rects__value = read_uint32(pos);
6027 base_clip_u_rects__nelements = num_rects__value;
6028
6029 base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
6030 base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
6031 }
6032
6033 base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
6034 base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
6035 rects__saved_size = base_clip_u__nw_size;
6036 base_clip_u__extra_size = base_clip_u__mem_size;
6037 } else {
6038 base_clip_u__nw_size = 0;
6039 base_clip_u__extra_size = 0;
6040 }
6041
6042 }
6043
6044 base_clip__nw_size = 1 + base_clip_u__nw_size;
6045 base_clip__extra_size = base_clip_u__extra_size;
6046 }
6047
6048 base__nw_size = 20 + base_clip__nw_size;
6049 base__extra_size = base_clip__extra_size;
6050 }
6051
6052 { /* data */
6053 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
6054 uint64_t data_src_bitmap__extra_size;
6055 uint64_t data_a__nw_size, data_a__extra_size;
6056 uint32_t flags__value;
6057 uint64_t data_b__nw_size;
6058 uint64_t data_c__nw_size;
6059 { /* src_bitmap */
6060 uint32_t src_bitmap__value;
6061 pos = (start2 + 4);
6062 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
6063 goto error;
6064 }
6065 src_bitmap__value = read_uint32(pos);
6066 ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value);
6067 if (SPICE_UNLIKELY(ptr_size < 0)) {
6068 goto error;
6069 }
6070 data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
6071 }
6072
6073 { /* a */
6074 pos = start2 + 0;
6075 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
6076 goto error;
6077 }
6078 flags__value = read_uint32(pos);
6079 if ((flags__value & SPICE_COMPOSITE_HAS_MASK)) {
6080 uint32_t data_a_mask_bitmap__value;
6081 data_a__nw_size = 4;
6082 pos = (start2 + 8);
6083 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
6084 goto error;
6085 }
6086 data_a_mask_bitmap__value = read_uint32(pos);
6087 ptr_size = validate_SpiceImage(message_start, message_end, data_a_mask_bitmap__value);
6088 if (SPICE_UNLIKELY(ptr_size < 0)) {
6089 goto error;
6090 }
6091 data_a__extra_size = ptr_size + /* for alignment */ 3;
6092 } else {
6093 data_a__nw_size = 0;
6094 data_a__extra_size = 0;
6095 }
6096
6097 }
6098
6099 { /* b */
6100 pos = start2 + 0;
6101 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
6102 goto error;
6103 }
6104 flags__value = read_uint32(pos);
6105 if ((flags__value & SPICE_COMPOSITE_HAS_SRC_TRANSFORM)) {
6106 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 8 + data_a__nw_size);
6107 data_b__nw_size = 24;
6108 } else {
6109 data_b__nw_size = 0;
6110 }
6111
6112 }
6113
6114 { /* c */
6115 pos = start2 + 0;
6116 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
6117 goto error;
6118 }
6119 flags__value = read_uint32(pos);
6120 if ((flags__value & SPICE_COMPOSITE_HAS_MASK_TRANSFORM)) {
6121 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 8 + data_a__nw_size + data_b__nw_size);
6122 data_c__nw_size = 24;
6123 } else {
6124 data_c__nw_size = 0;
6125 }
6126
6127 }
6128
6129 data__nw_size = 16 + data_a__nw_size + data_b__nw_size + data_c__nw_size;
6130 data__extra_size = data_src_bitmap__extra_size + data_a__extra_size;
6131 }
6132
6133 nw_size = 0 + base__nw_size + data__nw_size;
6134 mem_size = sizeof(SpiceMsgDisplayDrawComposite) + base__extra_size + data__extra_size;
6135
6136 /* Check if message fits in reported side */
6137 if (nw_size > (uintptr_t) (message_end - start)) {
6138 return NULL;
6139 }
6140
6141 /* Validated extents and calculated size */
6142 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6143 if (SPICE_UNLIKELY(data == NULL)) {
6144 goto error;
6145 }
6146 end = data + sizeof(SpiceMsgDisplayDrawComposite);
6147 in = start;
6148
6149 out = (SpiceMsgDisplayDrawComposite *)data;
6150
6151 /* base */ {
6152 out->base.surface_id = consume_uint32(&in);
6153 /* box */ {
6154 out->base.box.top = consume_int32(&in);
6155 out->base.box.left = consume_int32(&in);
6156 out->base.box.bottom = consume_int32(&in);
6157 out->base.box.right = consume_int32(&in);
6158 }
6159 /* clip */ {
6160 out->base.clip.type = consume_uint8(&in);
6161 if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
6162 ptr_info[n_ptr].offset = in - start;
6163 ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
6164 ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
6165 n_ptr++;
6166 in += rects__saved_size;
6167 }
6168 }
6169 }
6170 /* data */ {
6171 out->data.flags = consume_uint32(&in);
6172 ptr_info[n_ptr].offset = consume_uint32(&in);
6173 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
6174 ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
6175 n_ptr++;
6176 if ((out->data.flags & SPICE_COMPOSITE_HAS_MASK)) {
6177 ptr_info[n_ptr].offset = consume_uint32(&in);
6178 ptr_info[n_ptr].parse = parse_struct_SpiceImage;
6179 ptr_info[n_ptr].dest = (void **)&out->data.mask_bitmap;
6180 n_ptr++;
6181 }
6182 if ((out->data.flags & SPICE_COMPOSITE_HAS_SRC_TRANSFORM)) {
6183 out->data.src_transform.t00 = consume_uint32(&in);
6184 out->data.src_transform.t01 = consume_uint32(&in);
6185 out->data.src_transform.t02 = consume_uint32(&in);
6186 out->data.src_transform.t10 = consume_uint32(&in);
6187 out->data.src_transform.t11 = consume_uint32(&in);
6188 out->data.src_transform.t12 = consume_uint32(&in);
6189 }
6190 if ((out->data.flags & SPICE_COMPOSITE_HAS_MASK_TRANSFORM)) {
6191 out->data.mask_transform.t00 = consume_uint32(&in);
6192 out->data.mask_transform.t01 = consume_uint32(&in);
6193 out->data.mask_transform.t02 = consume_uint32(&in);
6194 out->data.mask_transform.t10 = consume_uint32(&in);
6195 out->data.mask_transform.t11 = consume_uint32(&in);
6196 out->data.mask_transform.t12 = consume_uint32(&in);
6197 }
6198 /* src_origin */ {
6199 out->data.src_origin.x = consume_int16(&in);
6200 out->data.src_origin.y = consume_int16(&in);
6201 }
6202 /* mask_origin */ {
6203 out->data.mask_origin.x = consume_int16(&in);
6204 out->data.mask_origin.y = consume_int16(&in);
6205 }
6206 }
6207
6208 assert(in <= message_end);
6209
6210 for (i = 0; i < n_ptr; i++) {
6211 if (ptr_info[i].offset == 0) {
6212 *ptr_info[i].dest = NULL;
6213 } else {
6214 /* Align to 32 bit */
6215 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
6216 *ptr_info[i].dest = (void *)end;
6217 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
6218 if (SPICE_UNLIKELY(end == NULL)) {
6219 goto error;
6220 }
6221 }
6222 }
6223
6224 assert(end <= data + mem_size);
6225
6226 *size = end - data;
6227 *free_message = (message_destructor_t) free;
6228 return data;
6229
6230 error:
6231 free(data);
6232 return NULL;
6233 }
6234
parse_msg_display_stream_activate_report(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6235 static uint8_t * parse_msg_display_stream_activate_report(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6236 {
6237 SPICE_GNUC_UNUSED uint8_t *pos;
6238 uint8_t *start = message_start;
6239 uint8_t *data = NULL;
6240 uint64_t nw_size;
6241 uint64_t mem_size;
6242 uint8_t *in, *end;
6243 SpiceMsgDisplayStreamActivateReport *out;
6244
6245 nw_size = 16;
6246 mem_size = sizeof(SpiceMsgDisplayStreamActivateReport);
6247
6248 /* Check if message fits in reported side */
6249 if (nw_size > (uintptr_t) (message_end - start)) {
6250 return NULL;
6251 }
6252
6253 /* Validated extents and calculated size */
6254 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6255 if (SPICE_UNLIKELY(data == NULL)) {
6256 goto error;
6257 }
6258 end = data + sizeof(SpiceMsgDisplayStreamActivateReport);
6259 in = start;
6260
6261 out = (SpiceMsgDisplayStreamActivateReport *)data;
6262
6263 out->stream_id = consume_uint32(&in);
6264 out->unique_id = consume_uint32(&in);
6265 out->max_window_size = consume_uint32(&in);
6266 out->timeout_ms = consume_uint32(&in);
6267
6268 assert(in <= message_end);
6269 assert(end <= data + mem_size);
6270
6271 *size = end - data;
6272 *free_message = (message_destructor_t) free;
6273 return data;
6274
6275 error:
6276 free(data);
6277 return NULL;
6278 }
6279
parse_msg_display_gl_scanout_unix(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6280 static uint8_t * parse_msg_display_gl_scanout_unix(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6281 {
6282 SPICE_GNUC_UNUSED uint8_t *pos;
6283 uint8_t *start = message_start;
6284 uint8_t *data = NULL;
6285 uint64_t nw_size;
6286 uint64_t mem_size;
6287 uint8_t *in, *end;
6288 SpiceMsgDisplayGlScanoutUnix *out;
6289
6290 nw_size = 20;
6291 mem_size = sizeof(SpiceMsgDisplayGlScanoutUnix);
6292
6293 /* Check if message fits in reported side */
6294 if (nw_size > (uintptr_t) (message_end - start)) {
6295 return NULL;
6296 }
6297
6298 /* Validated extents and calculated size */
6299 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6300 if (SPICE_UNLIKELY(data == NULL)) {
6301 goto error;
6302 }
6303 end = data + sizeof(SpiceMsgDisplayGlScanoutUnix);
6304 in = start;
6305
6306 out = (SpiceMsgDisplayGlScanoutUnix *)data;
6307
6308 out->drm_dma_buf_fd = consume_fd(&in);
6309 out->width = consume_uint32(&in);
6310 out->height = consume_uint32(&in);
6311 out->stride = consume_uint32(&in);
6312 out->drm_fourcc_format = consume_uint32(&in);
6313 out->flags = consume_uint32(&in);
6314
6315 assert(in <= message_end);
6316 assert(end <= data + mem_size);
6317
6318 *size = end - data;
6319 *free_message = (message_destructor_t) free;
6320 return data;
6321
6322 error:
6323 free(data);
6324 return NULL;
6325 }
6326
parse_msg_display_gl_draw(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6327 static uint8_t * parse_msg_display_gl_draw(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6328 {
6329 SPICE_GNUC_UNUSED uint8_t *pos;
6330 uint8_t *start = message_start;
6331 uint8_t *data = NULL;
6332 uint64_t nw_size;
6333 uint64_t mem_size;
6334 uint8_t *in, *end;
6335 SpiceMsgDisplayGlDraw *out;
6336
6337 nw_size = 16;
6338 mem_size = sizeof(SpiceMsgDisplayGlDraw);
6339
6340 /* Check if message fits in reported side */
6341 if (nw_size > (uintptr_t) (message_end - start)) {
6342 return NULL;
6343 }
6344
6345 /* Validated extents and calculated size */
6346 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6347 if (SPICE_UNLIKELY(data == NULL)) {
6348 goto error;
6349 }
6350 end = data + sizeof(SpiceMsgDisplayGlDraw);
6351 in = start;
6352
6353 out = (SpiceMsgDisplayGlDraw *)data;
6354
6355 out->x = consume_uint32(&in);
6356 out->y = consume_uint32(&in);
6357 out->w = consume_uint32(&in);
6358 out->h = consume_uint32(&in);
6359
6360 assert(in <= message_end);
6361 assert(end <= data + mem_size);
6362
6363 *size = end - data;
6364 *free_message = (message_destructor_t) free;
6365 return data;
6366
6367 error:
6368 free(data);
6369 return NULL;
6370 }
6371
parse_DisplayChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)6372 static uint8_t * parse_DisplayChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
6373 {
6374 static parse_msg_func_t funcs1[8] = {
6375 parse_msg_migrate,
6376 parse_SpiceMsgData,
6377 parse_msg_set_ack,
6378 parse_msg_ping,
6379 parse_msg_wait_for_channels,
6380 parse_msg_disconnecting,
6381 parse_msg_notify,
6382 parse_SpiceMsgData
6383 };
6384 static parse_msg_func_t funcs2[9] = {
6385 parse_SpiceMsgEmpty,
6386 parse_msg_display_mode,
6387 parse_SpiceMsgEmpty,
6388 parse_SpiceMsgEmpty,
6389 parse_msg_display_copy_bits,
6390 parse_msg_display_inval_list,
6391 parse_msg_display_inval_all_pixmaps,
6392 parse_msg_display_inval_palette,
6393 parse_SpiceMsgEmpty
6394 };
6395 static parse_msg_func_t funcs3[5] = {
6396 parse_msg_display_stream_create,
6397 parse_msg_display_stream_data,
6398 parse_msg_display_stream_clip,
6399 parse_msg_display_stream_destroy,
6400 parse_SpiceMsgEmpty
6401 };
6402 static parse_msg_func_t funcs4[20] = {
6403 parse_msg_display_draw_fill,
6404 parse_msg_display_draw_opaque,
6405 parse_msg_display_draw_copy,
6406 parse_msg_display_draw_blend,
6407 parse_msg_display_draw_blackness,
6408 parse_msg_display_draw_whiteness,
6409 parse_msg_display_draw_invers,
6410 parse_msg_display_draw_rop3,
6411 parse_msg_display_draw_stroke,
6412 parse_msg_display_draw_text,
6413 parse_msg_display_draw_transparent,
6414 parse_msg_display_draw_alpha_blend,
6415 parse_msg_display_surface_create,
6416 parse_msg_display_surface_destroy,
6417 parse_msg_display_stream_data_sized,
6418 parse_msg_display_monitors_config,
6419 parse_msg_display_draw_composite,
6420 parse_msg_display_stream_activate_report,
6421 parse_msg_display_gl_scanout_unix,
6422 parse_msg_display_gl_draw
6423 };
6424 if (message_type >= 1 && message_type < 9) {
6425 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
6426 } else if (message_type >= 100 && message_type < 109) {
6427 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
6428 } else if (message_type >= 122 && message_type < 127) {
6429 return funcs3[message_type-122](message_start, message_end, size_out, free_message);
6430 } else if (message_type >= 302 && message_type < 322) {
6431 return funcs4[message_type-302](message_start, message_end, size_out, free_message);
6432 }
6433 return NULL;
6434 }
6435
6436
6437
parse_msg_inputs_init(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6438 static uint8_t * parse_msg_inputs_init(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6439 {
6440 SPICE_GNUC_UNUSED uint8_t *pos;
6441 uint8_t *start = message_start;
6442 uint8_t *data = NULL;
6443 uint64_t nw_size;
6444 uint64_t mem_size;
6445 uint8_t *in, *end;
6446 SpiceMsgInputsInit *out;
6447
6448 nw_size = 2;
6449 mem_size = sizeof(SpiceMsgInputsInit);
6450
6451 /* Check if message fits in reported side */
6452 if (nw_size > (uintptr_t) (message_end - start)) {
6453 return NULL;
6454 }
6455
6456 /* Validated extents and calculated size */
6457 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6458 if (SPICE_UNLIKELY(data == NULL)) {
6459 goto error;
6460 }
6461 end = data + sizeof(SpiceMsgInputsInit);
6462 in = start;
6463
6464 out = (SpiceMsgInputsInit *)data;
6465
6466 out->keyboard_modifiers = consume_uint16(&in);
6467
6468 assert(in <= message_end);
6469 assert(end <= data + mem_size);
6470
6471 *size = end - data;
6472 *free_message = (message_destructor_t) free;
6473 return data;
6474
6475 error:
6476 free(data);
6477 return NULL;
6478 }
6479
parse_msg_inputs_key_modifiers(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6480 static uint8_t * parse_msg_inputs_key_modifiers(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6481 {
6482 SPICE_GNUC_UNUSED uint8_t *pos;
6483 uint8_t *start = message_start;
6484 uint8_t *data = NULL;
6485 uint64_t nw_size;
6486 uint64_t mem_size;
6487 uint8_t *in, *end;
6488 SpiceMsgInputsKeyModifiers *out;
6489
6490 nw_size = 2;
6491 mem_size = sizeof(SpiceMsgInputsKeyModifiers);
6492
6493 /* Check if message fits in reported side */
6494 if (nw_size > (uintptr_t) (message_end - start)) {
6495 return NULL;
6496 }
6497
6498 /* Validated extents and calculated size */
6499 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6500 if (SPICE_UNLIKELY(data == NULL)) {
6501 goto error;
6502 }
6503 end = data + sizeof(SpiceMsgInputsKeyModifiers);
6504 in = start;
6505
6506 out = (SpiceMsgInputsKeyModifiers *)data;
6507
6508 out->modifiers = consume_uint16(&in);
6509
6510 assert(in <= message_end);
6511 assert(end <= data + mem_size);
6512
6513 *size = end - data;
6514 *free_message = (message_destructor_t) free;
6515 return data;
6516
6517 error:
6518 free(data);
6519 return NULL;
6520 }
6521
parse_InputsChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)6522 static uint8_t * parse_InputsChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
6523 {
6524 static parse_msg_func_t funcs1[8] = {
6525 parse_msg_migrate,
6526 parse_SpiceMsgData,
6527 parse_msg_set_ack,
6528 parse_msg_ping,
6529 parse_msg_wait_for_channels,
6530 parse_msg_disconnecting,
6531 parse_msg_notify,
6532 parse_SpiceMsgData
6533 };
6534 static parse_msg_func_t funcs2[3] = {
6535 parse_SpiceMsgEmpty,
6536 parse_msg_inputs_init,
6537 parse_msg_inputs_key_modifiers
6538 };
6539 static parse_msg_func_t funcs3[1] = {
6540 parse_SpiceMsgEmpty
6541 };
6542 if (message_type >= 1 && message_type < 9) {
6543 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
6544 } else if (message_type >= 100 && message_type < 103) {
6545 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
6546 } else if (message_type >= 111 && message_type < 112) {
6547 return funcs3[message_type-111](message_start, message_end, size_out, free_message);
6548 }
6549 return NULL;
6550 }
6551
6552
6553
parse_msg_cursor_init(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6554 static uint8_t * parse_msg_cursor_init(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6555 {
6556 SPICE_GNUC_UNUSED uint8_t *pos;
6557 uint8_t *start = message_start;
6558 uint8_t *data = NULL;
6559 uint64_t nw_size;
6560 uint64_t mem_size;
6561 uint8_t *in, *end;
6562 uint64_t cursor__nw_size;
6563 SpiceMsgCursorInit *out;
6564
6565 { /* cursor */
6566 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 9);
6567 uint64_t cursor_u__nw_size;
6568 uint16_t flags__value;
6569 uint64_t cursor_data__nw_size;
6570 uint64_t cursor_data__nelements;
6571 { /* u */
6572 pos = start2 + 0;
6573 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
6574 goto error;
6575 }
6576 flags__value = read_uint16(pos);
6577 if (!(flags__value & SPICE_CURSOR_FLAGS_NONE)) {
6578 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 2);
6579 cursor_u__nw_size = 17;
6580 } else {
6581 cursor_u__nw_size = 0;
6582 }
6583
6584 }
6585
6586 { /* data */
6587 if (SPICE_UNLIKELY((start2 + 2 + cursor_u__nw_size) > message_end)) {
6588 goto error;
6589 }
6590 cursor_data__nelements = message_end - (start2 + 2 + cursor_u__nw_size);
6591
6592 cursor_data__nw_size = cursor_data__nelements;
6593 }
6594
6595 cursor__nw_size = 2 + cursor_u__nw_size + cursor_data__nw_size;
6596 }
6597
6598 nw_size = 9 + cursor__nw_size;
6599 mem_size = sizeof(SpiceMsgCursorInit);
6600
6601 /* Check if message fits in reported side */
6602 if (nw_size > (uintptr_t) (message_end - start)) {
6603 return NULL;
6604 }
6605
6606 /* Validated extents and calculated size */
6607 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6608 if (SPICE_UNLIKELY(data == NULL)) {
6609 goto error;
6610 }
6611 end = data + sizeof(SpiceMsgCursorInit);
6612 in = start;
6613
6614 out = (SpiceMsgCursorInit *)data;
6615
6616 /* position */ {
6617 out->position.x = consume_int16(&in);
6618 out->position.y = consume_int16(&in);
6619 }
6620 out->trail_length = consume_uint16(&in);
6621 out->trail_frequency = consume_uint16(&in);
6622 out->visible = consume_uint8(&in);
6623 /* cursor */ {
6624 uint64_t data__nelements;
6625 out->cursor.flags = consume_uint16(&in);
6626 if (!(out->cursor.flags & SPICE_CURSOR_FLAGS_NONE)) {
6627 out->cursor.header.unique = consume_uint64(&in);
6628 out->cursor.header.type = consume_uint8(&in);
6629 out->cursor.header.width = consume_uint16(&in);
6630 out->cursor.header.height = consume_uint16(&in);
6631 out->cursor.header.hot_spot_x = consume_uint16(&in);
6632 out->cursor.header.hot_spot_y = consume_uint16(&in);
6633 }
6634 data__nelements = (message_end - in) / (1);
6635 /* use array as pointer */
6636 out->cursor.data = (uint8_t *)in;
6637 out->cursor.data_size = data__nelements;
6638 in += data__nelements;
6639 }
6640
6641 assert(in <= message_end);
6642 assert(end <= data + mem_size);
6643
6644 *size = end - data;
6645 *free_message = (message_destructor_t) free;
6646 return data;
6647
6648 error:
6649 free(data);
6650 return NULL;
6651 }
6652
parse_msg_cursor_set(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6653 static uint8_t * parse_msg_cursor_set(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6654 {
6655 SPICE_GNUC_UNUSED uint8_t *pos;
6656 uint8_t *start = message_start;
6657 uint8_t *data = NULL;
6658 uint64_t nw_size;
6659 uint64_t mem_size;
6660 uint8_t *in, *end;
6661 uint64_t cursor__nw_size;
6662 SpiceMsgCursorSet *out;
6663
6664 { /* cursor */
6665 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 5);
6666 uint64_t cursor_u__nw_size;
6667 uint16_t flags__value;
6668 uint64_t cursor_data__nw_size;
6669 uint64_t cursor_data__nelements;
6670 { /* u */
6671 pos = start2 + 0;
6672 if (SPICE_UNLIKELY(pos + 2 > message_end)) {
6673 goto error;
6674 }
6675 flags__value = read_uint16(pos);
6676 if (!(flags__value & SPICE_CURSOR_FLAGS_NONE)) {
6677 SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 2);
6678 cursor_u__nw_size = 17;
6679 } else {
6680 cursor_u__nw_size = 0;
6681 }
6682
6683 }
6684
6685 { /* data */
6686 if (SPICE_UNLIKELY((start2 + 2 + cursor_u__nw_size) > message_end)) {
6687 goto error;
6688 }
6689 cursor_data__nelements = message_end - (start2 + 2 + cursor_u__nw_size);
6690
6691 cursor_data__nw_size = cursor_data__nelements;
6692 }
6693
6694 cursor__nw_size = 2 + cursor_u__nw_size + cursor_data__nw_size;
6695 }
6696
6697 nw_size = 5 + cursor__nw_size;
6698 mem_size = sizeof(SpiceMsgCursorSet);
6699
6700 /* Check if message fits in reported side */
6701 if (nw_size > (uintptr_t) (message_end - start)) {
6702 return NULL;
6703 }
6704
6705 /* Validated extents and calculated size */
6706 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6707 if (SPICE_UNLIKELY(data == NULL)) {
6708 goto error;
6709 }
6710 end = data + sizeof(SpiceMsgCursorSet);
6711 in = start;
6712
6713 out = (SpiceMsgCursorSet *)data;
6714
6715 /* position */ {
6716 out->position.x = consume_int16(&in);
6717 out->position.y = consume_int16(&in);
6718 }
6719 out->visible = consume_uint8(&in);
6720 /* cursor */ {
6721 uint64_t data__nelements;
6722 out->cursor.flags = consume_uint16(&in);
6723 if (!(out->cursor.flags & SPICE_CURSOR_FLAGS_NONE)) {
6724 out->cursor.header.unique = consume_uint64(&in);
6725 out->cursor.header.type = consume_uint8(&in);
6726 out->cursor.header.width = consume_uint16(&in);
6727 out->cursor.header.height = consume_uint16(&in);
6728 out->cursor.header.hot_spot_x = consume_uint16(&in);
6729 out->cursor.header.hot_spot_y = consume_uint16(&in);
6730 }
6731 data__nelements = (message_end - in) / (1);
6732 /* use array as pointer */
6733 out->cursor.data = (uint8_t *)in;
6734 out->cursor.data_size = data__nelements;
6735 in += data__nelements;
6736 }
6737
6738 assert(in <= message_end);
6739 assert(end <= data + mem_size);
6740
6741 *size = end - data;
6742 *free_message = (message_destructor_t) free;
6743 return data;
6744
6745 error:
6746 free(data);
6747 return NULL;
6748 }
6749
parse_msg_cursor_move(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6750 static uint8_t * parse_msg_cursor_move(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6751 {
6752 SPICE_GNUC_UNUSED uint8_t *pos;
6753 uint8_t *start = message_start;
6754 uint8_t *data = NULL;
6755 uint64_t nw_size;
6756 uint64_t mem_size;
6757 uint8_t *in, *end;
6758 SpiceMsgCursorMove *out;
6759
6760 nw_size = 4;
6761 mem_size = sizeof(SpiceMsgCursorMove);
6762
6763 /* Check if message fits in reported side */
6764 if (nw_size > (uintptr_t) (message_end - start)) {
6765 return NULL;
6766 }
6767
6768 /* Validated extents and calculated size */
6769 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6770 if (SPICE_UNLIKELY(data == NULL)) {
6771 goto error;
6772 }
6773 end = data + sizeof(SpiceMsgCursorMove);
6774 in = start;
6775
6776 out = (SpiceMsgCursorMove *)data;
6777
6778 /* position */ {
6779 out->position.x = consume_int16(&in);
6780 out->position.y = consume_int16(&in);
6781 }
6782
6783 assert(in <= message_end);
6784 assert(end <= data + mem_size);
6785
6786 *size = end - data;
6787 *free_message = (message_destructor_t) free;
6788 return data;
6789
6790 error:
6791 free(data);
6792 return NULL;
6793 }
6794
parse_msg_cursor_trail(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6795 static uint8_t * parse_msg_cursor_trail(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6796 {
6797 SPICE_GNUC_UNUSED uint8_t *pos;
6798 uint8_t *start = message_start;
6799 uint8_t *data = NULL;
6800 uint64_t nw_size;
6801 uint64_t mem_size;
6802 uint8_t *in, *end;
6803 SpiceMsgCursorTrail *out;
6804
6805 nw_size = 4;
6806 mem_size = sizeof(SpiceMsgCursorTrail);
6807
6808 /* Check if message fits in reported side */
6809 if (nw_size > (uintptr_t) (message_end - start)) {
6810 return NULL;
6811 }
6812
6813 /* Validated extents and calculated size */
6814 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6815 if (SPICE_UNLIKELY(data == NULL)) {
6816 goto error;
6817 }
6818 end = data + sizeof(SpiceMsgCursorTrail);
6819 in = start;
6820
6821 out = (SpiceMsgCursorTrail *)data;
6822
6823 out->length = consume_uint16(&in);
6824 out->frequency = consume_uint16(&in);
6825
6826 assert(in <= message_end);
6827 assert(end <= data + mem_size);
6828
6829 *size = end - data;
6830 *free_message = (message_destructor_t) free;
6831 return data;
6832
6833 error:
6834 free(data);
6835 return NULL;
6836 }
6837
parse_msg_cursor_inval_one(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6838 static uint8_t * parse_msg_cursor_inval_one(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6839 {
6840 SPICE_GNUC_UNUSED uint8_t *pos;
6841 uint8_t *start = message_start;
6842 uint8_t *data = NULL;
6843 uint64_t nw_size;
6844 uint64_t mem_size;
6845 uint8_t *in, *end;
6846 SpiceMsgDisplayInvalOne *out;
6847
6848 nw_size = 8;
6849 mem_size = sizeof(SpiceMsgDisplayInvalOne);
6850
6851 /* Check if message fits in reported side */
6852 if (nw_size > (uintptr_t) (message_end - start)) {
6853 return NULL;
6854 }
6855
6856 /* Validated extents and calculated size */
6857 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6858 if (SPICE_UNLIKELY(data == NULL)) {
6859 goto error;
6860 }
6861 end = data + sizeof(SpiceMsgDisplayInvalOne);
6862 in = start;
6863
6864 out = (SpiceMsgDisplayInvalOne *)data;
6865
6866 out->id = consume_uint64(&in);
6867
6868 assert(in <= message_end);
6869 assert(end <= data + mem_size);
6870
6871 *size = end - data;
6872 *free_message = (message_destructor_t) free;
6873 return data;
6874
6875 error:
6876 free(data);
6877 return NULL;
6878 }
6879
parse_CursorChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)6880 static uint8_t * parse_CursorChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
6881 {
6882 static parse_msg_func_t funcs1[8] = {
6883 parse_msg_migrate,
6884 parse_SpiceMsgData,
6885 parse_msg_set_ack,
6886 parse_msg_ping,
6887 parse_msg_wait_for_channels,
6888 parse_msg_disconnecting,
6889 parse_msg_notify,
6890 parse_SpiceMsgData
6891 };
6892 static parse_msg_func_t funcs2[9] = {
6893 parse_SpiceMsgEmpty,
6894 parse_msg_cursor_init,
6895 parse_SpiceMsgEmpty,
6896 parse_msg_cursor_set,
6897 parse_msg_cursor_move,
6898 parse_SpiceMsgEmpty,
6899 parse_msg_cursor_trail,
6900 parse_msg_cursor_inval_one,
6901 parse_SpiceMsgEmpty
6902 };
6903 if (message_type >= 1 && message_type < 9) {
6904 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
6905 } else if (message_type >= 100 && message_type < 109) {
6906 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
6907 }
6908 return NULL;
6909 }
6910
6911
6912
parse_msg_playback_data(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6913 static uint8_t * parse_msg_playback_data(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6914 {
6915 SPICE_GNUC_UNUSED uint8_t *pos;
6916 uint8_t *start = message_start;
6917 uint8_t *data = NULL;
6918 uint64_t nw_size;
6919 uint64_t mem_size;
6920 uint8_t *in, *end;
6921 uint64_t data__nw_size;
6922 uint64_t data__nelements;
6923 SpiceMsgPlaybackPacket *out;
6924
6925 { /* data */
6926 if (SPICE_UNLIKELY((start + 4) > message_end)) {
6927 goto error;
6928 }
6929 data__nelements = message_end - (start + 4);
6930
6931 data__nw_size = data__nelements;
6932 }
6933
6934 nw_size = 4 + data__nw_size;
6935 mem_size = sizeof(SpiceMsgPlaybackPacket);
6936
6937 /* Check if message fits in reported side */
6938 if (nw_size > (uintptr_t) (message_end - start)) {
6939 return NULL;
6940 }
6941
6942 /* Validated extents and calculated size */
6943 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
6944 if (SPICE_UNLIKELY(data == NULL)) {
6945 goto error;
6946 }
6947 end = data + sizeof(SpiceMsgPlaybackPacket);
6948 in = start;
6949
6950 out = (SpiceMsgPlaybackPacket *)data;
6951
6952 out->time = consume_uint32(&in);
6953 /* use array as pointer */
6954 out->data = (uint8_t *)in;
6955 out->data_size = data__nelements;
6956 in += data__nelements;
6957
6958 assert(in <= message_end);
6959 assert(end <= data + mem_size);
6960
6961 *size = end - data;
6962 *free_message = (message_destructor_t) free;
6963 return data;
6964
6965 error:
6966 free(data);
6967 return NULL;
6968 }
6969
parse_msg_playback_mode(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)6970 static uint8_t * parse_msg_playback_mode(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
6971 {
6972 SPICE_GNUC_UNUSED uint8_t *pos;
6973 uint8_t *start = message_start;
6974 uint8_t *data = NULL;
6975 uint64_t nw_size;
6976 uint64_t mem_size;
6977 uint8_t *in, *end;
6978 uint64_t data__nw_size;
6979 uint64_t data__nelements;
6980 SpiceMsgPlaybackMode *out;
6981
6982 { /* data */
6983 if (SPICE_UNLIKELY((start + 6) > message_end)) {
6984 goto error;
6985 }
6986 data__nelements = message_end - (start + 6);
6987
6988 data__nw_size = data__nelements;
6989 }
6990
6991 nw_size = 6 + data__nw_size;
6992 mem_size = sizeof(SpiceMsgPlaybackMode);
6993
6994 /* Check if message fits in reported side */
6995 if (nw_size > (uintptr_t) (message_end - start)) {
6996 return NULL;
6997 }
6998
6999 /* Validated extents and calculated size */
7000 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7001 if (SPICE_UNLIKELY(data == NULL)) {
7002 goto error;
7003 }
7004 end = data + sizeof(SpiceMsgPlaybackMode);
7005 in = start;
7006
7007 out = (SpiceMsgPlaybackMode *)data;
7008
7009 out->time = consume_uint32(&in);
7010 out->mode = consume_uint16(&in);
7011 /* use array as pointer */
7012 out->data = (uint8_t *)in;
7013 out->data_size = data__nelements;
7014 in += data__nelements;
7015
7016 assert(in <= message_end);
7017 assert(end <= data + mem_size);
7018
7019 *size = end - data;
7020 *free_message = (message_destructor_t) free;
7021 return data;
7022
7023 error:
7024 free(data);
7025 return NULL;
7026 }
7027
parse_msg_playback_start(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7028 static uint8_t * parse_msg_playback_start(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7029 {
7030 SPICE_GNUC_UNUSED uint8_t *pos;
7031 uint8_t *start = message_start;
7032 uint8_t *data = NULL;
7033 uint64_t nw_size;
7034 uint64_t mem_size;
7035 uint8_t *in, *end;
7036 SpiceMsgPlaybackStart *out;
7037
7038 nw_size = 14;
7039 mem_size = sizeof(SpiceMsgPlaybackStart);
7040
7041 /* Check if message fits in reported side */
7042 if (nw_size > (uintptr_t) (message_end - start)) {
7043 return NULL;
7044 }
7045
7046 /* Validated extents and calculated size */
7047 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7048 if (SPICE_UNLIKELY(data == NULL)) {
7049 goto error;
7050 }
7051 end = data + sizeof(SpiceMsgPlaybackStart);
7052 in = start;
7053
7054 out = (SpiceMsgPlaybackStart *)data;
7055
7056 out->channels = consume_uint32(&in);
7057 out->format = consume_uint16(&in);
7058 out->frequency = consume_uint32(&in);
7059 out->time = consume_uint32(&in);
7060
7061 assert(in <= message_end);
7062 assert(end <= data + mem_size);
7063
7064 *size = end - data;
7065 *free_message = (message_destructor_t) free;
7066 return data;
7067
7068 error:
7069 free(data);
7070 return NULL;
7071 }
7072
parse_SpiceMsgAudioVolume(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7073 static uint8_t * parse_SpiceMsgAudioVolume(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7074 {
7075 SPICE_GNUC_UNUSED uint8_t *pos;
7076 uint8_t *start = message_start;
7077 uint8_t *data = NULL;
7078 uint64_t nw_size;
7079 uint64_t mem_size;
7080 uint8_t *in, *end;
7081 uint64_t volume__nw_size, volume__mem_size;
7082 uint64_t volume__nelements;
7083 SpiceMsgAudioVolume *out;
7084 uint32_t i;
7085
7086 { /* volume */
7087 uint8_t nchannels__value;
7088 pos = start + 0;
7089 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
7090 goto error;
7091 }
7092 nchannels__value = read_uint8(pos);
7093 volume__nelements = nchannels__value;
7094
7095 volume__nw_size = (2) * volume__nelements;
7096 volume__mem_size = sizeof(uint16_t) * volume__nelements;
7097 }
7098
7099 nw_size = 1 + volume__nw_size;
7100 mem_size = sizeof(SpiceMsgAudioVolume) + volume__mem_size;
7101
7102 /* Check if message fits in reported side */
7103 if (nw_size > (uintptr_t) (message_end - start)) {
7104 return NULL;
7105 }
7106
7107 /* Validated extents and calculated size */
7108 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7109 if (SPICE_UNLIKELY(data == NULL)) {
7110 goto error;
7111 }
7112 end = data + sizeof(SpiceMsgAudioVolume);
7113 in = start;
7114
7115 out = (SpiceMsgAudioVolume *)data;
7116
7117 out->nchannels = consume_uint8(&in);
7118 for (i = 0; i < volume__nelements; i++) {
7119 out->volume[i] = consume_uint16(&in);
7120 end += sizeof(uint16_t);
7121 }
7122
7123 assert(in <= message_end);
7124 assert(end <= data + mem_size);
7125
7126 *size = end - data;
7127 *free_message = (message_destructor_t) free;
7128 return data;
7129
7130 error:
7131 free(data);
7132 return NULL;
7133 }
7134
parse_SpiceMsgAudioMute(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7135 static uint8_t * parse_SpiceMsgAudioMute(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7136 {
7137 SPICE_GNUC_UNUSED uint8_t *pos;
7138 uint8_t *start = message_start;
7139 uint8_t *data = NULL;
7140 uint64_t nw_size;
7141 uint64_t mem_size;
7142 uint8_t *in, *end;
7143 SpiceMsgAudioMute *out;
7144
7145 nw_size = 1;
7146 mem_size = sizeof(SpiceMsgAudioMute);
7147
7148 /* Check if message fits in reported side */
7149 if (nw_size > (uintptr_t) (message_end - start)) {
7150 return NULL;
7151 }
7152
7153 /* Validated extents and calculated size */
7154 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7155 if (SPICE_UNLIKELY(data == NULL)) {
7156 goto error;
7157 }
7158 end = data + sizeof(SpiceMsgAudioMute);
7159 in = start;
7160
7161 out = (SpiceMsgAudioMute *)data;
7162
7163 out->mute = consume_uint8(&in);
7164
7165 assert(in <= message_end);
7166 assert(end <= data + mem_size);
7167
7168 *size = end - data;
7169 *free_message = (message_destructor_t) free;
7170 return data;
7171
7172 error:
7173 free(data);
7174 return NULL;
7175 }
7176
parse_msg_playback_latency(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7177 static uint8_t * parse_msg_playback_latency(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7178 {
7179 SPICE_GNUC_UNUSED uint8_t *pos;
7180 uint8_t *start = message_start;
7181 uint8_t *data = NULL;
7182 uint64_t nw_size;
7183 uint64_t mem_size;
7184 uint8_t *in, *end;
7185 SpiceMsgPlaybackLatency *out;
7186
7187 nw_size = 4;
7188 mem_size = sizeof(SpiceMsgPlaybackLatency);
7189
7190 /* Check if message fits in reported side */
7191 if (nw_size > (uintptr_t) (message_end - start)) {
7192 return NULL;
7193 }
7194
7195 /* Validated extents and calculated size */
7196 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7197 if (SPICE_UNLIKELY(data == NULL)) {
7198 goto error;
7199 }
7200 end = data + sizeof(SpiceMsgPlaybackLatency);
7201 in = start;
7202
7203 out = (SpiceMsgPlaybackLatency *)data;
7204
7205 out->latency_ms = consume_uint32(&in);
7206
7207 assert(in <= message_end);
7208 assert(end <= data + mem_size);
7209
7210 *size = end - data;
7211 *free_message = (message_destructor_t) free;
7212 return data;
7213
7214 error:
7215 free(data);
7216 return NULL;
7217 }
7218
parse_PlaybackChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)7219 static uint8_t * parse_PlaybackChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
7220 {
7221 static parse_msg_func_t funcs1[8] = {
7222 parse_msg_migrate,
7223 parse_SpiceMsgData,
7224 parse_msg_set_ack,
7225 parse_msg_ping,
7226 parse_msg_wait_for_channels,
7227 parse_msg_disconnecting,
7228 parse_msg_notify,
7229 parse_SpiceMsgData
7230 };
7231 static parse_msg_func_t funcs2[8] = {
7232 parse_SpiceMsgEmpty,
7233 parse_msg_playback_data,
7234 parse_msg_playback_mode,
7235 parse_msg_playback_start,
7236 parse_SpiceMsgEmpty,
7237 parse_SpiceMsgAudioVolume,
7238 parse_SpiceMsgAudioMute,
7239 parse_msg_playback_latency
7240 };
7241 if (message_type >= 1 && message_type < 9) {
7242 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
7243 } else if (message_type >= 100 && message_type < 108) {
7244 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
7245 }
7246 return NULL;
7247 }
7248
7249
7250
parse_msg_record_start(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7251 static uint8_t * parse_msg_record_start(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7252 {
7253 SPICE_GNUC_UNUSED uint8_t *pos;
7254 uint8_t *start = message_start;
7255 uint8_t *data = NULL;
7256 uint64_t nw_size;
7257 uint64_t mem_size;
7258 uint8_t *in, *end;
7259 SpiceMsgRecordStart *out;
7260
7261 nw_size = 10;
7262 mem_size = sizeof(SpiceMsgRecordStart);
7263
7264 /* Check if message fits in reported side */
7265 if (nw_size > (uintptr_t) (message_end - start)) {
7266 return NULL;
7267 }
7268
7269 /* Validated extents and calculated size */
7270 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7271 if (SPICE_UNLIKELY(data == NULL)) {
7272 goto error;
7273 }
7274 end = data + sizeof(SpiceMsgRecordStart);
7275 in = start;
7276
7277 out = (SpiceMsgRecordStart *)data;
7278
7279 out->channels = consume_uint32(&in);
7280 out->format = consume_uint16(&in);
7281 out->frequency = consume_uint32(&in);
7282
7283 assert(in <= message_end);
7284 assert(end <= data + mem_size);
7285
7286 *size = end - data;
7287 *free_message = (message_destructor_t) free;
7288 return data;
7289
7290 error:
7291 free(data);
7292 return NULL;
7293 }
7294
parse_RecordChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)7295 static uint8_t * parse_RecordChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
7296 {
7297 static parse_msg_func_t funcs1[8] = {
7298 parse_msg_migrate,
7299 parse_SpiceMsgData,
7300 parse_msg_set_ack,
7301 parse_msg_ping,
7302 parse_msg_wait_for_channels,
7303 parse_msg_disconnecting,
7304 parse_msg_notify,
7305 parse_SpiceMsgData
7306 };
7307 static parse_msg_func_t funcs2[5] = {
7308 parse_SpiceMsgEmpty,
7309 parse_msg_record_start,
7310 parse_SpiceMsgEmpty,
7311 parse_SpiceMsgAudioVolume,
7312 parse_SpiceMsgAudioMute
7313 };
7314 if (message_type >= 1 && message_type < 9) {
7315 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
7316 } else if (message_type >= 100 && message_type < 105) {
7317 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
7318 }
7319 return NULL;
7320 }
7321
7322
7323
parse_TunnelChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)7324 static uint8_t * parse_TunnelChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
7325 {
7326
7327 return NULL;
7328 }
7329
7330
7331 #ifdef USE_SMARTCARD
7332
parse_msg_smartcard_data(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7333 static uint8_t * parse_msg_smartcard_data(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7334 {
7335 SPICE_GNUC_UNUSED uint8_t *pos;
7336 uint8_t *start = message_start;
7337 uint8_t *data = NULL;
7338 uint64_t nw_size;
7339 uint64_t mem_size;
7340 uint8_t *in, *end;
7341 uint64_t data__nw_size, data__mem_size;
7342 uint64_t data__nelements;
7343 SpiceMsgSmartcard *out;
7344
7345 { /* data */
7346 uint32_t length__value;
7347 pos = start + 8;
7348 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
7349 goto error;
7350 }
7351 length__value = read_uint32(pos);
7352 data__nelements = length__value;
7353
7354 data__nw_size = data__nelements;
7355 data__mem_size = sizeof(uint8_t) * data__nelements;
7356 }
7357
7358 nw_size = 12 + data__nw_size;
7359 mem_size = sizeof(SpiceMsgSmartcard) + data__mem_size;
7360
7361 /* Check if message fits in reported side */
7362 if (nw_size > (uintptr_t) (message_end - start)) {
7363 return NULL;
7364 }
7365
7366 /* Validated extents and calculated size */
7367 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7368 if (SPICE_UNLIKELY(data == NULL)) {
7369 goto error;
7370 }
7371 end = data + sizeof(SpiceMsgSmartcard);
7372 in = start;
7373
7374 out = (SpiceMsgSmartcard *)data;
7375
7376 out->type = consume_uint32(&in);
7377 out->reader_id = consume_uint32(&in);
7378 out->length = consume_uint32(&in);
7379 memcpy(out->data, in, data__nelements);
7380 in += data__nelements;
7381 end += data__nelements;
7382
7383 assert(in <= message_end);
7384 assert(end <= data + mem_size);
7385
7386 *size = end - data;
7387 *free_message = (message_destructor_t) free;
7388 return data;
7389
7390 error:
7391 free(data);
7392 return NULL;
7393 }
7394
parse_SmartcardChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)7395 static uint8_t * parse_SmartcardChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
7396 {
7397 static parse_msg_func_t funcs1[8] = {
7398 parse_msg_migrate,
7399 parse_SpiceMsgData,
7400 parse_msg_set_ack,
7401 parse_msg_ping,
7402 parse_msg_wait_for_channels,
7403 parse_msg_disconnecting,
7404 parse_msg_notify,
7405 parse_SpiceMsgData
7406 };
7407 static parse_msg_func_t funcs2[2] = {
7408 parse_SpiceMsgEmpty,
7409 parse_msg_smartcard_data
7410 };
7411 if (message_type >= 1 && message_type < 9) {
7412 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
7413 } else if (message_type >= 100 && message_type < 102) {
7414 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
7415 }
7416 return NULL;
7417 }
7418 #endif /* USE_SMARTCARD */
7419
7420
7421
parse_SpiceMsgCompressedData(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7422 static uint8_t * parse_SpiceMsgCompressedData(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7423 {
7424 SPICE_GNUC_UNUSED uint8_t *pos;
7425 uint8_t *start = message_start;
7426 uint8_t *data = NULL;
7427 uint64_t nw_size;
7428 uint64_t mem_size;
7429 uint8_t *in, *end;
7430 uint64_t u__nw_size;
7431 uint8_t type__value;
7432 uint64_t compressed_data__nw_size;
7433 uint64_t compressed_data__nelements;
7434 SpiceMsgCompressedData *out;
7435
7436 { /* u */
7437 pos = start + 0;
7438 if (SPICE_UNLIKELY(pos + 1 > message_end)) {
7439 goto error;
7440 }
7441 type__value = read_uint8(pos);
7442 if (type__value == SPICE_DATA_COMPRESSION_TYPE_NONE) {
7443 SPICE_GNUC_UNUSED uint8_t *start2 = (start + 1);
7444 u__nw_size = 0;
7445 } else if (1) {
7446 u__nw_size = 4;
7447 } else {
7448 u__nw_size = 0;
7449 }
7450
7451 }
7452
7453 { /* compressed_data */
7454 if (SPICE_UNLIKELY((start + 1 + u__nw_size) > message_end)) {
7455 goto error;
7456 }
7457 compressed_data__nelements = message_end - (start + 1 + u__nw_size);
7458
7459 compressed_data__nw_size = compressed_data__nelements;
7460 }
7461
7462 nw_size = 1 + u__nw_size + compressed_data__nw_size;
7463 mem_size = sizeof(SpiceMsgCompressedData);
7464
7465 /* Check if message fits in reported side */
7466 if (nw_size > (uintptr_t) (message_end - start)) {
7467 return NULL;
7468 }
7469
7470 /* Validated extents and calculated size */
7471 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7472 if (SPICE_UNLIKELY(data == NULL)) {
7473 goto error;
7474 }
7475 end = data + sizeof(SpiceMsgCompressedData);
7476 in = start;
7477
7478 out = (SpiceMsgCompressedData *)data;
7479
7480 out->type = consume_uint8(&in);
7481 if (out->type == SPICE_DATA_COMPRESSION_TYPE_NONE) {
7482 } else if (1) {
7483 out->uncompressed_size = consume_uint32(&in);
7484 }
7485 /* use array as pointer */
7486 out->compressed_data = (uint8_t *)in;
7487 out->compressed_size = compressed_data__nelements;
7488 in += compressed_data__nelements;
7489
7490 assert(in <= message_end);
7491 assert(end <= data + mem_size);
7492
7493 *size = end - data;
7494 *free_message = (message_destructor_t) free;
7495 return data;
7496
7497 error:
7498 free(data);
7499 return NULL;
7500 }
7501
parse_UsbredirChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)7502 static uint8_t * parse_UsbredirChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
7503 {
7504 static parse_msg_func_t funcs1[8] = {
7505 parse_msg_migrate,
7506 parse_SpiceMsgData,
7507 parse_msg_set_ack,
7508 parse_msg_ping,
7509 parse_msg_wait_for_channels,
7510 parse_msg_disconnecting,
7511 parse_msg_notify,
7512 parse_SpiceMsgData
7513 };
7514 static parse_msg_func_t funcs2[3] = {
7515 parse_SpiceMsgEmpty,
7516 parse_SpiceMsgData,
7517 parse_SpiceMsgCompressedData
7518 };
7519 if (message_type >= 1 && message_type < 9) {
7520 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
7521 } else if (message_type >= 100 && message_type < 103) {
7522 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
7523 }
7524 return NULL;
7525 }
7526
7527
7528
parse_msg_port_init(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7529 static uint8_t * parse_msg_port_init(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7530 {
7531 SPICE_GNUC_UNUSED uint8_t *pos;
7532 uint8_t *start = message_start;
7533 uint8_t *data = NULL;
7534 uint64_t nw_size;
7535 uint64_t mem_size;
7536 uint8_t *in, *end;
7537 SPICE_GNUC_UNUSED intptr_t ptr_size;
7538 uint32_t n_ptr=0;
7539 PointerInfo ptr_info[1];
7540 uint64_t name__extra_size;
7541 uint64_t name__array__nelements;
7542 SpiceMsgPortInit *out;
7543 uint32_t i;
7544
7545 { /* name */
7546 uint32_t name__value;
7547 uint64_t name__array__nw_size;
7548 uint64_t name__array__mem_size;
7549 uint32_t name_size__value;
7550 pos = (start + 4);
7551 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
7552 goto error;
7553 }
7554 name__value = read_uint32(pos);
7555 if (SPICE_UNLIKELY(name__value == 0)) {
7556 goto error;
7557 }
7558 if (SPICE_UNLIKELY(name__value >= (uintptr_t) (message_end - message_start))) {
7559 goto error;
7560 }
7561 pos = start + 0;
7562 if (SPICE_UNLIKELY(pos + 4 > message_end)) {
7563 goto error;
7564 }
7565 name_size__value = read_uint32(pos);
7566 name__array__nelements = name_size__value;
7567
7568 name__array__nw_size = name__array__nelements;
7569 name__array__mem_size = sizeof(uint8_t) * name__array__nelements;
7570 if (SPICE_UNLIKELY(name__value + name__array__nw_size > (uintptr_t) (message_end - message_start))) {
7571 goto error;
7572 }
7573 name__extra_size = name__array__mem_size + /* for alignment */ 3;
7574 }
7575
7576 nw_size = 9;
7577 mem_size = sizeof(SpiceMsgPortInit) + name__extra_size;
7578
7579 /* Check if message fits in reported side */
7580 if (nw_size > (uintptr_t) (message_end - start)) {
7581 return NULL;
7582 }
7583
7584 /* Validated extents and calculated size */
7585 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7586 if (SPICE_UNLIKELY(data == NULL)) {
7587 goto error;
7588 }
7589 end = data + sizeof(SpiceMsgPortInit);
7590 in = start;
7591
7592 out = (SpiceMsgPortInit *)data;
7593
7594 out->name_size = consume_uint32(&in);
7595 ptr_info[n_ptr].offset = consume_uint32(&in);
7596 ptr_info[n_ptr].parse = parse_array_uint8;
7597 ptr_info[n_ptr].dest = (void **)&out->name;
7598 ptr_info[n_ptr].nelements = name__array__nelements;
7599 n_ptr++;
7600 out->opened = consume_uint8(&in);
7601
7602 assert(in <= message_end);
7603
7604 for (i = 0; i < n_ptr; i++) {
7605 if (ptr_info[i].offset == 0) {
7606 *ptr_info[i].dest = NULL;
7607 } else {
7608 /* Align to 32 bit */
7609 end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
7610 *ptr_info[i].dest = (void *)end;
7611 end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
7612 if (SPICE_UNLIKELY(end == NULL)) {
7613 goto error;
7614 }
7615 }
7616 }
7617
7618 assert(end <= data + mem_size);
7619
7620 *size = end - data;
7621 *free_message = (message_destructor_t) free;
7622 return data;
7623
7624 error:
7625 free(data);
7626 return NULL;
7627 }
7628
parse_msg_port_event(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)7629 static uint8_t * parse_msg_port_event(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
7630 {
7631 SPICE_GNUC_UNUSED uint8_t *pos;
7632 uint8_t *start = message_start;
7633 uint8_t *data = NULL;
7634 uint64_t nw_size;
7635 uint64_t mem_size;
7636 uint8_t *in, *end;
7637 SpiceMsgPortEvent *out;
7638
7639 nw_size = 1;
7640 mem_size = sizeof(SpiceMsgPortEvent);
7641
7642 /* Check if message fits in reported side */
7643 if (nw_size > (uintptr_t) (message_end - start)) {
7644 return NULL;
7645 }
7646
7647 /* Validated extents and calculated size */
7648 data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
7649 if (SPICE_UNLIKELY(data == NULL)) {
7650 goto error;
7651 }
7652 end = data + sizeof(SpiceMsgPortEvent);
7653 in = start;
7654
7655 out = (SpiceMsgPortEvent *)data;
7656
7657 out->event = consume_uint8(&in);
7658
7659 assert(in <= message_end);
7660 assert(end <= data + mem_size);
7661
7662 *size = end - data;
7663 *free_message = (message_destructor_t) free;
7664 return data;
7665
7666 error:
7667 free(data);
7668 return NULL;
7669 }
7670
parse_PortChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)7671 static uint8_t * parse_PortChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
7672 {
7673 static parse_msg_func_t funcs1[8] = {
7674 parse_msg_migrate,
7675 parse_SpiceMsgData,
7676 parse_msg_set_ack,
7677 parse_msg_ping,
7678 parse_msg_wait_for_channels,
7679 parse_msg_disconnecting,
7680 parse_msg_notify,
7681 parse_SpiceMsgData
7682 };
7683 static parse_msg_func_t funcs2[3] = {
7684 parse_SpiceMsgEmpty,
7685 parse_SpiceMsgData,
7686 parse_SpiceMsgCompressedData
7687 };
7688 static parse_msg_func_t funcs3[2] = {
7689 parse_msg_port_init,
7690 parse_msg_port_event
7691 };
7692 if (message_type >= 1 && message_type < 9) {
7693 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
7694 } else if (message_type >= 100 && message_type < 103) {
7695 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
7696 } else if (message_type >= 201 && message_type < 203) {
7697 return funcs3[message_type-201](message_start, message_end, size_out, free_message);
7698 }
7699 return NULL;
7700 }
7701
7702
7703
parse_WebDAVChannel_msg(uint8_t * message_start,uint8_t * message_end,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)7704 static uint8_t * parse_WebDAVChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
7705 {
7706 static parse_msg_func_t funcs1[8] = {
7707 parse_msg_migrate,
7708 parse_SpiceMsgData,
7709 parse_msg_set_ack,
7710 parse_msg_ping,
7711 parse_msg_wait_for_channels,
7712 parse_msg_disconnecting,
7713 parse_msg_notify,
7714 parse_SpiceMsgData
7715 };
7716 static parse_msg_func_t funcs2[3] = {
7717 parse_SpiceMsgEmpty,
7718 parse_SpiceMsgData,
7719 parse_SpiceMsgCompressedData
7720 };
7721 static parse_msg_func_t funcs3[2] = {
7722 parse_msg_port_init,
7723 parse_msg_port_event
7724 };
7725 if (message_type >= 1 && message_type < 9) {
7726 return funcs1[message_type-1](message_start, message_end, size_out, free_message);
7727 } else if (message_type >= 100 && message_type < 103) {
7728 return funcs2[message_type-100](message_start, message_end, size_out, free_message);
7729 } else if (message_type >= 201 && message_type < 203) {
7730 return funcs3[message_type-201](message_start, message_end, size_out, free_message);
7731 }
7732 return NULL;
7733 }
7734
spice_get_server_channel_parser(uint32_t channel,unsigned int * max_message_type)7735 spice_parse_channel_func_t spice_get_server_channel_parser(uint32_t channel, unsigned int *max_message_type)
7736 {
7737 static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[12] = {
7738 { NULL, 0 },
7739 { parse_MainChannel_msg, 118},
7740 { parse_DisplayChannel_msg, 321},
7741 { parse_InputsChannel_msg, 111},
7742 { parse_CursorChannel_msg, 108},
7743 { parse_PlaybackChannel_msg, 107},
7744 { parse_RecordChannel_msg, 104},
7745 { parse_TunnelChannel_msg, 0},
7746 #ifdef USE_SMARTCARD
7747 { parse_SmartcardChannel_msg, 101},
7748 #else /* USE_SMARTCARD */
7749 { NULL, 0 },
7750 #endif /* USE_SMARTCARD */
7751 { parse_UsbredirChannel_msg, 102},
7752 { parse_PortChannel_msg, 202},
7753 { parse_WebDAVChannel_msg, 202}
7754 };
7755 if (channel < 12) {
7756 if (max_message_type != NULL) {
7757 *max_message_type = channels[channel].max_messages;
7758 }
7759 return channels[channel].func;
7760 }
7761 return NULL;
7762 }
7763
spice_parse_msg(uint8_t * message_start,uint8_t * message_end,uint32_t channel,uint16_t message_type,SPICE_GNUC_UNUSED int minor,size_t * size_out,message_destructor_t * free_message)7764 uint8_t * spice_parse_msg(uint8_t *message_start, uint8_t *message_end, uint32_t channel, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
7765 {
7766 spice_parse_channel_func_t func;
7767 func = spice_get_server_channel_parser(channel, NULL);
7768 if (func != NULL) {
7769 return func(message_start, message_end, message_type, minor, size_out, free_message);
7770 }
7771 return NULL;
7772 }
7773