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