LCOV - code coverage report
Current view: top level - atom - forge-overflow-test.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 89 96 92.7 %
Date: 2020-09-30 14:18:52 Functions: 7 7 100.0 %
Branches: 44 64 68.8 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :   Copyright 2019 David Robillard <http://drobilla.net>
       3                 :            : 
       4                 :            :   Permission to use, copy, modify, and/or distribute this software for any
       5                 :            :   purpose with or without fee is hereby granted, provided that the above
       6                 :            :   copyright notice and this permission notice appear in all copies.
       7                 :            : 
       8                 :            :   THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
       9                 :            :   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      10                 :            :   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      11                 :            :   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      12                 :            :   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      13                 :            :   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      14                 :            :   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      15                 :            : */
      16                 :            : 
      17                 :            : #include "lv2/atom/atom-test-utils.c"
      18                 :            : #include "lv2/atom/atom.h"
      19                 :            : #include "lv2/atom/forge.h"
      20                 :            : #include "lv2/atom/util.h"
      21                 :            : #include "lv2/urid/urid.h"
      22                 :            : 
      23                 :            : #include <assert.h>
      24                 :            : #include <stdint.h>
      25                 :            : #include <stdlib.h>
      26                 :            : #include <string.h>
      27                 :            : 
      28                 :            : static int
      29                 :          1 : test_string_overflow(void)
      30                 :            : {
      31                 :            : #define MAX_CHARS 15
      32                 :            : 
      33                 :            :         static const size_t capacity = sizeof(LV2_Atom_String) + MAX_CHARS + 1;
      34                 :            :         static const char*  str      = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      35                 :            : 
      36                 :          1 :         uint8_t*       buf = (uint8_t*)malloc(capacity);
      37                 :          1 :         LV2_URID_Map   map = { NULL, urid_map };
      38                 :            :         LV2_Atom_Forge forge;
      39                 :          1 :         lv2_atom_forge_init(&forge, &map);
      40                 :            : 
      41                 :            :         // Check that writing increasingly long strings fails at the right point
      42         [ +  + ]:         16 :         for (size_t count = 0; count < MAX_CHARS; ++count) {
      43                 :         15 :                 lv2_atom_forge_set_buffer(&forge, buf, capacity);
      44                 :            : 
      45                 :            :                 const LV2_Atom_Forge_Ref ref =
      46                 :         15 :                         lv2_atom_forge_string(&forge, str, count);
      47         [ -  + ]:         15 :                 if (!ref) {
      48                 :          0 :                         return test_fail("Failed to write %zu byte string\n", count);
      49                 :            :                 }
      50                 :            :         }
      51                 :            : 
      52                 :            :         // Failure writing to an exactly full forge
      53                 :          1 :         LV2_Atom_Forge_Ref ref = 0;
      54         [ -  + ]:          1 :         if ((ref = lv2_atom_forge_string(&forge, str, MAX_CHARS + 1))) {
      55                 :          0 :                 return test_fail("Successfully wrote past end of buffer\n");
      56                 :            :         }
      57                 :            : 
      58                 :            :         // Failure writing body after successfully writing header
      59                 :          1 :         lv2_atom_forge_set_buffer(&forge, buf, sizeof(LV2_Atom) + 1);
      60         [ -  + ]:          1 :         if ((ref = lv2_atom_forge_string(&forge, "AB", 2))) {
      61                 :          0 :                 return test_fail("Successfully wrote atom header past end\n");
      62                 :            :         }
      63                 :            : 
      64                 :          1 :         free(buf);
      65                 :          1 :         return 0;
      66                 :            : }
      67                 :            : 
      68                 :            : static int
      69                 :          1 : test_literal_overflow(void)
      70                 :            : {
      71                 :            :         static const size_t capacity = sizeof(LV2_Atom_Literal) + 2;
      72                 :            : 
      73                 :          1 :         uint8_t*           buf = (uint8_t*)malloc(capacity);
      74                 :          1 :         LV2_URID_Map       map = { NULL, urid_map };
      75                 :          1 :         LV2_Atom_Forge_Ref ref = 0;
      76                 :            :         LV2_Atom_Forge     forge;
      77                 :          1 :         lv2_atom_forge_init(&forge, &map);
      78                 :            : 
      79                 :            :         // Failure in atom header
      80                 :          1 :         lv2_atom_forge_set_buffer(&forge, buf, 1);
      81         [ -  + ]:          1 :         if ((ref = lv2_atom_forge_literal(&forge, "A", 1, 0, 0))) {
      82                 :          0 :                 return test_fail("Successfully wrote atom header past end\n");
      83                 :            :         }
      84                 :            : 
      85                 :            :         // Failure in literal header
      86                 :          1 :         lv2_atom_forge_set_buffer(&forge, buf, sizeof(LV2_Atom) + 1);
      87         [ -  + ]:          1 :         if ((ref = lv2_atom_forge_literal(&forge, "A", 1, 0, 0))) {
      88                 :          0 :                 return test_fail("Successfully wrote literal header past end\n");
      89                 :            :         }
      90                 :            : 
      91                 :            :         // Success (only room for one character + null terminator)
      92                 :          1 :         lv2_atom_forge_set_buffer(&forge, buf, capacity);
      93         [ -  + ]:          1 :         if (!(ref = lv2_atom_forge_literal(&forge, "A", 1, 0, 0))) {
      94                 :          0 :                 return test_fail("Failed to write small enough literal\n");
      95                 :            :         }
      96                 :            : 
      97                 :            :         // Failure in body
      98                 :          1 :         lv2_atom_forge_set_buffer(&forge, buf, capacity);
      99         [ -  + ]:          1 :         if ((ref = lv2_atom_forge_literal(&forge, "AB", 2, 0, 0))) {
     100                 :          0 :                 return test_fail("Successfully wrote literal body past end\n");
     101                 :            :         }
     102                 :            : 
     103                 :          1 :         free(buf);
     104                 :          1 :         return 0;
     105                 :            : }
     106                 :            : 
     107                 :            : static int
     108                 :          1 : test_sequence_overflow(void)
     109                 :            : {
     110                 :            :         static const size_t size = sizeof(LV2_Atom_Sequence) + 6 * sizeof(LV2_Atom);
     111                 :          1 :         LV2_URID_Map        map  = { NULL, urid_map };
     112                 :            : 
     113                 :            :         // Test over a range that fails in the sequence header and event components
     114         [ +  + ]:         64 :         for (size_t capacity = 1; capacity < size; ++capacity) {
     115                 :         63 :                 uint8_t* buf = (uint8_t*)malloc(capacity);
     116                 :            : 
     117                 :            :                 LV2_Atom_Forge forge;
     118                 :         63 :                 lv2_atom_forge_init(&forge, &map);
     119                 :         63 :                 lv2_atom_forge_set_buffer(&forge, buf, capacity);
     120                 :            : 
     121                 :            :                 LV2_Atom_Forge_Frame frame;
     122                 :            :                 LV2_Atom_Forge_Ref   ref =
     123                 :         63 :                         lv2_atom_forge_sequence_head(&forge, &frame, 0);
     124                 :            : 
     125 [ +  + ][ -  + ]:         63 :                 assert(capacity >= sizeof(LV2_Atom_Sequence) || !frame.ref);
     126 [ +  + ][ -  + ]:         63 :                 assert(capacity >= sizeof(LV2_Atom_Sequence) || !ref);
     127                 :            : 
     128                 :         63 :                 lv2_atom_forge_frame_time(&forge, 0);
     129                 :         63 :                 lv2_atom_forge_int(&forge, 42);
     130                 :         63 :                 lv2_atom_forge_pop(&forge, &frame);
     131                 :            : 
     132                 :         63 :                 free(buf);
     133                 :            :         }
     134                 :            : 
     135                 :          1 :         return 0;
     136                 :            : }
     137                 :            : 
     138                 :            : static int
     139                 :          1 : test_vector_head_overflow(void)
     140                 :            : {
     141                 :            :         static const size_t size = sizeof(LV2_Atom_Vector) + 3 * sizeof(LV2_Atom);
     142                 :          1 :         LV2_URID_Map        map  = { NULL, urid_map };
     143                 :            : 
     144                 :            :         // Test over a range that fails in the vector header and elements
     145         [ +  + ]:         40 :         for (size_t capacity = 1; capacity < size; ++capacity) {
     146                 :         39 :                 uint8_t* buf = (uint8_t*)malloc(capacity);
     147                 :            : 
     148                 :            :                 LV2_Atom_Forge forge;
     149                 :         39 :                 lv2_atom_forge_init(&forge, &map);
     150                 :         39 :                 lv2_atom_forge_set_buffer(&forge, buf, capacity);
     151                 :            : 
     152                 :            :                 LV2_Atom_Forge_Frame frame;
     153                 :         39 :                 LV2_Atom_Forge_Ref   ref = lv2_atom_forge_vector_head(
     154                 :            :                 &forge, &frame, sizeof(int32_t), forge.Int);
     155                 :            : 
     156 [ +  + ][ -  + ]:         39 :                 assert(capacity >= sizeof(LV2_Atom_Vector) || !frame.ref);
     157 [ +  + ][ -  + ]:         39 :                 assert(capacity >= sizeof(LV2_Atom_Vector) || !ref);
     158                 :            : 
     159                 :         39 :                 lv2_atom_forge_int(&forge, 1);
     160                 :         39 :                 lv2_atom_forge_int(&forge, 2);
     161                 :         39 :                 lv2_atom_forge_int(&forge, 3);
     162                 :         39 :                 lv2_atom_forge_pop(&forge, &frame);
     163                 :            : 
     164                 :         39 :                 free(buf);
     165                 :            :         }
     166                 :            : 
     167                 :          1 :         return 0;
     168                 :            : }
     169                 :            : 
     170                 :            : static int
     171                 :          1 : test_vector_overflow(void)
     172                 :            : {
     173                 :            :         static const size_t  size  = sizeof(LV2_Atom_Vector) + 3 * sizeof(LV2_Atom);
     174                 :            :         static const int32_t vec[] = { 1, 2, 3 };
     175                 :          1 :         LV2_URID_Map         map   = { NULL, urid_map };
     176                 :            : 
     177                 :            :         // Test over a range that fails in the vector header and elements
     178         [ +  + ]:         40 :         for (size_t capacity = 1; capacity < size; ++capacity) {
     179                 :         39 :                 uint8_t* buf = (uint8_t*)malloc(capacity);
     180                 :            : 
     181                 :            :                 LV2_Atom_Forge forge;
     182                 :         39 :                 lv2_atom_forge_init(&forge, &map);
     183                 :         39 :                 lv2_atom_forge_set_buffer(&forge, buf, capacity);
     184                 :            : 
     185                 :         39 :                 LV2_Atom_Forge_Ref ref = lv2_atom_forge_vector(
     186                 :            :                         &forge, sizeof(int32_t), forge.Int, 3, vec);
     187                 :            : 
     188 [ +  + ][ -  + ]:         39 :                 assert(capacity >= sizeof(LV2_Atom_Vector) || !ref);
     189                 :            : 
     190                 :         39 :                 free(buf);
     191                 :            :         }
     192                 :            : 
     193                 :          1 :         return 0;
     194                 :            : }
     195                 :            : 
     196                 :            : static int
     197                 :          1 : test_tuple_overflow(void)
     198                 :            : {
     199                 :            :         static const size_t size = sizeof(LV2_Atom_Tuple) + 3 * sizeof(LV2_Atom);
     200                 :          1 :         LV2_URID_Map        map  = { NULL, urid_map };
     201                 :            : 
     202                 :            :         // Test over a range that fails in the tuple header and elements
     203         [ +  + ]:         32 :         for (size_t capacity = 1; capacity < size; ++capacity) {
     204                 :         31 :                 uint8_t* buf = (uint8_t*)malloc(capacity);
     205                 :            : 
     206                 :            :                 LV2_Atom_Forge forge;
     207                 :         31 :                 lv2_atom_forge_init(&forge, &map);
     208                 :         31 :                 lv2_atom_forge_set_buffer(&forge, buf, capacity);
     209                 :            : 
     210                 :            :                 LV2_Atom_Forge_Frame frame;
     211                 :         31 :                 LV2_Atom_Forge_Ref   ref = lv2_atom_forge_tuple(&forge, &frame);
     212                 :            : 
     213 [ +  + ][ -  + ]:         31 :                 assert(capacity >= sizeof(LV2_Atom_Tuple) || !frame.ref);
     214 [ +  + ][ -  + ]:         31 :                 assert(capacity >= sizeof(LV2_Atom_Tuple) || !ref);
     215                 :            : 
     216                 :         31 :                 lv2_atom_forge_int(&forge, 1);
     217                 :         31 :                 lv2_atom_forge_float(&forge, 2.0f);
     218                 :         31 :                 lv2_atom_forge_string(&forge, "three", 5);
     219                 :         31 :                 lv2_atom_forge_pop(&forge, &frame);
     220                 :            : 
     221                 :         31 :                 free(buf);
     222                 :            :         }
     223                 :            : 
     224                 :          1 :         return 0;
     225                 :            : }
     226                 :            : 
     227                 :            : int
     228                 :          1 : main(void)
     229                 :            : {
     230   [ +  -  +  - ]:          3 :         const int ret = test_string_overflow() || test_literal_overflow() ||
     231   [ +  -  +  - ]:          3 :                         test_sequence_overflow() || test_vector_head_overflow() ||
     232 [ +  - ][ -  + ]:          3 :                         test_vector_overflow() || test_tuple_overflow();
     233                 :            : 
     234                 :          1 :         free_urid_map();
     235                 :            : 
     236                 :          1 :         return ret;
     237                 :            : }

Generated by: LCOV version 1.13