Code

data_test: Fixed access to uninitialized memory.
[sysdb.git] / t / unit / core / data_test.c
1 /*
2  * SysDB - t/unit/core/data_test.c
3  * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 #include "core/data.h"
29 #include "libsysdb_test.h"
31 #include <check.h>
33 START_TEST(test_data)
34 {
35         sdb_data_t d1, d2;
36         int check;
38         d2.type = SDB_TYPE_INTEGER;
39         d2.data.integer = 4711;
40         memset(&d1, 0, sizeof(d1));
41         check = sdb_data_copy(&d1, &d2);
42         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
43         fail_unless(d1.type == d2.type,
44                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
45                         d1.type, d2.type);
46         fail_unless(d1.data.integer == d2.data.integer,
47                         "sdb_data_copy() didn't copy integer data: got: %d; expected: %d",
48                         d1.data.integer, d2.data.integer);
50         d2.type = SDB_TYPE_DECIMAL;
51         d2.data.decimal = 47.11;
52         check = sdb_data_copy(&d1, &d2);
53         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
54         fail_unless(d1.type == d2.type,
55                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
56                         d1.type, d2.type);
57         fail_unless(d1.data.decimal == d2.data.decimal,
58                         "sdb_data_copy() didn't copy decimal data: got: %f; expected: %f",
59                         d1.data.decimal, d2.data.decimal);
61         d2.type = SDB_TYPE_STRING;
62         d2.data.string = "some string";
63         check = sdb_data_copy(&d1, &d2);
64         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
65         fail_unless(d1.type == d2.type,
66                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
67                         d1.type, d2.type);
68         fail_unless(!strcmp(d1.data.string, d2.data.string),
69                         "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
70                         d1.data.string, d2.data.string);
72         sdb_data_free_datum(&d1);
73         fail_unless(d1.data.string == NULL,
74                         "sdb_data_free_datum() didn't free string data");
76         d2.type = SDB_TYPE_DATETIME;
77         d2.data.datetime = 4711;
78         check = sdb_data_copy(&d1, &d2);
79         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
80         fail_unless(d1.type == d2.type,
81                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
82                         d1.type, d2.type);
83         fail_unless(d1.data.datetime == d2.data.datetime,
84                         "sdb_data_copy() didn't copy datetime data: got: %d; expected: %d",
85                         d1.data.datetime, d2.data.datetime);
87         d2.type = SDB_TYPE_BINARY;
88         d2.data.binary.datum = (unsigned char *)"some string";
89         d2.data.binary.length = strlen((const char *)d2.data.binary.datum);
90         check = sdb_data_copy(&d1, &d2);
91         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
92         fail_unless(d1.type == d2.type,
93                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
94                         d1.type, d2.type);
95         fail_unless(d1.data.binary.length == d2.data.binary.length,
96                         "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
97                         d1.data.binary.length, d2.data.binary.length);
98         fail_unless(!memcmp(d1.data.binary.datum, d2.data.binary.datum,
99                                 d2.data.binary.length),
100                         "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
101                         d1.data.string, d2.data.string);
103         sdb_data_free_datum(&d1);
104         fail_unless(d1.data.binary.length == 0,
105                         "sdb_data_free_datum() didn't reset binary datum length");
106         fail_unless(d1.data.binary.datum == NULL,
107                         "sdb_data_free_datum() didn't free binary datum");
109 END_TEST
111 START_TEST(test_cmp)
113         struct {
114                 sdb_data_t d1;
115                 sdb_data_t d2;
116                 int expected;
117         } golden_data[] = {
118                 {
119                         { SDB_TYPE_INTEGER, { .integer = 47 } },
120                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
121                         -1,
122                 },
123                 {
124                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
125                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
126                         0,
127                 },
128                 {
129                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
130                         { SDB_TYPE_INTEGER, { .integer = 47 } },
131                         1,
132                 },
133                 {
134                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
135                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
136                         -1,
137                 },
138                 {
139                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
140                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
141                         0,
142                 },
143                 {
144                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
145                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
146                         1,
147                 },
148                 {
149                         { SDB_TYPE_STRING, { .string = NULL } },
150                         { SDB_TYPE_STRING, { .string = "" } },
151                         -1,
152                 },
153                 {
154                         { SDB_TYPE_STRING, { .string = NULL } },
155                         { SDB_TYPE_STRING, { .string = NULL } },
156                         0,
157                 },
158                 {
159                         { SDB_TYPE_STRING, { .string = "" } },
160                         { SDB_TYPE_STRING, { .string = NULL } },
161                         1,
162                 },
163                 {
164                         { SDB_TYPE_STRING, { .string = "a" } },
165                         { SDB_TYPE_STRING, { .string = "b" } },
166                         -1,
167                 },
168                 {
169                         { SDB_TYPE_STRING, { .string = "a" } },
170                         { SDB_TYPE_STRING, { .string = "ab" } },
171                         -1,
172                 },
173                 {
174                         { SDB_TYPE_STRING, { .string = "a" } },
175                         { SDB_TYPE_STRING, { .string = "a" } },
176                         0,
177                 },
178                 {
179                         { SDB_TYPE_STRING, { .string = "b" } },
180                         { SDB_TYPE_STRING, { .string = "a" } },
181                         1,
182                 },
183                 {
184                         { SDB_TYPE_STRING, { .string = "ab" } },
185                         { SDB_TYPE_STRING, { .string = "a" } },
186                         1,
187                 },
188                 {
189                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
190                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
191                         -1,
192                 },
193                 {
194                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
195                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
196                         0,
197                 },
198                 {
199                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
200                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
201                         1,
202                 },
203                 {
204                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
205                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
206                         -1,
207                 },
208                 {
209                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
210                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
211                         0,
212                 },
213                 {
214                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
215                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
216                         1,
217                 },
218                 {
219                         {
220                                 SDB_TYPE_BINARY,
221                                 { .binary = { 3, (unsigned char *)"a\0a" } },
222                         },
223                         {
224                                 SDB_TYPE_BINARY,
225                                 { .binary = { 3, (unsigned char *)"a\0b" } },
226                         },
227                         -1,
228                 },
229                 {
230                         {
231                                 SDB_TYPE_BINARY,
232                                 { .binary = { 1, (unsigned char *)"a" } },
233                         },
234                         {
235                                 SDB_TYPE_BINARY,
236                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
237                         },
238                         -1,
239                 },
240                 {
241                         {
242                                 SDB_TYPE_BINARY,
243                                 { .binary = { 3, (unsigned char *)"a\0a" } },
244                         },
245                         {
246                                 SDB_TYPE_BINARY,
247                                 { .binary = { 3, (unsigned char *)"a\0a" } },
248                         },
249                         0,
250                 },
251                 {
252                         {
253                                 SDB_TYPE_BINARY,
254                                 { .binary = { 3, (unsigned char *)"a\0b" } },
255                         },
256                         {
257                                 SDB_TYPE_BINARY,
258                                 { .binary = { 3, (unsigned char *)"a\0a" } },
259                         },
260                         1,
261                 },
262                 {
263                         {
264                                 SDB_TYPE_BINARY,
265                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
266                         },
267                         {
268                                 SDB_TYPE_BINARY,
269                                 { .binary = { 1, (unsigned char *)"a" } },
270                         },
271                         1,
272                 },
273         };
275         size_t i;
277         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
278                 int check = sdb_data_cmp(&golden_data[i].d1, &golden_data[i].d2);
279                 check = check < 0 ? -1 : check > 0 ? 1 : 0;
280                 if (check != golden_data[i].expected) {
281                         char d1_str[64] = "", d2_str[64] = "";
282                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
283                                         SDB_DOUBLE_QUOTED);
284                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
285                                         SDB_DOUBLE_QUOTED);
286                         fail("sdb_data_cmp(%s, %s) = %d; expected: %d",
287                                         d1_str, d2_str, check, golden_data[i].expected);
288                 }
289         }
291 END_TEST
293 START_TEST(test_format)
295         struct {
296                 sdb_data_t datum;
297                 const char *expected;
298         } golden_data[] = {
299                 {
300                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
301                         "4711",
302                 },
303                 {
304                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
305                         "0x1p+16",
306                 },
307                 {
308                         { SDB_TYPE_STRING, { .string = NULL } },
309                         "\"NULL\"",
310                 },
311                 {
312                         { SDB_TYPE_STRING, { .string = "this is a test" } },
313                         "\"this is a test\"",
314                 },
315                 {
316                         { SDB_TYPE_STRING, { .string = "special \\ \" characters" } },
317                         "\"special \\\\ \\\" characters\"",
318                 },
319                 {
320                         { SDB_TYPE_DATETIME, { .datetime= 471147114711471100 } },
321                         "\"1984-12-06 02:11:54 +0000\"",
322                 },
323                 {
324                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
325                         "\"\"",
326                 },
327                 {
328                         {
329                                 SDB_TYPE_BINARY,
330                                 { .binary = { 12, (unsigned char *)"binary\0crap\x42" } },
331                         },
332                         "\"\\x62\\x69\\x6e\\x61\\x72\\x79\\x0\\x63\\x72\\x61\\x70\\x42\"",
333                 },
334         };
336         size_t i;
338         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
339                 sdb_data_t *datum = &golden_data[i].datum;
340                 char buf[sdb_data_strlen(datum) + 2];
341                 int check;
343                 memset(buf, (int)'A', sizeof(buf));
345                 check = sdb_data_format(datum, buf, sizeof(buf) - 1,
346                                 SDB_DOUBLE_QUOTED);
347                 fail_unless(check > 0,
348                                 "sdb_data_format(type=%s) = %d; expected: >0",
349                                 SDB_TYPE_TO_STRING(datum->type), check);
350                 fail_unless(! strcmp(buf, golden_data[i].expected),
351                                 "sdb_data_format(type=%s) used wrong format: %s; expected: %s",
352                                 SDB_TYPE_TO_STRING(datum->type), buf, golden_data[i].expected);
354                 fail_unless((size_t)check <= sizeof(buf) - 2,
355                                 "sdb_data_format(type=%s) wrote %d bytes; "
356                                 "expected <= %zu based on sdb_data_strlen()",
357                                 SDB_TYPE_TO_STRING(datum->type), check, sizeof(buf) - 2);
359                 fail_unless(buf[sizeof(buf) - 2] == '\0',
360                                 "sdb_data_format(type=%s) did not nul-terminate the buffer",
361                                 SDB_TYPE_TO_STRING(datum->type));
362                 fail_unless(buf[sizeof(buf) - 1] == 'A',
363                                 "sdb_data_format(type=%s) wrote past the end of the buffer",
364                                 SDB_TYPE_TO_STRING(datum->type));
365         }
367 END_TEST
369 START_TEST(test_parse)
371         struct {
372                 char *input;
373                 sdb_data_t result;
374                 int expected;
375         } golden_data[] = {
376                 { "4711",    { SDB_TYPE_INTEGER,  { .integer  = 4711 } },       0 },
377                 { "0x10",    { SDB_TYPE_INTEGER,  { .integer  = 16 } },         0 },
378                 { "010",     { SDB_TYPE_INTEGER,  { .integer  = 8 } },          0 },
379                 { "abc",     { SDB_TYPE_INTEGER,  { .integer  = 0 } },         -1 },
380                 { "1.2",     { SDB_TYPE_DECIMAL,  { .decimal  = 1.2 } },        0 },
381                 { "0x1p+16", { SDB_TYPE_DECIMAL,  { .decimal  = 65536.0 } },    0 },
382                 { "abc",     { SDB_TYPE_DECIMAL,  { .decimal  = 0.0 } },       -1 },
383                 { "abc",     { SDB_TYPE_STRING,   { .string   = "abc" } },      0 },
384                 { ".4",      { SDB_TYPE_DATETIME, { .datetime = 400000000 } },  0 },
385                 { "abc",     { SDB_TYPE_DATETIME, { .datetime = 0 } },         -1 },
386                 { "abc",     { SDB_TYPE_BINARY,
387                                          { .binary = { 3, (unsigned char *)"abc" } } }, 0 },
388         };
390         size_t i;
392         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
393                 sdb_data_t result;
394                 int type, check;
396                 memset(&result, 0, sizeof(result));
397                 type = golden_data[i].result.type;
398                 check = sdb_data_parse(golden_data[i].input, type, &result);
399                 fail_unless(check == golden_data[i].expected,
400                                 "sdb_data_parse(%s, %d, <d>) = %d; expected: %d",
401                                 golden_data[i].input, type, check, golden_data[i].expected);
403                 if (check)
404                         continue;
406                 fail_unless(sdb_data_cmp(&result, &golden_data[i].result) == 0,
407                                 "sdb_data_parse(%s, %d, <d>) did not create expected result",
408                                 golden_data[i].input, type);
410                 if (type == SDB_TYPE_STRING)
411                         fail_unless(golden_data[i].input == result.data.string,
412                                         "sdb_data_parse(%s, %d, <d>) modified input string",
413                                         golden_data[i].input, type);
414                 if (type == SDB_TYPE_BINARY)
415                         fail_unless(golden_data[i].input == (char *)result.data.binary.datum,
416                                         "sdb_data_parse(%s, %d, <d>) modified input string",
417                                         golden_data[i].input, type);
418         }
420 END_TEST
422 Suite *
423 core_data_suite(void)
425         Suite *s = suite_create("core::data");
426         TCase *tc;
428         tc = tcase_create("core");
429         tcase_add_test(tc, test_data);
430         tcase_add_test(tc, test_cmp);
431         tcase_add_test(tc, test_format);
432         tcase_add_test(tc, test_parse);
433         suite_add_tcase(s, tc);
435         return s;
436 } /* core_data_suite */
438 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */