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
test_bools(void ** _state _CBOR_UNUSED)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
test_null(void ** _state _CBOR_UNUSED)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
test_undef(void ** _state _CBOR_UNUSED)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
test_break(void ** _state _CBOR_UNUSED)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.*/
assert_half_float_codec_identity(void)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
test_half(void ** _state _CBOR_UNUSED)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
test_half_special(void ** _state _CBOR_UNUSED)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
test_half_infinity(void ** _state _CBOR_UNUSED)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
test_float(void ** _state _CBOR_UNUSED)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
test_double(void ** _state _CBOR_UNUSED)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
main(void)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