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 #include <config.h>
20 #include "test-marshallers.h"
21 #include <string.h>
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <spice/protocol.h>
26 #include <spice/macros.h>
27 #include <common/mem.h>
28 #include <common/demarshallers.h>
29 
30 #ifdef _MSC_VER
31 #pragma warning(disable:4101)
32 #endif
33 
34 
35 
36 #include <spice/start-packed.h>
37 typedef struct SPICE_ATTR_PACKED {
38     int16_t v;
39 } int16_unaligned_t;
40 typedef struct SPICE_ATTR_PACKED {
41     uint16_t v;
42 } uint16_unaligned_t;
43 typedef struct SPICE_ATTR_PACKED {
44     int32_t v;
45 } int32_unaligned_t;
46 typedef struct SPICE_ATTR_PACKED {
47     uint32_t v;
48 } uint32_unaligned_t;
49 typedef struct SPICE_ATTR_PACKED {
50     int64_t v;
51 } int64_unaligned_t;
52 typedef struct SPICE_ATTR_PACKED {
53     uint64_t v;
54 } uint64_unaligned_t;
55 #include <spice/end-packed.h>
56 
57 #define read_int8(ptr) (*((int8_t *)(ptr)))
58 #define write_int8(ptr, val) *(int8_t *)(ptr) = val
59 #define read_uint8(ptr) (*((uint8_t *)(ptr)))
60 #define write_uint8(ptr, val) *(uint8_t *)(ptr) = val
61 
62 #ifdef WORDS_BIGENDIAN
63 #define read_int16(ptr) ((int16_t)SPICE_BYTESWAP16(((uint16_unaligned_t *)(ptr))->v))
64 #define write_int16(ptr, val) ((uint16_unaligned_t *)(ptr))->v = SPICE_BYTESWAP16((uint16_t)val)
65 #define read_uint16(ptr) ((uint16_t)SPICE_BYTESWAP16(((uint16_unaligned_t *)(ptr))->v))
66 #define write_uint16(ptr, val) ((uint16_unaligned_t *)(ptr))->v = SPICE_BYTESWAP16((uint16_t)val)
67 #define read_int32(ptr) ((int32_t)SPICE_BYTESWAP32(((uint32_unaligned_t *)(ptr))->v))
68 #define write_int32(ptr, val) ((uint32_unaligned_t *)(ptr))->v = SPICE_BYTESWAP32((uint32_t)val)
69 #define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(((uint32_unaligned_t *)(ptr))->v))
70 #define write_uint32(ptr, val) ((uint32_unaligned_t *)(ptr))->v = SPICE_BYTESWAP32((uint32_t)val)
71 #define read_int64(ptr) ((int64_t)SPICE_BYTESWAP64(((uint64_unaligned_t *)(ptr))->v))
72 #define write_int64(ptr, val) ((uint64_unaligned_t *)(ptr))->v = SPICE_BYTESWAP64((uint64_t)val)
73 #define read_uint64(ptr) ((uint64_t)SPICE_BYTESWAP64(((uint64_unaligned_t *)(ptr))->v))
74 #define write_uint64(ptr, val) ((uint64_unaligned_t *)(ptr))->v = SPICE_BYTESWAP64((uint64_t)val)
75 #else
76 #define read_int16(ptr) (((int16_unaligned_t *)(ptr))->v)
77 #define write_int16(ptr, val) (((int16_unaligned_t *)(ptr))->v) = val
78 #define read_uint16(ptr) (((uint16_unaligned_t *)(ptr))->v)
79 #define write_uint16(ptr, val) (((uint16_unaligned_t *)(ptr))->v) = val
80 #define read_int32(ptr) (((int32_unaligned_t *)(ptr))->v)
81 #define write_int32(ptr, val) (((int32_unaligned_t *)(ptr))->v) = val
82 #define read_uint32(ptr) (((uint32_unaligned_t *)(ptr))->v)
83 #define write_uint32(ptr, val) (((uint32_unaligned_t *)(ptr))->v) = val
84 #define read_int64(ptr) (((int64_unaligned_t *)(ptr))->v)
85 #define write_int64(ptr, val) (((int64_unaligned_t *)(ptr))->v) = val
86 #define read_uint64(ptr) (((uint64_unaligned_t *)(ptr))->v)
87 #define write_uint64(ptr, val) (((uint64_unaligned_t *)(ptr))->v) = val
88 #endif
89 
consume_int8(uint8_t ** ptr)90 static int8_t SPICE_GNUC_UNUSED consume_int8(uint8_t **ptr)
91 {
92     int8_t val;
93     val = read_int8(*ptr);
94     *ptr += 1;
95     return val;
96 }
97 
consume_uint8(uint8_t ** ptr)98 static uint8_t SPICE_GNUC_UNUSED consume_uint8(uint8_t **ptr)
99 {
100     uint8_t val;
101     val = read_uint8(*ptr);
102     *ptr += 1;
103     return val;
104 }
105 
consume_int16(uint8_t ** ptr)106 static int16_t SPICE_GNUC_UNUSED consume_int16(uint8_t **ptr)
107 {
108     int16_t val;
109     val = read_int16(*ptr);
110     *ptr += 2;
111     return val;
112 }
113 
consume_uint16(uint8_t ** ptr)114 static uint16_t SPICE_GNUC_UNUSED consume_uint16(uint8_t **ptr)
115 {
116     uint16_t val;
117     val = read_uint16(*ptr);
118     *ptr += 2;
119     return val;
120 }
121 
consume_int32(uint8_t ** ptr)122 static int32_t SPICE_GNUC_UNUSED consume_int32(uint8_t **ptr)
123 {
124     int32_t val;
125     val = read_int32(*ptr);
126     *ptr += 4;
127     return val;
128 }
129 
consume_uint32(uint8_t ** ptr)130 static uint32_t SPICE_GNUC_UNUSED consume_uint32(uint8_t **ptr)
131 {
132     uint32_t val;
133     val = read_uint32(*ptr);
134     *ptr += 4;
135     return val;
136 }
137 
consume_int64(uint8_t ** ptr)138 static int64_t SPICE_GNUC_UNUSED consume_int64(uint8_t **ptr)
139 {
140     int64_t val;
141     val = read_int64(*ptr);
142     *ptr += 8;
143     return val;
144 }
145 
consume_uint64(uint8_t ** ptr)146 static uint64_t SPICE_GNUC_UNUSED consume_uint64(uint8_t **ptr)
147 {
148     uint64_t val;
149     val = read_uint64(*ptr);
150     *ptr += 8;
151     return val;
152 }
consume_fd(uint8_t ** ptr SPICE_GNUC_UNUSED)153 static int SPICE_GNUC_UNUSED consume_fd(uint8_t **ptr SPICE_GNUC_UNUSED)
154 {
155     return -1;
156 }
157 
158 typedef struct PointerInfo PointerInfo;
159 typedef void (*message_destructor_t)(uint8_t *message);
160 typedef uint8_t * (*parse_func_t)(uint8_t *message_start, uint8_t *message_end, uint8_t *struct_data, PointerInfo *ptr_info);
161 typedef uint8_t * (*parse_msg_func_t)(uint8_t *message_start, uint8_t *message_end, size_t *size_out, message_destructor_t *free_message);
162 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);
163 
164 struct PointerInfo {
165     uint64_t offset;
166     parse_func_t parse;
167     void * *dest;
168     uint64_t nelements;
169 };
170 
parse_array_uint64(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)171 static uint8_t * parse_array_uint64(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
172 {
173     uint8_t *in = message_start + this_ptr_info->offset;
174     uint8_t *end;
175     uint32_t i;
176 
177     end = struct_data;
178     for (i = 0; i < this_ptr_info->nelements; i++) {
179         *(uint64_t *)end = consume_uint64(&in);
180         end += sizeof(uint64_t);
181     }
182     return end;
183 }
184 
parse_msg_main_ShortDataSubMarshall(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)185 static uint8_t * parse_msg_main_ShortDataSubMarshall(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
186 {
187     SPICE_GNUC_UNUSED uint8_t *pos;
188     uint8_t *start = message_start;
189     uint8_t *data = NULL;
190     uint64_t nw_size;
191     uint64_t mem_size;
192     uint8_t *in, *end;
193     SPICE_GNUC_UNUSED intptr_t ptr_size;
194     uint32_t n_ptr=0;
195     PointerInfo ptr_info[1];
196     uint64_t data__extra_size;
197     uint64_t data__array__nelements;
198     SpiceMsgMainShortDataSubMarshall *out;
199     uint32_t i;
200 
201     { /* data */
202         uint32_t data__value;
203         uint64_t data__array__nw_size;
204         uint64_t data__array__mem_size;
205         uint32_t data_size__value;
206         pos = (start + 5);
207         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
208             goto error;
209         }
210         data__value = read_uint32(pos);
211         if (SPICE_UNLIKELY(data__value >= (uintptr_t) (message_end - message_start))) {
212             goto error;
213         }
214         pos = start + 1;
215         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
216             goto error;
217         }
218         data_size__value = read_uint32(pos);
219         data__array__nelements = data_size__value;
220 
221         data__array__nw_size = (8) * data__array__nelements;
222         data__array__mem_size = sizeof(uint64_t) * data__array__nelements;
223         if (SPICE_UNLIKELY(data__array__nw_size > (uintptr_t) (message_end - message_start - data__value))) {
224             goto error;
225         }
226         data__extra_size = data__array__mem_size + /* for alignment */ 3;
227     }
228 
229     nw_size = 9;
230     mem_size = sizeof(SpiceMsgMainShortDataSubMarshall) + data__extra_size;
231 
232     /* Check if message fits in reported side */
233     if (nw_size > (uintptr_t) (message_end - start)) {
234         return NULL;
235     }
236 
237     /* Validated extents and calculated size */
238     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
239     if (SPICE_UNLIKELY(data == NULL)) {
240         goto error;
241     }
242     end = data + sizeof(SpiceMsgMainShortDataSubMarshall);
243     in = start;
244 
245     out = (SpiceMsgMainShortDataSubMarshall *)data;
246 
247     out->dummy_byte = consume_uint8(&in);
248     out->data_size = consume_uint32(&in);
249     ptr_info[n_ptr].offset = consume_uint32(&in);
250     ptr_info[n_ptr].parse = parse_array_uint64;
251     ptr_info[n_ptr].dest = (void **)&out->data;
252     ptr_info[n_ptr].nelements = data__array__nelements;
253     n_ptr++;
254 
255     assert(in <= message_end);
256 
257     for (i = 0; i < n_ptr; i++) {
258         if (ptr_info[i].offset == 0) {
259             *ptr_info[i].dest = NULL;
260         } else {
261             /* Align to 32 bit */
262             end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
263             *ptr_info[i].dest = (void *)end;
264             end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
265             if (SPICE_UNLIKELY(end == NULL)) {
266                 goto error;
267             }
268         }
269     }
270 
271     assert(end <= data + mem_size);
272 
273     *size = end - data;
274     *free_message = (message_destructor_t) free;
275     return data;
276 
277    error:
278     free(data);
279     return NULL;
280 }
281 
parse_msg_main_ArrayMessage(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)282 static uint8_t * parse_msg_main_ArrayMessage(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
283 {
284     SPICE_GNUC_UNUSED uint8_t *pos;
285     uint8_t *start = message_start;
286     uint8_t *data = NULL;
287     uint64_t nw_size;
288     uint64_t mem_size;
289     uint8_t *in, *end;
290     uint64_t name__nw_size, name__mem_size;
291     uint64_t name__nelements;
292     SpiceMsgMainArrayMessage *out;
293 
294     { /* name */
295         if (SPICE_UNLIKELY((start + 0) > message_end)) {
296             goto error;
297         }
298         name__nelements = message_end - (start + 0);
299 
300         name__nw_size = name__nelements;
301         name__mem_size = sizeof(int8_t) * name__nelements;
302     }
303 
304     nw_size = 0 + name__nw_size;
305     mem_size = sizeof(SpiceMsgMainArrayMessage) + name__mem_size;
306 
307     /* Check if message fits in reported side */
308     if (nw_size > (uintptr_t) (message_end - start)) {
309         return NULL;
310     }
311 
312     /* Validated extents and calculated size */
313     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
314     if (SPICE_UNLIKELY(data == NULL)) {
315         goto error;
316     }
317     end = data + sizeof(SpiceMsgMainArrayMessage);
318     in = start;
319 
320     out = (SpiceMsgMainArrayMessage *)data;
321 
322     verify(sizeof(out->name) == 0);
323     memcpy(out->name, in, name__nelements);
324     in += name__nelements;
325     end += name__nelements;
326 
327     assert(in <= message_end);
328     assert(end <= data + mem_size);
329 
330     *size = end - data;
331     *free_message = (message_destructor_t) free;
332     return data;
333 
334    error:
335     free(data);
336     return NULL;
337 }
338 
parse_msg_main_Zeroes(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)339 static uint8_t * parse_msg_main_Zeroes(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
340 {
341     SPICE_GNUC_UNUSED uint8_t *pos;
342     uint8_t *start = message_start;
343     uint8_t *data = NULL;
344     uint64_t nw_size;
345     uint64_t mem_size;
346     uint8_t *in, *end;
347     SpiceMsgMainZeroes *out;
348 
349     nw_size = 7;
350     mem_size = sizeof(SpiceMsgMainZeroes);
351 
352     /* Check if message fits in reported side */
353     if (nw_size > (uintptr_t) (message_end - start)) {
354         return NULL;
355     }
356 
357     /* Validated extents and calculated size */
358     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
359     if (SPICE_UNLIKELY(data == NULL)) {
360         goto error;
361     }
362     end = data + sizeof(SpiceMsgMainZeroes);
363     in = start;
364 
365     out = (SpiceMsgMainZeroes *)data;
366 
367     consume_uint8(&in);
368     out->n = consume_uint16(&in);
369     consume_uint32(&in);
370 
371     assert(in <= message_end);
372     assert(end <= data + mem_size);
373 
374     *size = end - data;
375     *free_message = (message_destructor_t) free;
376     return data;
377 
378    error:
379     free(data);
380     return NULL;
381 }
382 
parse_msg_main_channels_list(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)383 static uint8_t * parse_msg_main_channels_list(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
384 {
385     SPICE_GNUC_UNUSED uint8_t *pos;
386     uint8_t *start = message_start;
387     uint8_t *data = NULL;
388     uint64_t nw_size;
389     uint64_t mem_size;
390     uint8_t *in, *end;
391     uint64_t channels__nw_size, channels__mem_size;
392     uint64_t channels__nelements;
393     SpiceMsgChannels *out;
394     uint32_t i;
395 
396     { /* channels */
397         uint32_t num_of_channels__value;
398         pos = start + 0;
399         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
400             goto error;
401         }
402         num_of_channels__value = read_uint32(pos);
403         channels__nelements = num_of_channels__value;
404 
405         channels__nw_size = (2) * channels__nelements;
406         channels__mem_size = sizeof(uint16_t) * channels__nelements;
407     }
408 
409     nw_size = 4 + channels__nw_size;
410     mem_size = sizeof(SpiceMsgChannels) + channels__mem_size;
411 
412     /* Check if message fits in reported side */
413     if (nw_size > (uintptr_t) (message_end - start)) {
414         return NULL;
415     }
416 
417     /* Validated extents and calculated size */
418     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
419     if (SPICE_UNLIKELY(data == NULL)) {
420         goto error;
421     }
422     end = data + sizeof(SpiceMsgChannels);
423     in = start;
424 
425     out = (SpiceMsgChannels *)data;
426 
427     out->num_of_channels = consume_uint32(&in);
428     verify(sizeof(out->channels) == 0);
429     for (i = 0; i < channels__nelements; i++) {
430         out->channels[i] = consume_uint16(&in);
431         end += sizeof(uint16_t);
432     }
433 
434     assert(in <= message_end);
435     assert(end <= data + mem_size);
436 
437     *size = end - data;
438     *free_message = (message_destructor_t) free;
439     return data;
440 
441    error:
442     free(data);
443     return NULL;
444 }
445 
parse_msg_main_LenMessage(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)446 static uint8_t * parse_msg_main_LenMessage(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
447 {
448     SPICE_GNUC_UNUSED uint8_t *pos;
449     uint8_t *start = message_start;
450     uint8_t *data = NULL;
451     uint64_t nw_size;
452     uint64_t mem_size;
453     uint8_t *in, *end;
454     uint64_t data__nw_size, data__mem_size;
455     uint64_t data__nelements;
456     SpiceMsgMainLenMessage *out;
457     uint64_t dummy__nelements;
458     uint32_t i;
459 
460     { /* data */
461         if (SPICE_UNLIKELY((start + 8) > message_end)) {
462             goto error;
463         }
464         data__nelements = message_end - (start + 8);
465 
466         data__nw_size = data__nelements;
467         data__mem_size = sizeof(uint8_t) * data__nelements;
468     }
469 
470     nw_size = 8 + data__nw_size;
471     mem_size = sizeof(SpiceMsgMainLenMessage) + data__mem_size;
472 
473     /* Check if message fits in reported side */
474     if (nw_size > (uintptr_t) (message_end - start)) {
475         return NULL;
476     }
477 
478     /* Validated extents and calculated size */
479     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
480     if (SPICE_UNLIKELY(data == NULL)) {
481         goto error;
482     }
483     end = data + sizeof(SpiceMsgMainLenMessage);
484     in = start;
485 
486     out = (SpiceMsgMainLenMessage *)data;
487 
488     dummy__nelements = 2;
489     for (i = 0; i < dummy__nelements; i++) {
490         out->dummy[i] = consume_uint32(&in);
491     }
492     verify(sizeof(out->data) == 0);
493     memcpy(out->data, in, data__nelements);
494     in += data__nelements;
495     end += data__nelements;
496 
497     assert(in <= message_end);
498     assert(end <= data + mem_size);
499 
500     *size = end - data;
501     *free_message = (message_destructor_t) free;
502     return data;
503 
504    error:
505     free(data);
506     return NULL;
507 }
508 
parse_array_uint8_terminated(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)509 static uint8_t * parse_array_uint8_terminated(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
510 {
511     uint8_t *in = message_start + this_ptr_info->offset;
512     uint8_t *end;
513 
514     end = struct_data;
515     memcpy(end, in, this_ptr_info->nelements);
516 #if defined(__GNUC__)
517 #pragma GCC diagnostic push
518 #pragma GCC diagnostic ignored "-Wstringop-overflow"
519 #endif
520     ((char *) (end))[this_ptr_info->nelements] = 0;
521 #if defined(__GNUC__)
522 #pragma GCC diagnostic pop
523 #endif
524     in += this_ptr_info->nelements;
525     end += this_ptr_info->nelements;
526     end += 1;
527     return end;
528 }
529 
parse_msg_main_ZeroLen1(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)530 static uint8_t * parse_msg_main_ZeroLen1(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     SPICE_GNUC_UNUSED intptr_t ptr_size;
539     uint32_t n_ptr=0;
540     PointerInfo ptr_info[2];
541     uint64_t txt2__extra_size;
542     uint64_t txt2__array__nelements;
543     uint64_t txt3__nw_size, txt3__mem_size;
544     uint64_t txt3__nelements;
545     uint32_t txt3__saved_size = 0;
546     uint64_t txt4__nw_size, txt4__mem_size;
547     uint64_t txt4__nelements;
548     SpiceMsgMainZeroLen1 *out;
549     uint64_t txt1__nelements;
550     uint64_t txt3__array__nelements;
551     uint32_t i;
552 
553     { /* txt2 */
554         uint32_t txt2__value;
555         uint64_t txt2__array__nw_size;
556         uint64_t txt2__array__mem_size;
557         uint32_t txt2_len__value;
558         pos = (start + 9);
559         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
560             goto error;
561         }
562         txt2__value = read_uint32(pos);
563         if (SPICE_UNLIKELY(txt2__value >= (uintptr_t) (message_end - message_start))) {
564             goto error;
565         }
566         pos = start + 5;
567         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
568             goto error;
569         }
570         txt2_len__value = read_uint32(pos);
571         txt2__array__nelements = txt2_len__value;
572 
573         txt2__array__nw_size = txt2__array__nelements;
574         txt2__array__mem_size = sizeof(uint8_t) * txt2__array__nelements + sizeof(uint8_t);
575         txt2__array__mem_size = SPICE_ALIGN(txt2__array__mem_size, 4);
576         if (SPICE_UNLIKELY(txt2__array__nw_size > (uintptr_t) (message_end - message_start - txt2__value))) {
577             goto error;
578         }
579         txt2__extra_size = txt2__array__mem_size + /* for alignment */ 3;
580     }
581 
582     { /* txt3 */
583         uint32_t txt2_len__value;
584         pos = start + 5;
585         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
586             goto error;
587         }
588         txt2_len__value = read_uint32(pos);
589         txt3__nelements = txt2_len__value;
590 
591         txt3__nw_size = txt3__nelements;
592         txt3__mem_size = sizeof(uint8_t) * txt3__nelements + sizeof(uint8_t);
593         txt3__mem_size = SPICE_ALIGN(txt3__mem_size, 4);
594         txt3__saved_size = txt3__nw_size;
595     }
596 
597     { /* txt4 */
598         uint16_t txt4_len__value;
599         pos = start + 17 + txt3__nw_size;
600         if (SPICE_UNLIKELY(pos + 2 > message_end)) {
601             goto error;
602         }
603         txt4_len__value = read_uint16(pos);
604         txt4__nelements = txt4_len__value;
605 
606         txt4__nw_size = txt4__nelements;
607         txt4__mem_size = sizeof(uint8_t) * txt4__nelements + sizeof(uint8_t);
608         txt4__mem_size = SPICE_ALIGN(txt4__mem_size, 4);
609     }
610 
611     nw_size = 19 + txt3__nw_size + txt4__nw_size;
612     mem_size = sizeof(SpiceMsgMainZeroLen1) + txt2__extra_size + txt3__mem_size + txt4__mem_size;
613 
614     /* Check if message fits in reported side */
615     if (nw_size > (uintptr_t) (message_end - start)) {
616         return NULL;
617     }
618 
619     /* Validated extents and calculated size */
620     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
621     if (SPICE_UNLIKELY(data == NULL)) {
622         goto error;
623     }
624     end = data + sizeof(SpiceMsgMainZeroLen1);
625     in = start;
626 
627     out = (SpiceMsgMainZeroLen1 *)data;
628 
629     txt1__nelements = 4;
630     memcpy(out->txt1, in, txt1__nelements);
631 #if defined(__GNUC__)
632 #pragma GCC diagnostic push
633 #pragma GCC diagnostic ignored "-Wstringop-overflow"
634 #endif
635     ((char *) (out->txt1))[txt1__nelements] = 0;
636 #if defined(__GNUC__)
637 #pragma GCC diagnostic pop
638 #endif
639     in += txt1__nelements;
640     out->sep1 = consume_uint8(&in);
641     out->txt2_len = consume_uint32(&in);
642     ptr_info[n_ptr].offset = consume_uint32(&in);
643     ptr_info[n_ptr].parse = parse_array_uint8_terminated;
644     ptr_info[n_ptr].dest = (void **)&out->txt2;
645     ptr_info[n_ptr].nelements = txt2__array__nelements;
646     n_ptr++;
647     ptr_info[n_ptr].offset = in - start;
648     ptr_info[n_ptr].parse = parse_array_uint8_terminated;
649     ptr_info[n_ptr].dest = (void **)&out->txt3;
650     txt3__array__nelements = out->txt2_len;
651     ptr_info[n_ptr].nelements = txt3__array__nelements;
652     n_ptr++;
653     in += txt3__saved_size;
654     out->n = consume_uint32(&in);
655     out->txt4_len = consume_uint16(&in);
656     verify(sizeof(out->txt4) == 0);
657     memcpy(out->txt4, in, txt4__nelements);
658 #if defined(__GNUC__)
659 #pragma GCC diagnostic push
660 #pragma GCC diagnostic ignored "-Wstringop-overflow"
661 #endif
662     ((char *) (out->txt4))[txt4__nelements] = 0;
663 #if defined(__GNUC__)
664 #pragma GCC diagnostic pop
665 #endif
666     in += txt4__nelements;
667     end += txt4__nelements;
668     end += 1;
669 
670     assert(in <= message_end);
671 
672     for (i = 0; i < n_ptr; i++) {
673         if (ptr_info[i].offset == 0) {
674             *ptr_info[i].dest = NULL;
675         } else {
676             /* Align to 32 bit */
677             end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
678             *ptr_info[i].dest = (void *)end;
679             end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
680             if (SPICE_UNLIKELY(end == NULL)) {
681                 goto error;
682             }
683         }
684     }
685 
686     assert(end <= data + mem_size);
687 
688     *size = end - data;
689     *free_message = (message_destructor_t) free;
690     return data;
691 
692    error:
693     free(data);
694     return NULL;
695 }
696 
parse_TestChannel_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)697 static uint8_t * parse_TestChannel_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)
698 {
699     static parse_msg_func_t funcs1[6] =  {
700         parse_msg_main_ShortDataSubMarshall,
701         parse_msg_main_ArrayMessage,
702         parse_msg_main_Zeroes,
703         parse_msg_main_channels_list,
704         parse_msg_main_LenMessage,
705         parse_msg_main_ZeroLen1
706     };
707     if (message_type >= 1 && message_type < 7) {
708         return funcs1[message_type-1](message_start, message_end, size_out, free_message);
709     }
710     return NULL;
711 }
712 
spice_get_server_channel_parser_test(uint32_t channel,unsigned int * max_message_type)713 spice_parse_channel_func_t spice_get_server_channel_parser_test(uint32_t channel, unsigned int *max_message_type)
714 {
715     static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[2] =  {
716         { NULL, 0 },
717         { parse_TestChannel_msg, 6}
718     };
719     if (channel < 2) {
720         if (max_message_type != NULL) {
721             *max_message_type = channels[channel].max_messages;
722         }
723         return channels[channel].func;
724     }
725     return NULL;
726 }
727 
spice_parse_msg_test(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)728 uint8_t * spice_parse_msg_test(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)
729 {
730     spice_parse_channel_func_t func;
731     func = spice_get_server_channel_parser_test(channel, NULL);
732     if (func != NULL) {
733         return func(message_start, message_end, message_type, minor, size_out, free_message);
734     }
735     return NULL;
736 }
737