LCOV - code coverage report
Current view: top level - tests - test-marshallers.c (source / functions) Hit Total Coverage
Test: out.info Lines: 78 81 96.3 %
Date: 2022-01-27 10:43:00 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :    Copyright (C) 2015-2021 Red Hat, Inc.
       3             : 
       4             :    This library is free software; you can redistribute it and/or
       5             :    modify it under the terms of the GNU Lesser General Public
       6             :    License as published by the Free Software Foundation; either
       7             :    version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             :    This library is distributed in the hope that it will be useful,
      10             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :    Lesser General Public License for more details.
      13             : 
      14             :    You should have received a copy of the GNU Lesser General Public
      15             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      16             : */
      17             : #include <config.h>
      18             : 
      19             : #include <glib.h>
      20             : #include <string.h>
      21             : 
      22             : #include <common/marshaller.h>
      23             : #include <common/demarshallers.h>
      24             : #include "generated_test_enums.h"
      25             : #include "generated_test_marshallers.h"
      26             : 
      27             : #ifndef g_assert_true
      28             : #define g_assert_true g_assert
      29             : #endif
      30             : 
      31             : #define NUM_CHANNELS 3u
      32             : 
      33             : spice_parse_channel_func_t
      34             : spice_get_server_channel_parser_test(uint32_t channel, unsigned int *max_message_type);
      35             : 
      36           1 : static void test_overflow(SpiceMarshaller *m)
      37             : {
      38             :     SpiceMsgChannels *msg;
      39             :     uint8_t *data, *out;
      40             :     size_t len;
      41           1 :     int to_free = 0;
      42             :     spice_parse_channel_func_t func;
      43             :     unsigned int max_message_type, n;
      44             :     message_destructor_t free_output;
      45             : 
      46           1 :     msg = (SpiceMsgChannels *) malloc(sizeof(SpiceMsgChannels) +
      47             :           NUM_CHANNELS * sizeof(uint16_t));
      48           1 :     g_assert_nonnull(msg);
      49             : 
      50             :     // build a message and marshal it
      51           1 :     msg->num_of_channels = NUM_CHANNELS;
      52           4 :     for (n = 0; n < NUM_CHANNELS; ++n) {
      53           3 :         msg->channels[n] = n + 1;
      54             :     }
      55           1 :     spice_marshall_msg_main_channels_list(m, msg);
      56             : 
      57             :     // get linear data
      58           1 :     data = spice_marshaller_linearize(m, 0, &len, &to_free);
      59           1 :     g_assert_nonnull(data);
      60             : 
      61           1 :     printf("output len %lu\n", (unsigned long) len);
      62             : 
      63             :     // hack: setting the number of channels in the marshalled message to a
      64             :     // value that will cause overflow while parsing the message to make sure
      65             :     // that the parser can handle this situation
      66           1 :     *((uint32_t *) data) = 0x80000002u;
      67             : 
      68             :     // extract the message
      69           1 :     func = spice_get_server_channel_parser_test(SPICE_CHANNEL_MAIN, &max_message_type);
      70           1 :     g_assert_nonnull(func);
      71           1 :     out = func(data, data+len, SPICE_MSG_MAIN_CHANNELS_LIST, 0, &len, &free_output);
      72           1 :     g_assert_null(out);
      73             : 
      74             :     // cleanup
      75           1 :     if (to_free) {
      76           0 :         free(data);
      77             :     }
      78           1 :     if (out) {
      79           0 :         free_output(out);
      80             :     }
      81           1 :     free(msg);
      82           1 : }
      83             : 
      84             : static uint8_t expected_data[] = { 123, /* dummy byte */
      85             :                                    0x02, 0x00, 0x00, 0x00, /* data_size */
      86             :                                    0x09, 0x00, 0x00, 0x00, /* data offset */
      87             :                                    0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12, /* data */
      88             :                                    0x21, 0x43, 0x65, 0x87, 0x09, 0xba, 0xdc, 0xfe, /* data */
      89             : };
      90             : 
      91             : typedef void (*message_destructor_t)(uint8_t *message);
      92             : uint8_t * spice_parse_msg_test(uint8_t *message_start, uint8_t *message_end,
      93             :                                uint32_t channel, uint16_t message_type, int minor,
      94             :                                size_t *size_out, message_destructor_t *free_message);
      95             : 
      96           1 : static void test_zerolen1(void)
      97             : {
      98             :     static uint8_t data[] = {
      99             :         'd', 'a', 't', 'a', // txt1
     100             :         123, // sep1
     101             :         4, 0, 0, 0, // len
     102             :         26, 0, 0, 0, // ptr to txt2
     103             :         'n','e','k','o', // txt3
     104             :         12, 13, 14, 15, // n
     105             :         3, 0, // txt4_len
     106             :         'b','a','r', // txt4
     107             :         'f', 'o', 'o', '!', // string
     108             :         'x', 'x', // garbage at the end
     109             :     };
     110             : 
     111             :     size_t msg_len;
     112             :     message_destructor_t free_message;
     113             : 
     114             :     // demarshal array with @zero_terminated data
     115             :     SpiceMsgMainZeroLen1 *msg = (SpiceMsgMainZeroLen1 *)
     116           1 :         spice_parse_msg_test(data, data + sizeof(data), SPICE_CHANNEL_MAIN, SPICE_MSG_MAIN_ZEROLEN1,
     117             :                              0, &msg_len, &free_message);
     118             : 
     119           1 :     g_assert_nonnull(msg);
     120           1 :     g_assert_cmpmem(msg->txt1, 5, "data", 5);
     121           1 :     g_assert_cmpint(msg->sep1, ==, 123);
     122           1 :     g_assert_cmpint(msg->txt2_len, ==, 4);
     123           1 :     g_assert_cmpint(msg->n , ==, 0x0f0e0d0c);
     124           1 :     g_assert_nonnull(msg->txt2);
     125           1 :     g_assert_cmpmem(msg->txt2, 5, "foo!", 5);
     126           1 :     g_assert_nonnull(msg->txt3);
     127           1 :     g_assert_cmpmem(msg->txt3, 5, "neko", 5);
     128           1 :     g_assert_cmpint(msg->txt4_len, ==, 3);
     129           1 :     g_assert_cmpmem(msg->txt4, 4, "bar", 4);
     130             : 
     131           1 :     free_message((uint8_t *) msg);
     132           1 : }
     133             : 
     134           1 : int main(void)
     135             : {
     136             :     SpiceMarshaller *marshaller;
     137             :     SpiceMsgMainShortDataSubMarshall *msg;
     138             :     size_t len, msg_len;
     139             :     int free_res;
     140             :     uint8_t *data;
     141             :     message_destructor_t free_message;
     142             : 
     143           1 :     msg = g_new0(SpiceMsgMainShortDataSubMarshall, 1);
     144           1 :     msg->data = g_new(uint64_t, 2);
     145           1 :     msg->dummy_byte = 123;
     146           1 :     msg->data_size = 2;
     147           1 :     msg->data[0] = 0x1234567890abcdef;
     148           1 :     msg->data[1] = 0xfedcba0987654321;
     149             : 
     150           1 :     marshaller = spice_marshaller_new();
     151           1 :     spice_marshall_msg_main_ShortDataSubMarshall(marshaller, msg);
     152           1 :     spice_marshaller_flush(marshaller);
     153           1 :     data = spice_marshaller_linearize(marshaller, 0, &len, &free_res);
     154           1 :     g_assert_cmpint(len, ==, G_N_ELEMENTS(expected_data));
     155           1 :     g_assert_true(memcmp(data, expected_data, len) == 0);
     156             : 
     157           1 :     g_free(msg->data);
     158           1 :     g_free(msg);
     159             : 
     160             :     // test demarshaller
     161             :     msg = (SpiceMsgMainShortDataSubMarshall *)
     162           1 :         spice_parse_msg_test(data, data + len, SPICE_CHANNEL_MAIN,
     163             :                              SPICE_MSG_MAIN_SHORTDATASUBMARSHALL,
     164             :                              0, &msg_len, &free_message);
     165             : 
     166           1 :     g_assert_nonnull(msg);
     167           1 :     g_assert_cmpint(msg->dummy_byte, ==, 123);
     168           1 :     g_assert_cmpint(msg->data_size, ==, 2);
     169           1 :     g_assert_nonnull(msg->data);
     170           1 :     g_assert_cmpint(msg->data[0], ==, 0x1234567890abcdef);
     171           1 :     g_assert_cmpint(msg->data[1], ==, 0xfedcba0987654321);
     172             : 
     173           1 :     free_message((uint8_t *) msg);
     174             : 
     175           1 :     if (free_res) {
     176           1 :         free(data);
     177             :     }
     178           1 :     spice_marshaller_reset(marshaller);
     179             : 
     180           1 :     test_zerolen1();
     181             : 
     182           1 :     SpiceMsgMainZeroes msg_zeroes = { 0x0102 };
     183             : 
     184           1 :     spice_marshall_msg_main_Zeroes(marshaller, &msg_zeroes);
     185           1 :     spice_marshaller_flush(marshaller);
     186           1 :     data = spice_marshaller_linearize(marshaller, 0, &len, &free_res);
     187           1 :     g_assert_cmpint(len, ==, 7);
     188           1 :     g_assert_true(memcmp(data, "\x00\x02\x01\x00\x00\x00\x00", 7) == 0);
     189           1 :     if (free_res) {
     190           0 :         free(data);
     191             :     }
     192             : 
     193           1 :     test_overflow(marshaller);
     194             : 
     195           1 :     len = 4;
     196           1 :     data = g_new0(uint8_t, len);
     197           1 :     memset(data, 0, len);
     198           1 :     msg = (SpiceMsgMainShortDataSubMarshall *) spice_parse_msg_test(data, data + len, 1, 3, 0,
     199             :                                                                     &msg_len, &free_message);
     200           1 :     g_assert_null(msg);
     201           1 :     g_free(data);
     202             : 
     203           1 :     spice_marshaller_destroy(marshaller);
     204             : 
     205           1 :     return 0;
     206             : }

Generated by: LCOV version 1.14