1 /* 2 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com> 3 * 4 * libcbor is free software; you can redistribute it and/or modify 5 * it under the terms of the MIT license. See LICENSE for details. 6 */ 7 8 #include <math.h> 9 #include "assertions.h" 10 #include "cbor.h" 11 12 unsigned char buffer[512]; 13 14 static void test_bools(void** _state _CBOR_UNUSED) { 15 assert_size_equal(1, cbor_encode_bool(false, buffer, 512)); 16 assert_memory_equal(buffer, ((unsigned char[]){0xF4}), 1); 17 assert_size_equal(1, cbor_encode_bool(true, buffer, 512)); 18 assert_memory_equal(buffer, ((unsigned char[]){0xF5}), 1); 19 } 20 21 static void test_null(void** _state _CBOR_UNUSED) { 22 assert_size_equal(1, cbor_encode_null(buffer, 512)); 23 assert_memory_equal(buffer, ((unsigned char[]){0xF6}), 1); 24 } 25 26 static void test_undef(void** _state _CBOR_UNUSED) { 27 assert_size_equal(1, cbor_encode_undef(buffer, 512)); 28 assert_memory_equal(buffer, ((unsigned char[]){0xF7}), 1); 29 } 30 31 static void test_break(void** _state _CBOR_UNUSED) { 32 assert_size_equal(1, cbor_encode_break(buffer, 512)); 33 assert_memory_equal(buffer, ((unsigned char[]){0xFF}), 1); 34 } 35 36 /* Check that encode(decode(buffer)) = buffer for a valid half-float in the 37 * buffer.*/ 38 static void assert_half_float_codec_identity(void) { 39 unsigned char secondary_buffer[3]; 40 struct cbor_load_result res; 41 // Load and check data in buffer 42 cbor_item_t* half_float = cbor_load(buffer, 3, &res); 43 assert_size_equal(res.error.code, CBOR_ERR_NONE); 44 assert_true(cbor_isa_float_ctrl(half_float)); 45 assert_true(cbor_is_float(half_float)); 46 assert_size_equal(cbor_float_get_width(half_float), CBOR_FLOAT_16); 47 // Encode again and check equality 48 assert_size_equal(3, cbor_encode_half(cbor_float_get_float2(half_float), 49 secondary_buffer, 3)); 50 assert_memory_equal(buffer, secondary_buffer, 3); 51 cbor_decref(&half_float); 52 } 53 54 static void test_half(void** _state _CBOR_UNUSED) { 55 assert_size_equal(3, cbor_encode_half(1.5f, buffer, 512)); 56 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x3E, 0x00}), 3); 57 assert_half_float_codec_identity(); 58 59 assert_size_equal(3, cbor_encode_half(-0.0f, buffer, 512)); 60 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x80, 0x00}), 3); 61 assert_half_float_codec_identity(); 62 63 assert_size_equal(3, cbor_encode_half(0.0f, buffer, 512)); 64 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x00, 0x00}), 3); 65 assert_half_float_codec_identity(); 66 67 assert_size_equal(3, cbor_encode_half(65504.0f, buffer, 512)); 68 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x7B, 0xFF}), 3); 69 assert_half_float_codec_identity(); 70 71 assert_size_equal(3, cbor_encode_half(0.00006103515625f, buffer, 512)); 72 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x04, 0x00}), 3); 73 assert_half_float_codec_identity(); 74 75 assert_size_equal(3, cbor_encode_half(-4.0f, buffer, 512)); 76 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0xC4, 0x00}), 3); 77 assert_half_float_codec_identity(); 78 79 /* Smallest representable value */ 80 assert_size_equal(3, cbor_encode_half(5.960464477539063e-8f, buffer, 512)); 81 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x00, 0x01}), 3); 82 assert_half_float_codec_identity(); 83 84 /* Smaller than the smallest, approximate magnitude representation */ 85 assert_size_equal(3, cbor_encode_half(5.960464477539062e-8f, buffer, 512)); 86 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x00, 0x01}), 3); 87 assert_half_float_codec_identity(); 88 89 assert_size_equal(3, cbor_encode_half(4.172325134277344e-7f, buffer, 512)); 90 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x00, 0x07}), 3); 91 assert_half_float_codec_identity(); 92 93 assert_size_equal(3, cbor_encode_half(6.097555160522461e-5f, buffer, 512)); 94 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x03, 0xff}), 3); 95 assert_half_float_codec_identity(); 96 97 assert_size_equal(3, cbor_encode_half(6.100535392761231e-5f, buffer, 512)); 98 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x04, 0x00}), 3); 99 assert_half_float_codec_identity(); 100 101 /* Smaller than the smallest and even the magnitude cannot be represented, 102 round off to zero */ 103 assert_size_equal(3, cbor_encode_half(1e-25f, buffer, 512)); 104 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x00, 0x00}), 3); 105 assert_half_float_codec_identity(); 106 107 assert_size_equal(3, cbor_encode_half(1.1920928955078125e-7, buffer, 512)); 108 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x00, 0x02}), 3); 109 assert_half_float_codec_identity(); 110 111 assert_size_equal(3, cbor_encode_half(-1.1920928955078124e-7, buffer, 512)); 112 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x80, 0x02}), 3); 113 assert_half_float_codec_identity(); 114 115 assert_size_equal(3, cbor_encode_half(INFINITY, buffer, 512)); 116 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x7C, 0x00}), 3); 117 assert_half_float_codec_identity(); 118 } 119 120 static void test_half_special(void** _state _CBOR_UNUSED) { 121 assert_size_equal(3, cbor_encode_half(NAN, buffer, 512)); 122 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x7E, 0x00}), 3); 123 assert_half_float_codec_identity(); 124 125 assert_size_equal(3, cbor_encode_half(nanf("2"), buffer, 512)); 126 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x7E, 0x00}), 3); 127 assert_half_float_codec_identity(); 128 } 129 130 static void test_half_infinity(void** _state _CBOR_UNUSED) { 131 assert_size_equal(3, cbor_encode_half(INFINITY, buffer, 512)); 132 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x7C, 0x00}), 3); 133 assert_half_float_codec_identity(); 134 135 assert_size_equal(3, cbor_encode_half(-INFINITY, buffer, 512)); 136 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0xFC, 0x00}), 3); 137 assert_half_float_codec_identity(); 138 } 139 140 static void test_float(void** _state _CBOR_UNUSED) { 141 assert_size_equal(5, cbor_encode_single(3.4028234663852886e+38, buffer, 512)); 142 assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0x7F, 0x7F, 0xFF, 0xFF}), 143 5); 144 145 assert_size_equal(5, cbor_encode_single(NAN, buffer, 512)); 146 assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0x7F, 0xC0, 0x00, 0x00}), 147 5); 148 149 assert_size_equal(5, cbor_encode_single(nanf("3"), buffer, 512)); 150 assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0x7F, 0xC0, 0x00, 0x00}), 151 5); 152 153 assert_size_equal(5, cbor_encode_single(strtof("Inf", NULL), buffer, 512)); 154 assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0x7F, 0x80, 0x00, 0x00}), 155 5); 156 157 assert_size_equal(5, cbor_encode_single(strtof("-Inf", NULL), buffer, 512)); 158 assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0xFF, 0x80, 0x00, 0x00}), 159 5); 160 } 161 162 static void test_double(void** _state _CBOR_UNUSED) { 163 assert_size_equal(9, cbor_encode_double(1.0e+300, buffer, 512)); 164 assert_memory_equal( 165 buffer, 166 ((unsigned char[]){0xFB, 0x7E, 0x37, 0xE4, 0x3C, 0x88, 0x00, 0x75, 0x9C}), 167 9); 168 169 assert_size_equal(9, cbor_encode_double(nan(""), buffer, 512)); 170 assert_memory_equal( 171 buffer, 172 ((unsigned char[]){0xFB, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 173 9); 174 175 assert_size_equal(9, cbor_encode_double(nan("3"), buffer, 512)); 176 assert_memory_equal( 177 buffer, 178 ((unsigned char[]){0xFB, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 179 9); 180 181 assert_size_equal(9, cbor_encode_double(strtod("Inf", NULL), buffer, 512)); 182 assert_memory_equal( 183 buffer, 184 ((unsigned char[]){0xFB, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 185 9); 186 187 assert_size_equal(9, cbor_encode_double(strtod("-Inf", NULL), buffer, 512)); 188 assert_memory_equal( 189 buffer, 190 ((unsigned char[]){0xFB, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 191 9); 192 } 193 194 int main(void) { 195 const struct CMUnitTest tests[] = { 196 cmocka_unit_test(test_bools), cmocka_unit_test(test_null), 197 cmocka_unit_test(test_undef), cmocka_unit_test(test_break), 198 cmocka_unit_test(test_half), cmocka_unit_test(test_float), 199 cmocka_unit_test(test_double), cmocka_unit_test(test_half_special), 200 cmocka_unit_test(test_half_infinity), 201 }; 202 return cmocka_run_group_tests(tests, NULL, NULL); 203 } 204