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 "test-marshallers.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_array_uint64(uint8_t * message_start,SPICE_GNUC_UNUSED uint8_t * message_end,uint8_t * struct_data,PointerInfo * this_ptr_info)173 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)
174 {
175     uint8_t *in = message_start + this_ptr_info->offset;
176     uint8_t *end;
177     uint32_t i;
178 
179     end = struct_data;
180     for (i = 0; i < this_ptr_info->nelements; i++) {
181         *(uint64_t *)end = consume_uint64(&in);
182         end += sizeof(uint64_t);
183     }
184     return end;
185 }
186 
parse_msg_main_ShortDataSubMarshall(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)187 static uint8_t * parse_msg_main_ShortDataSubMarshall(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
188 {
189     SPICE_GNUC_UNUSED uint8_t *pos;
190     uint8_t *start = message_start;
191     uint8_t *data = NULL;
192     uint64_t nw_size;
193     uint64_t mem_size;
194     uint8_t *in, *end;
195     SPICE_GNUC_UNUSED intptr_t ptr_size;
196     uint32_t n_ptr=0;
197     PointerInfo ptr_info[1];
198     uint64_t data__extra_size;
199     uint64_t data__array__nelements;
200     SpiceMsgMainShortDataSubMarshall *out;
201     uint32_t i;
202 
203     { /* data */
204         uint32_t data__value;
205         uint64_t data__array__nw_size;
206         uint64_t data__array__mem_size;
207         uint32_t data_size__value;
208         pos = (start + 5);
209         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
210             goto error;
211         }
212         data__value = read_uint32(pos);
213         if (SPICE_UNLIKELY(data__value >= (uintptr_t) (message_end - message_start))) {
214             goto error;
215         }
216         pos = start + 1;
217         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
218             goto error;
219         }
220         data_size__value = read_uint32(pos);
221         data__array__nelements = data_size__value;
222 
223         data__array__nw_size = (8) * data__array__nelements;
224         data__array__mem_size = sizeof(uint64_t) * data__array__nelements;
225         if (SPICE_UNLIKELY(data__value + data__array__nw_size > (uintptr_t) (message_end - message_start))) {
226             goto error;
227         }
228         data__extra_size = data__array__mem_size + /* for alignment */ 3;
229     }
230 
231     nw_size = 9;
232     mem_size = sizeof(SpiceMsgMainShortDataSubMarshall) + data__extra_size;
233 
234     /* Check if message fits in reported side */
235     if (nw_size > (uintptr_t) (message_end - start)) {
236         return NULL;
237     }
238 
239     /* Validated extents and calculated size */
240     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
241     if (SPICE_UNLIKELY(data == NULL)) {
242         goto error;
243     }
244     end = data + sizeof(SpiceMsgMainShortDataSubMarshall);
245     in = start;
246 
247     out = (SpiceMsgMainShortDataSubMarshall *)data;
248 
249     out->dummy_byte = consume_uint8(&in);
250     out->data_size = consume_uint32(&in);
251     ptr_info[n_ptr].offset = consume_uint32(&in);
252     ptr_info[n_ptr].parse = parse_array_uint64;
253     ptr_info[n_ptr].dest = (void **)&out->data;
254     ptr_info[n_ptr].nelements = data__array__nelements;
255     n_ptr++;
256 
257     assert(in <= message_end);
258 
259     for (i = 0; i < n_ptr; i++) {
260         if (ptr_info[i].offset == 0) {
261             *ptr_info[i].dest = NULL;
262         } else {
263             /* Align to 32 bit */
264             end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
265             *ptr_info[i].dest = (void *)end;
266             end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
267             if (SPICE_UNLIKELY(end == NULL)) {
268                 goto error;
269             }
270         }
271     }
272 
273     assert(end <= data + mem_size);
274 
275     *size = end - data;
276     *free_message = (message_destructor_t) free;
277     return data;
278 
279    error:
280     free(data);
281     return NULL;
282 }
283 
parse_msg_main_ArrayMessage(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)284 static uint8_t * parse_msg_main_ArrayMessage(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
285 {
286     SPICE_GNUC_UNUSED uint8_t *pos;
287     uint8_t *start = message_start;
288     uint8_t *data = NULL;
289     uint64_t nw_size;
290     uint64_t mem_size;
291     uint8_t *in, *end;
292     uint64_t name__nw_size;
293     uint64_t name__nelements;
294     SpiceMsgMainArrayMessage *out;
295 
296     { /* name */
297         if (SPICE_UNLIKELY((start + 0) > message_end)) {
298             goto error;
299         }
300         name__nelements = message_end - (start + 0);
301 
302         name__nw_size = name__nelements;
303     }
304 
305     nw_size = 0 + name__nw_size;
306     mem_size = sizeof(SpiceMsgMainArrayMessage);
307 
308     /* Check if message fits in reported side */
309     if (nw_size > (uintptr_t) (message_end - start)) {
310         return NULL;
311     }
312 
313     /* Validated extents and calculated size */
314     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
315     if (SPICE_UNLIKELY(data == NULL)) {
316         goto error;
317     }
318     end = data + sizeof(SpiceMsgMainArrayMessage);
319     in = start;
320 
321     out = (SpiceMsgMainArrayMessage *)data;
322 
323     memcpy(out->name, in, name__nelements);
324     in += name__nelements;
325 
326     assert(in <= message_end);
327     assert(end <= data + mem_size);
328 
329     *size = end - data;
330     *free_message = (message_destructor_t) free;
331     return data;
332 
333    error:
334     free(data);
335     return NULL;
336 }
337 
parse_msg_main_Zeroes(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)338 static uint8_t * parse_msg_main_Zeroes(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
339 {
340     SPICE_GNUC_UNUSED uint8_t *pos;
341     uint8_t *start = message_start;
342     uint8_t *data = NULL;
343     uint64_t nw_size;
344     uint64_t mem_size;
345     uint8_t *in, *end;
346     SpiceMsgMainZeroes *out;
347 
348     nw_size = 7;
349     mem_size = sizeof(SpiceMsgMainZeroes);
350 
351     /* Check if message fits in reported side */
352     if (nw_size > (uintptr_t) (message_end - start)) {
353         return NULL;
354     }
355 
356     /* Validated extents and calculated size */
357     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
358     if (SPICE_UNLIKELY(data == NULL)) {
359         goto error;
360     }
361     end = data + sizeof(SpiceMsgMainZeroes);
362     in = start;
363 
364     out = (SpiceMsgMainZeroes *)data;
365 
366     consume_uint8(&in);
367     out->n = consume_uint16(&in);
368     consume_uint32(&in);
369 
370     assert(in <= message_end);
371     assert(end <= data + mem_size);
372 
373     *size = end - data;
374     *free_message = (message_destructor_t) free;
375     return data;
376 
377    error:
378     free(data);
379     return NULL;
380 }
381 
parse_msg_main_channels_list(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)382 static uint8_t * parse_msg_main_channels_list(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
383 {
384     SPICE_GNUC_UNUSED uint8_t *pos;
385     uint8_t *start = message_start;
386     uint8_t *data = NULL;
387     uint64_t nw_size;
388     uint64_t mem_size;
389     uint8_t *in, *end;
390     uint64_t channels__nw_size, channels__mem_size;
391     uint64_t channels__nelements;
392     SpiceMsgChannels *out;
393     uint32_t i;
394 
395     { /* channels */
396         uint32_t num_of_channels__value;
397         pos = start + 0;
398         if (SPICE_UNLIKELY(pos + 4 > message_end)) {
399             goto error;
400         }
401         num_of_channels__value = read_uint32(pos);
402         channels__nelements = num_of_channels__value;
403 
404         channels__nw_size = (2) * channels__nelements;
405         channels__mem_size = sizeof(uint16_t) * channels__nelements;
406     }
407 
408     nw_size = 4 + channels__nw_size;
409     mem_size = sizeof(SpiceMsgChannels) + channels__mem_size;
410 
411     /* Check if message fits in reported side */
412     if (nw_size > (uintptr_t) (message_end - start)) {
413         return NULL;
414     }
415 
416     /* Validated extents and calculated size */
417     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
418     if (SPICE_UNLIKELY(data == NULL)) {
419         goto error;
420     }
421     end = data + sizeof(SpiceMsgChannels);
422     in = start;
423 
424     out = (SpiceMsgChannels *)data;
425 
426     out->num_of_channels = consume_uint32(&in);
427     for (i = 0; i < channels__nelements; i++) {
428         out->channels[i] = consume_uint16(&in);
429         end += sizeof(uint16_t);
430     }
431 
432     assert(in <= message_end);
433     assert(end <= data + mem_size);
434 
435     *size = end - data;
436     *free_message = (message_destructor_t) free;
437     return data;
438 
439    error:
440     free(data);
441     return NULL;
442 }
443 
parse_msg_main_LenMessage(uint8_t * message_start,uint8_t * message_end,size_t * size,message_destructor_t * free_message)444 static uint8_t * parse_msg_main_LenMessage(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
445 {
446     SPICE_GNUC_UNUSED uint8_t *pos;
447     uint8_t *start = message_start;
448     uint8_t *data = NULL;
449     uint64_t nw_size;
450     uint64_t mem_size;
451     uint8_t *in, *end;
452     uint64_t data__nw_size, data__mem_size;
453     uint64_t data__nelements;
454     SpiceMsgMainLenMessage *out;
455     uint64_t dummy__nelements;
456     uint32_t i;
457 
458     { /* data */
459         if (SPICE_UNLIKELY((start + 8) > message_end)) {
460             goto error;
461         }
462         data__nelements = message_end - (start + 8);
463 
464         data__nw_size = data__nelements;
465         data__mem_size = sizeof(uint8_t) * data__nelements;
466     }
467 
468     nw_size = 8 + data__nw_size;
469     mem_size = sizeof(SpiceMsgMainLenMessage) + data__mem_size;
470 
471     /* Check if message fits in reported side */
472     if (nw_size > (uintptr_t) (message_end - start)) {
473         return NULL;
474     }
475 
476     /* Validated extents and calculated size */
477     data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
478     if (SPICE_UNLIKELY(data == NULL)) {
479         goto error;
480     }
481     end = data + sizeof(SpiceMsgMainLenMessage);
482     in = start;
483 
484     out = (SpiceMsgMainLenMessage *)data;
485 
486     dummy__nelements = 2;
487     for (i = 0; i < dummy__nelements; i++) {
488         out->dummy[i] = consume_uint32(&in);
489     }
490     memcpy(out->data, in, data__nelements);
491     in += data__nelements;
492     end += data__nelements;
493 
494     assert(in <= message_end);
495     assert(end <= data + mem_size);
496 
497     *size = end - data;
498     *free_message = (message_destructor_t) free;
499     return data;
500 
501    error:
502     free(data);
503     return NULL;
504 }
505 
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)506 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)
507 {
508     static parse_msg_func_t funcs1[5] =  {
509         parse_msg_main_ShortDataSubMarshall,
510         parse_msg_main_ArrayMessage,
511         parse_msg_main_Zeroes,
512         parse_msg_main_channels_list,
513         parse_msg_main_LenMessage
514     };
515     if (message_type >= 1 && message_type < 6) {
516         return funcs1[message_type-1](message_start, message_end, size_out, free_message);
517     }
518     return NULL;
519 }
520 
spice_get_server_channel_parser(uint32_t channel,unsigned int * max_message_type)521 spice_parse_channel_func_t spice_get_server_channel_parser(uint32_t channel, unsigned int *max_message_type)
522 {
523     static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[2] =  {
524         { NULL, 0 },
525         { parse_TestChannel_msg, 5}
526     };
527     if (channel < 2) {
528         if (max_message_type != NULL) {
529             *max_message_type = channels[channel].max_messages;
530         }
531         return channels[channel].func;
532     }
533     return NULL;
534 }
535 
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)536 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)
537 {
538     spice_parse_channel_func_t func;
539     func = spice_get_server_channel_parser(channel, NULL);
540     if (func != NULL) {
541         return func(message_start, message_end, message_type, minor, size_out, free_message);
542     }
543     return NULL;
544 }
545