novi upstream verzije 2.8.3
[ossec-hids.git] / src / tests / test_os_xml.c
1 /* Copyright (C) 2014 Trend Micro Inc.
2  * All rights reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #include <check.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <unistd.h>
14
15 #include "../os_xml/os_xml.h"
16 #include "../os_xml/os_xml_internal.h"
17
18 Suite *test_suite(void);
19
20 static void create_xml_file(const char *str, char file_name[], size_t length)
21 {
22     strncpy(file_name, "/tmp/tmp_file-XXXXXX", length);
23     int fd = mkstemp(file_name);
24
25     write(fd, str, strlen(str));
26     close(fd);
27 }
28
29 static void nodecat(XML_NODE node, OS_XML *xml, char *buffer) {
30     int i = 0;
31     /* write node */
32     while(node[i])
33     {
34         strncat(buffer, "<", 1);
35         ck_assert_ptr_ne(node[i]->element, NULL);
36         strncat(buffer, node[i]->element, strlen(node[i]->element));
37         /* write attributes */
38         if(node[i]->attributes)
39         {
40             ck_assert_ptr_ne(node[i]->values, NULL);
41             int j = 0;
42             while(node[i]->attributes[j])
43             {
44                 strncat(buffer, " ", 1);
45                 ck_assert_ptr_ne(node[i]->values[j], NULL);
46                 strncat(buffer, node[i]->attributes[j], strlen(node[i]->attributes[j]));
47                 strncat(buffer, "=", 1);
48                 strncat(buffer, "\"", 1);
49                 strncat(buffer, node[i]->values[j], strlen(node[i]->values[j]));
50                 strncat(buffer, "\"", 1);
51                 j++;
52             }
53             ck_assert_ptr_eq(node[i]->values[j], NULL);
54         }
55         else
56         {
57             ck_assert_ptr_eq(node[i]->values, NULL);
58         }
59         strncat(buffer, ">", 1);
60         ck_assert_ptr_ne(node[i]->content, NULL);
61         strncat(buffer, node[i]->content, strlen(node[i]->content));
62
63         /* write children */
64         XML_NODE child = OS_GetElementsbyNode(xml, node[i]);
65         if(child != NULL)
66         {
67             nodecat(child, xml, buffer);
68             OS_ClearNode(child);
69         }
70
71         /* close node */
72         strncat(buffer, "</", 2);
73         strncat(buffer, node[i]->element, strlen(node[i]->element));
74         strncat(buffer, ">", 1);
75         i++;
76     }
77 }
78
79 static void assert_os_xml_eq_str(OS_XML *xml, const char *xml_str)
80 {
81     XML_NODE node = OS_GetElementsbyNode(xml, NULL);
82     if(node == NULL)
83     {
84         ck_assert_str_eq(xml_str, "");
85         return;
86     }
87
88     char *buffer = (char *) malloc(6144 * sizeof(char));
89     buffer[0] = '\0';
90     nodecat(node, xml, buffer);
91     OS_ClearNode(node);
92
93     ck_assert_str_eq(buffer, xml_str);
94
95     free(buffer);
96 }
97
98 #define assert_os_xml_eq(PARSE_STR, XML_STR) do { \
99     char _ck_xml_file_name[256]; \
100     create_xml_file(PARSE_STR, _ck_xml_file_name, 256); \
101     OS_XML _ck_xml; \
102     ck_assert_int_eq(OS_ReadXML(_ck_xml_file_name, &_ck_xml), 0); \
103     ck_assert_int_eq(OS_ApplyVariables(&_ck_xml), 0); \
104     assert_os_xml_eq_str(&_ck_xml, XML_STR); \
105     OS_ClearXML(&_ck_xml); \
106     unlink(_ck_xml_file_name); \
107 } while (0)
108
109 START_TEST(test_simplenodes)
110 {
111     assert_os_xml_eq("", "");
112     assert_os_xml_eq("<root></root>", "<root></root>");
113     assert_os_xml_eq("<root/>", "<root></root>");
114     assert_os_xml_eq("<root />", "<root></root>");
115 }
116 END_TEST
117
118
119 START_TEST(test_multiplenodes)
120 {
121     assert_os_xml_eq(
122             "<root1></root1>"
123             "<root2></root2>"
124             "<root3/>",
125             "<root1></root1>"
126             "<root2></root2>"
127             "<root3></root3>");
128 }
129 END_TEST
130
131 START_TEST(test_children)
132 {
133     assert_os_xml_eq(
134             "<root1>"
135             "<child1></child1>"
136             "</root1>"
137             "<root2>"
138             "<child1></child1>"
139             "<child2/>"
140             "<child3>"
141             "<child3.1></child3.1>"
142             "</child3>"
143             "</root2>"
144             "<root3></root3>",
145             "<root1>"
146             "<child1></child1>"
147             "</root1>"
148             "<root2>"
149             "<child1></child1>"
150             "<child2></child2>"
151             "<child3>"
152             "<child3.1></child3.1>"
153             "</child3>"
154             "</root2>"
155             "<root3></root3>");
156 }
157 END_TEST
158
159 START_TEST(test_multiplecontent)
160 {
161     assert_os_xml_eq(
162             "<root>"
163             "value1"
164             "<child/>"
165             "</root>",
166             "<root><child></child></root>");
167     assert_os_xml_eq(
168             "<root>"
169             "value1"
170             "<child/>"
171             "value2"
172             "</root>",
173             "<root>value2<child></child></root>");
174 }
175 END_TEST
176
177
178 START_TEST(test_attributes)
179 {
180     assert_os_xml_eq(
181             "<root attr1=\"test\" attr2=\"1\"></root>",
182             "<root attr1=\"test\" attr2=\"1\"></root>");
183
184     assert_os_xml_eq(
185             "<root attr1=\"test\"\nattr2=\"test\"\tattr3=\"test\"></root>",
186             "<root attr1=\"test\" attr2=\"test\" attr3=\"test\"></root>");
187
188     assert_os_xml_eq(
189             "<root attr1=\"test/test\"></root>",
190             "<root attr1=\"test/test\"></root>");
191
192     assert_os_xml_eq(
193             "<root attr1=\"test1\"></root><root attr1=\"test2\"></root>",
194             "<root attr1=\"test1\"></root><root attr1=\"test2\"></root>");
195
196     assert_os_xml_eq(
197             "<root attr1=\"test\"\n\t  \t\n  \n\t  \nattr2=\"test\"></root>",
198             "<root attr1=\"test\" attr2=\"test\"></root>");
199
200     assert_os_xml_eq(
201             "<root\n\t  \t\n  \n\t  \nattr1=\"test\"></root>",
202             "<root attr1=\"test\"></root>");
203
204     assert_os_xml_eq(
205             "<root attr1=\n\t  \t\n  \n\t  \n\"test\"></root>",
206             "<root attr1=\"test\"></root>");
207
208     assert_os_xml_eq(
209             "<root attr=\"test\" />",
210             "<root attr=\"test\"></root>");
211
212     assert_os_xml_eq(
213             "<root attr=\"test\"/>",
214             "<root attr=\"test\"></root>");
215 }
216 END_TEST
217
218 START_TEST(test_variables)
219 {
220     assert_os_xml_eq(
221             "<var name=\"var1\">value1</var>"
222             "<var name=\"var2\">value2</var>"
223             "<root attr1=\"$var1\" attr2=\"1\">$var2</root>"
224             "<root attr1=\"blah$var1\" attr2=\"1\">blah$var2</root>"
225             "<root attr1=\"blah$var1$var2 blah\" attr2=\"1\">blah$var2$var1 blah</root>",
226             "<root attr1=\"value1\" attr2=\"1\">value2</root>"
227             "<root attr1=\"blahvalue1\" attr2=\"1\">blahvalue2</root>"
228             "<root attr1=\"blahvalue1value2 blah\" attr2=\"1\">blahvalue2value1 blah</root>");
229 }
230 END_TEST
231
232 START_TEST(test_comments)
233 {
234     assert_os_xml_eq(
235             "<root1/><!comment!><root2/>",
236             "<root1></root1><root2></root2>");
237     assert_os_xml_eq(
238             "<root1/><!--comment--><root2/>",
239             "<root1></root1><root2></root2>");
240
241     assert_os_xml_eq(
242             "<root1/><! comment with ! !><root2/>",
243             "<root1></root1><root2></root2>");
244
245     assert_os_xml_eq(
246             "<root1/><! comment with - --><root2/>",
247             "<root1></root1><root2></root2>");
248 }
249 END_TEST
250
251 START_TEST(test_specialchars)
252 {
253     assert_os_xml_eq(
254             "<var name=\"var1\">value1</var>"
255             "<root1>\\</root1\\></root1>",
256             "<root1>\\</root1\\></root1>");
257 }
258 END_TEST
259
260 START_TEST(test_linecounter)
261 {
262     char xml_file_name[256];
263     create_xml_file("<root1/>\n<root2/>\n<root3/>" , xml_file_name, 256);
264     OS_XML xml;
265     XML_NODE node;
266     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
267     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
268     ck_assert_ptr_ne(node = OS_GetElementsbyNode(&xml, NULL), NULL);
269     ck_assert_int_eq(xml.ln[0], 1);
270     ck_assert_int_eq(xml.ln[1], 2);
271     ck_assert_int_eq(xml.ln[2], 3);
272
273     OS_ClearNode(node);
274     OS_ClearXML(&xml);
275     unlink(xml_file_name);
276 }
277 END_TEST
278
279 START_TEST(test_invalidfile)
280 {
281     OS_XML xml;
282     ck_assert_int_ne(OS_ReadXML("invalid_file.inv", &xml), 0);
283     ck_assert_str_eq(xml.err, "XMLERR: File 'invalid_file.inv' not found.");
284     ck_assert_int_eq(xml.err_line, 0);
285
286     OS_ClearXML(&xml);
287 }
288 END_TEST
289
290 START_TEST(test_unclosednode)
291 {
292     char xml_file_name[256];
293     create_xml_file("<root>", xml_file_name, 256);
294     OS_XML xml;
295     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
296     ck_assert_str_eq(xml.err, "XMLERR: End of file and some elements were not closed.");
297     ck_assert_int_eq(xml.err_line, 1);
298
299     OS_ClearXML(&xml);
300     unlink(xml_file_name);
301 }
302 END_TEST
303
304 START_TEST(test_unclosednode2)
305 {
306     char xml_file_name[256];
307     create_xml_file("<root></root2>", xml_file_name, 256);
308     OS_XML xml;
309     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
310     ck_assert_str_eq(xml.err, "XMLERR: Element 'root' not closed.");
311     ck_assert_int_eq(xml.err_line, 1);
312
313     OS_ClearXML(&xml);
314     unlink(xml_file_name);
315 }
316 END_TEST
317
318 START_TEST(test_unclosedcomment)
319 {
320     char xml_file_name[256];
321     create_xml_file("<!-- comment", xml_file_name, 256);
322     OS_XML xml;
323     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
324     ck_assert_str_eq(xml.err, "XMLERR: Comment not closed.");
325     ck_assert_int_eq(xml.err_line, 1);
326
327     OS_ClearXML(&xml);
328     unlink(xml_file_name);
329 }
330 END_TEST
331
332 START_TEST(test_nodenotopened)
333 {
334     char xml_file_name[256];
335     create_xml_file("</root>", xml_file_name, 256);
336     OS_XML xml;
337     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
338     ck_assert_str_eq(xml.err, "XMLERR: Element not opened.");
339     ck_assert_int_eq(xml.err_line, 1);
340
341     OS_ClearXML(&xml);
342     unlink(xml_file_name);
343 }
344 END_TEST
345
346 START_TEST(test_unclosedattribute)
347 {
348     char xml_file_name[256];
349     create_xml_file("<root attr=\"attribute></root>", xml_file_name, 256);
350     OS_XML xml;
351     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
352     ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' not closed.");
353     ck_assert_int_eq(xml.err_line, 1);
354
355     OS_ClearXML(&xml);
356     unlink(xml_file_name);
357 }
358 END_TEST
359
360 START_TEST(test_unquotedattribute)
361 {
362     char xml_file_name[256];
363     create_xml_file("<root attr=attribute></root>", xml_file_name, 256);
364     OS_XML xml;
365     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
366     ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' not followed by a \" or '.");
367     ck_assert_int_eq(xml.err_line, 1);
368
369     OS_ClearXML(&xml);
370     unlink(xml_file_name);
371 }
372 END_TEST
373
374 START_TEST(test_infiniteattribute)
375 {
376     char xml_file_name[256];
377     create_xml_file("<root attr", xml_file_name, 256);
378     OS_XML xml;
379     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
380     ck_assert_str_eq(xml.err, "XMLERR: End of file while reading an attribute.");
381     ck_assert_int_eq(xml.err_line, 1);
382
383     OS_ClearXML(&xml);
384     unlink(xml_file_name);
385 }
386 END_TEST
387
388 START_TEST(test_invalidvariablename)
389 {
390     char xml_file_name[256];
391     create_xml_file("<var test=\"test\"></var>", xml_file_name, 256);
392     OS_XML xml;
393     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
394     ck_assert_int_ne(OS_ApplyVariables(&xml), 0);
395     ck_assert_str_eq(xml.err, "XMLERR: Only \"name\" is allowed as an attribute for a variable.");
396     ck_assert_int_eq(xml.err_line, 1);
397
398     OS_ClearXML(&xml);
399     unlink(xml_file_name);
400 }
401 END_TEST
402
403 START_TEST(test_invalidvariable)
404 {
405     char xml_file_name[256];
406     char overflow_string[XML_VARIABLE_MAXSIZE + 10];
407     memset(overflow_string, 'c', XML_VARIABLE_MAXSIZE + 9);
408     overflow_string[XML_VARIABLE_MAXSIZE + 9] = '\0';
409
410     char xml_string[2 * XML_VARIABLE_MAXSIZE];
411     snprintf(xml_string, 2 * XML_VARIABLE_MAXSIZE - 1, "<var name=\"%s\">test</var><root/>", overflow_string);
412     create_xml_file(xml_string, xml_file_name, 256);
413     OS_XML xml;
414     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
415     ck_assert_int_ne(OS_ApplyVariables(&xml), 0);
416     ck_assert_str_eq(xml.err, "XMLERR: Invalid variable name size.");
417     ck_assert_int_eq(xml.err_line, 1);
418
419     OS_ClearXML(&xml);
420     unlink(xml_file_name);
421 }
422 END_TEST
423
424 START_TEST(test_invalidvariable2)
425 {
426     char xml_file_name[256];
427     char overflow_string[XML_VARIABLE_MAXSIZE + 10];
428     memset(overflow_string, 'c', XML_VARIABLE_MAXSIZE + 9);
429     overflow_string[XML_VARIABLE_MAXSIZE + 9] = '\0';
430
431     char xml_string[3 * XML_VARIABLE_MAXSIZE];
432     snprintf(xml_string, 3 * XML_VARIABLE_MAXSIZE - 1, "<var name=\"%s\">test</var><test>$%s</test>", overflow_string, overflow_string);
433     create_xml_file(xml_string, xml_file_name, 256);
434     OS_XML xml;
435     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
436     ck_assert_int_ne(OS_ApplyVariables(&xml), 0);
437     ck_assert_str_eq(xml.err, "XMLERR: Invalid variable name size.");
438     ck_assert_int_eq(xml.err_line, 1);
439
440     OS_ClearXML(&xml);
441     unlink(xml_file_name);
442 }
443 END_TEST
444
445 START_TEST(test_unknownvariable)
446 {
447     char xml_file_name[256];
448     create_xml_file("<var name=\"test\">content</var><root>$var</root>", xml_file_name, 256);
449     OS_XML xml;
450     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
451     ck_assert_int_ne(OS_ApplyVariables(&xml), 0);
452     ck_assert_str_eq(xml.err, "XMLERR: Unknown variable: 'var'.");
453     ck_assert_int_eq(xml.err_line, 1);
454
455     OS_ClearXML(&xml);
456     unlink(xml_file_name);
457 }
458 END_TEST
459
460 START_TEST(test_infiniteattribute2)
461 {
462     char xml_file_name[256];
463     create_xml_file("<root attr=", xml_file_name, 256);
464     OS_XML xml;
465     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
466     ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' not followed by a \" or '.");
467     ck_assert_int_eq(xml.err_line, 1);
468
469     OS_ClearXML(&xml);
470     unlink(xml_file_name);
471 }
472 END_TEST
473
474 START_TEST(test_invalidattributestart)
475 {
476     char xml_file_name[256];
477     create_xml_file("<root attr=  test\"test\"/>", xml_file_name, 256);
478     OS_XML xml;
479     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
480     ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' not followed by a \" or '.");
481     ck_assert_int_eq(xml.err_line, 1);
482
483     OS_ClearXML(&xml);
484     unlink(xml_file_name);
485 }
486 END_TEST
487
488 START_TEST(test_invalidattributeclosing)
489 {
490     char xml_file_name[256];
491     create_xml_file("<root attr=''", xml_file_name, 256);
492     OS_XML xml;
493     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
494     ck_assert_str_eq(xml.err, "XMLERR: Bad attribute closing for 'attr'=''.");
495     ck_assert_int_eq(xml.err_line, 1);
496
497     OS_ClearXML(&xml);
498     unlink(xml_file_name);
499 }
500 END_TEST
501
502 START_TEST(test_invalidattributeclosing2)
503 {
504     char xml_file_name[256];
505     create_xml_file("<root attr='test'test/>", xml_file_name, 256);
506     OS_XML xml;
507     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
508     ck_assert_str_eq(xml.err, "XMLERR: Bad attribute closing for 'attr'='test'.");
509     ck_assert_int_eq(xml.err_line, 1);
510
511     OS_ClearXML(&xml);
512     unlink(xml_file_name);
513 }
514 END_TEST
515
516 START_TEST(test_infiniteattribute3)
517 {
518     char xml_file_name[256];
519     create_xml_file("<root attr='", xml_file_name, 256);
520     OS_XML xml;
521     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
522     ck_assert_str_eq(xml.err, "XMLERR: End of file while reading an attribute.");
523     ck_assert_int_eq(xml.err_line, 1);
524
525     OS_ClearXML(&xml);
526     unlink(xml_file_name);
527 }
528 END_TEST
529
530 START_TEST(test_duplicateattribute)
531 {
532     char xml_file_name[256];
533     create_xml_file("<root attr='test' attr2='test' attr='test123'></root>", xml_file_name, 256);
534     OS_XML xml;
535     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
536     ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' already defined.");
537     ck_assert_int_eq(xml.err_line, 1);
538
539     OS_ClearXML(&xml);
540     unlink(xml_file_name);
541 }
542 END_TEST
543
544 START_TEST(test_noattributevalue)
545 {
546     char xml_file_name[256];
547     create_xml_file("<root attr></root>", xml_file_name, 256);
548     OS_XML xml;
549     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
550     ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' has no value.");
551     ck_assert_int_eq(xml.err_line, 1);
552
553     OS_ClearXML(&xml);
554     unlink(xml_file_name);
555 }
556 END_TEST
557
558 START_TEST(test_noattributevalue2)
559 {
560     char xml_file_name[256];
561     create_xml_file("<root attr attr2='test'></root>", xml_file_name, 256);
562     OS_XML xml;
563     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
564     ck_assert_str_eq(xml.err, "XMLERR: Attribute 'attr' has no value.");
565     ck_assert_int_eq(xml.err_line, 1);
566
567     OS_ClearXML(&xml);
568     unlink(xml_file_name);
569 }
570 END_TEST
571
572 //TODO
573 /*START_TEST(test_unknownvariable)
574 {
575     char xml_file_name[256];
576     create_xml_file("<root>$var</root>", xml_file_name, 256);
577     OS_XML xml;
578     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
579     ck_assert_int_ne(OS_ApplyVariables(&xml), 0);
580     ck_assert_str_eq(xml.err, "XML_ERR: Unknown variable: var");
581     ck_assert_int_eq(xml.err_line, 0);
582
583     OS_ClearXML(&xml);
584     unlink(xml_file_name);
585 }
586 END_TEST*/
587
588 START_TEST(test_oselementsexists)
589 {
590     char xml_file_name[256];
591     create_xml_file("<root></root><root1/><root/>", xml_file_name, 256);
592     OS_XML xml;
593     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
594     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
595     ck_assert_int_eq(OS_RootElementExist(&xml, "root"), 2);
596     ck_assert_int_eq(OS_RootElementExist(&xml, "root1"), 1);
597     ck_assert_int_eq(OS_RootElementExist(&xml, "root2"), 0);
598
599     OS_ClearXML(&xml);
600     unlink(xml_file_name);
601 }
602 END_TEST
603
604 START_TEST(test_osgetonecontentforelement)
605 {
606     char xml_file_name[256];
607     create_xml_file("<root><child>test</child><child>test2</child><child2>test</child2></root>", xml_file_name, 256);
608     OS_XML xml;
609     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
610     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
611     const char *xml_path1[] = { "root", "child", NULL };
612     const char *xml_path2[] = { "root", "child2", NULL };
613     const char *xml_path3[] = { "root", "child3", NULL };
614     char *content1, *content2;
615     ck_assert_str_eq(content1 = OS_GetOneContentforElement(&xml, xml_path1), "test");
616     ck_assert_str_eq(content2 = OS_GetOneContentforElement(&xml, xml_path2), "test");
617     ck_assert_ptr_eq(OS_GetOneContentforElement(&xml, xml_path3), NULL);
618
619     free(content1);
620     free(content2);
621     OS_ClearXML(&xml);
622     unlink(xml_file_name);
623 }
624 END_TEST
625
626 static void assert_ox_xml_write_eq(const char *xml_str_old, const char *xml_str_new,const char **xml_path, const char *oldval, const char *newval)
627 {
628     char xml_in_file_name[256];
629     create_xml_file(xml_str_old, xml_in_file_name, 256);
630     char xml_out_file_name[256];
631     create_xml_file("", xml_out_file_name, 256);
632
633     ck_assert_int_eq(OS_WriteXML(xml_in_file_name, xml_out_file_name, xml_path, oldval, newval), 0);
634
635     OS_XML xml;
636     ck_assert_int_eq(OS_ReadXML(xml_out_file_name, &xml), 0);
637     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
638     assert_os_xml_eq_str(&xml, xml_str_new);
639
640     OS_ClearXML(&xml);
641     unlink(xml_in_file_name);
642     unlink(xml_out_file_name);
643 }
644
645 START_TEST(test_oswritexml_success)
646 {
647     const char *xml_path[] = { "root", "child", NULL };
648     assert_ox_xml_write_eq(
649             "<root><child>test</child></root>",
650             "<root><child>test_new</child></root>",
651             xml_path, "test", "test_new");
652
653     assert_ox_xml_write_eq(
654             "<root><child>test</child></root>",
655             "<root><child>test</child></root>",
656             xml_path, "test", "test");
657
658     assert_ox_xml_write_eq(
659             "<root><child></child></root>",
660             "<root><child>test</child></root>",
661             xml_path, "test", "test");
662
663     assert_ox_xml_write_eq(
664                 "<root2><child></child></root2>",
665                 "<root2><child></child></root2><root>\n <child>test</child></root>",
666                 xml_path, NULL, "test");
667 }
668 END_TEST
669
670 START_TEST(test_oswritexml_failures)
671 {
672     char xml_in_file_name[256];
673     create_xml_file("<root><child>test</child></root>", xml_in_file_name, 256);
674     char xml_out_file_name[256];
675     create_xml_file("", xml_out_file_name, 256);
676     const char *xml_path[] = { "root", "child", NULL };
677
678     ck_assert_int_eq(OS_WriteXML("invalid", xml_out_file_name, xml_path, "test", "test_new"), XMLW_NOIN);
679     ck_assert_int_eq(OS_WriteXML(xml_in_file_name, "??invalid<<!!\"\"//\\\\", xml_path, "test", "test_new"), XMLW_NOOUT);
680
681     unlink(xml_in_file_name);
682     unlink(xml_out_file_name);
683 }
684 END_TEST
685
686 START_TEST(test_osgetattributecontent)
687 {
688     char xml_file_name[256];
689     create_xml_file("<root attr=\"value\" attr2=\"value1\"></root>", xml_file_name, 256);
690     OS_XML xml;
691     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
692     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
693     const char *xml_path1[] = { "root", NULL };
694     const char *xml_path2[] = { NULL };
695     char *content1, *content2, *content3, *content4;
696     ck_assert_str_eq(content1 = OS_GetAttributeContent(&xml, xml_path1, "attr"), "value");
697     ck_assert_str_eq(content2 = OS_GetAttributeContent(&xml, xml_path1, "attr2"), "value1");
698     ck_assert_str_eq(content3 = OS_GetAttributeContent(&xml, xml_path1, "attr3"), "");
699     ck_assert_str_eq(content4 = OS_GetAttributeContent(&xml, xml_path1, NULL), "");
700     ck_assert_ptr_eq(OS_GetAttributeContent(&xml, xml_path2, NULL), NULL);
701
702
703     free(content1);
704     free(content2);
705     free(content3);
706     free(content4);
707     OS_ClearXML(&xml);
708     unlink(xml_file_name);
709 }
710 END_TEST
711
712 START_TEST(test_osgetcontents)
713 {
714     char xml_file_name[256];
715     create_xml_file("<root>value</root><root>value2</root><root2>value</root2>", xml_file_name, 256);
716     OS_XML xml;
717     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
718     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
719     const char *xml_path1[] = { "root", NULL };
720     const char *xml_path2[] = { "root2", NULL };
721     char **content1, **content2;
722     ck_assert_ptr_ne(content1 = OS_GetContents(&xml, xml_path1), NULL);
723     ck_assert_str_eq(content1[0], "value");
724     ck_assert_str_eq(content1[1], "value2");
725     ck_assert_ptr_eq(content1[2], NULL);
726
727     ck_assert_ptr_ne(content2 = OS_GetContents(&xml, xml_path2), NULL);
728     ck_assert_str_eq(content2[0], "value");
729     ck_assert_ptr_eq(content2[1], NULL);
730
731     ck_assert_ptr_eq(OS_GetContents(&xml, NULL), NULL);
732
733     int i = 0;
734     while(content1[i])
735         free(content1[i++]);
736     free(content1);
737
738     i = 0;
739     while(content2[i])
740         free(content2[i++]);
741     free(content2);
742     OS_ClearXML(&xml);
743     unlink(xml_file_name);
744 }
745 END_TEST
746
747 START_TEST(test_osgetelementcontent)
748 {
749     char xml_file_name[256];
750     create_xml_file("<root>value</root>", xml_file_name, 256);
751     OS_XML xml;
752     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
753     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
754     const char *xml_path[] = { "root", NULL };
755     char **content;
756     ck_assert_ptr_ne(content = OS_GetElementContent(&xml, xml_path), NULL);
757     ck_assert_str_eq(content[0], "value");
758     ck_assert_ptr_eq(content[1], NULL);
759
760     int i = 0;
761     while(content[i])
762         free(content[i++]);
763     free(content);
764     OS_ClearXML(&xml);
765     unlink(xml_file_name);
766 }
767 END_TEST
768
769 START_TEST(test_osgetelements)
770 {
771     char xml_file_name[256];
772     create_xml_file("<root><child1/><child2/></root>", xml_file_name, 256);
773     OS_XML xml;
774     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
775     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
776     const char *xml_path[] = { "root", NULL };
777     char **content1, **content2;
778     ck_assert_ptr_ne(content1 = OS_GetElements(&xml, xml_path), NULL);
779     ck_assert_str_eq(content1[0], "child1");
780     ck_assert_str_eq(content1[1], "child2");
781     ck_assert_ptr_eq(content1[2], NULL);
782     ck_assert_ptr_ne(content2 = OS_GetElements(&xml, NULL), NULL);
783     ck_assert_str_eq(content2[0], "root");
784     ck_assert_ptr_eq(content2[1], NULL);
785     const char *xml_path2[] = { NULL };
786     ck_assert_ptr_eq(OS_GetElements(&xml,  xml_path2), NULL);
787
788     int i = 0;
789     while(content1[i])
790         free(content1[i++]);
791     free(content1);
792     i = 0;
793     while(content2[i])
794         free(content2[i++]);
795     free(content2);
796     OS_ClearXML(&xml);
797     unlink(xml_file_name);
798 }
799 END_TEST
800
801 START_TEST(test_osgetattributes)
802 {
803     char xml_file_name[256];
804     create_xml_file("<root attr1=\"1\" attr2=\"2\"></root>", xml_file_name, 256);
805     OS_XML xml;
806     ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0);
807     ck_assert_int_eq(OS_ApplyVariables(&xml), 0);
808     const char *xml_path[] = { "root", NULL };
809     char **content;
810     ck_assert_ptr_ne(content = OS_GetAttributes(&xml, xml_path), NULL);
811     ck_assert_str_eq(content[0], "attr1");
812     ck_assert_str_eq(content[1], "attr2");
813     ck_assert_ptr_eq(content[2], NULL);
814
815     int i = 0;
816     while(content[i])
817         free(content[i++]);
818     free(content);
819     OS_ClearXML(&xml);
820     unlink(xml_file_name);
821 }
822 END_TEST
823
824 START_TEST(test_osclearnode)
825 {
826     OS_ClearNode(NULL);
827 }
828 END_TEST
829
830 START_TEST(test_stringoverflow)
831 {
832     char xml_file_name[256];
833     char overflow_string[XML_MAXSIZE + 10];
834     memset(overflow_string, 'c', XML_MAXSIZE + 9);
835     overflow_string[XML_MAXSIZE + 9] = '\0';
836
837     char xml_string[2 * XML_MAXSIZE];
838     snprintf(xml_string, 2 * XML_MAXSIZE - 1, "<%s/>", overflow_string);
839     create_xml_file(xml_string, xml_file_name, 256);
840     OS_XML xml;
841     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
842     ck_assert_str_eq(xml.err, "XMLERR: String overflow.");
843     ck_assert_int_eq(xml.err_line, 1);
844
845     OS_ClearXML(&xml);
846     unlink(xml_file_name);
847 }
848 END_TEST
849
850 START_TEST(test_stringoverflow2)
851 {
852     char xml_file_name[256];
853     char overflow_string[XML_MAXSIZE + 10];
854     memset(overflow_string, 'c', XML_MAXSIZE + 9);
855     overflow_string[XML_MAXSIZE + 9] = '\0';
856
857     char xml_string[2 * XML_MAXSIZE];
858     snprintf(xml_string, 2 * XML_MAXSIZE - 1, "<test>%s</test>", overflow_string);
859     create_xml_file(xml_string, xml_file_name, 256);
860     OS_XML xml;
861     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
862     ck_assert_str_eq(xml.err, "XMLERR: String overflow.");
863     ck_assert_int_eq(xml.err_line, 1);
864
865     OS_ClearXML(&xml);
866     unlink(xml_file_name);
867 }
868 END_TEST
869
870 START_TEST(test_stringoverflow3)
871 {
872     char xml_file_name[256];
873     char overflow_string[XML_MAXSIZE + 10];
874     memset(overflow_string, 'c', XML_MAXSIZE + 9);
875     overflow_string[XML_MAXSIZE + 9] = '\0';
876
877     char xml_string[2 * XML_MAXSIZE];
878     snprintf(xml_string, 2 * XML_MAXSIZE - 1, "<test %s=\"test\">test</test>", overflow_string);
879     create_xml_file(xml_string, xml_file_name, 256);
880     OS_XML xml;
881     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
882     ck_assert_str_eq(xml.err, "XMLERR: Overflow attempt at attribute 'cccccccccccccccccccc'.");
883     ck_assert_int_eq(xml.err_line, 1);
884
885     OS_ClearXML(&xml);
886     unlink(xml_file_name);
887 }
888 END_TEST
889
890 START_TEST(test_stringoverflow4)
891 {
892     char xml_file_name[256];
893     char overflow_string[XML_MAXSIZE + 10];
894     memset(overflow_string, 'c', XML_MAXSIZE + 9);
895     overflow_string[XML_MAXSIZE + 9] = '\0';
896
897     char xml_string[2 * XML_MAXSIZE];
898     snprintf(xml_string, 2 * XML_MAXSIZE - 1, "<test test=\"%s\">test</test>", overflow_string);
899     create_xml_file(xml_string, xml_file_name, 256);
900     OS_XML xml;
901     ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0);
902     ck_assert_str_eq(xml.err, "XMLERR: Overflow attempt at attribute 'test'.");
903     ck_assert_int_eq(xml.err_line, 1);
904
905     OS_ClearXML(&xml);
906     unlink(xml_file_name);
907 }
908 END_TEST
909
910 Suite *test_suite(void)
911 {
912     Suite *s = suite_create("os_xml");
913
914     /* Core test case */
915     TCase *tc_core = tcase_create("Core");
916     tcase_add_test(tc_core, test_simplenodes);
917     tcase_add_test(tc_core, test_multiplenodes);
918     tcase_add_test(tc_core, test_multiplecontent);
919     tcase_add_test(tc_core, test_children);
920     tcase_add_test(tc_core, test_attributes);
921     tcase_add_test(tc_core, test_variables);
922     tcase_add_test(tc_core, test_comments);
923     tcase_add_test(tc_core, test_specialchars);
924     tcase_add_test(tc_core, test_linecounter);
925     tcase_add_test(tc_core, test_invalidfile);
926     tcase_add_test(tc_core, test_unclosednode);
927     tcase_add_test(tc_core, test_unclosednode2);
928     tcase_add_test(tc_core, test_unclosedcomment);
929     tcase_add_test(tc_core, test_nodenotopened);
930     tcase_add_test(tc_core, test_unclosedattribute);
931     tcase_add_test(tc_core, test_infiniteattribute);
932     tcase_add_test(tc_core, test_unquotedattribute);
933     tcase_add_test(tc_core, test_invalidvariablename);
934     tcase_add_test(tc_core, test_invalidvariable);
935     tcase_add_test(tc_core, test_invalidvariable2);
936     tcase_add_test(tc_core, test_unknownvariable);
937     tcase_add_test(tc_core, test_infiniteattribute2);
938     tcase_add_test(tc_core, test_invalidattributestart);
939     tcase_add_test(tc_core, test_invalidattributeclosing);
940     tcase_add_test(tc_core, test_invalidattributeclosing2);
941     tcase_add_test(tc_core, test_infiniteattribute3);
942     tcase_add_test(tc_core, test_duplicateattribute);
943     tcase_add_test(tc_core, test_noattributevalue);
944     tcase_add_test(tc_core, test_noattributevalue2);
945     tcase_add_test(tc_core, test_oselementsexists);
946     tcase_add_test(tc_core, test_osgetonecontentforelement);
947     tcase_add_test(tc_core, test_oswritexml_success);
948     tcase_add_test(tc_core, test_oswritexml_failures);
949     tcase_add_test(tc_core, test_osgetattributecontent);
950     tcase_add_test(tc_core, test_osgetcontents);
951     tcase_add_test(tc_core, test_osgetelementcontent);
952     tcase_add_test(tc_core, test_osgetelements);
953     tcase_add_test(tc_core, test_osgetattributes);
954     tcase_add_test(tc_core, test_osclearnode);
955     tcase_add_test(tc_core, test_stringoverflow);
956     tcase_add_test(tc_core, test_stringoverflow2);
957     tcase_add_test(tc_core, test_stringoverflow3);
958     tcase_add_test(tc_core, test_stringoverflow4);
959     suite_add_tcase(s, tc_core);
960
961     return (s);
962 }
963
964 int main(void)
965 {
966     Suite *s = test_suite();
967     SRunner *sr = srunner_create(s);
968     srunner_run_all(sr, CK_NORMAL);
969     int number_failed = srunner_ntests_failed(sr);
970     srunner_free(sr);
971
972     return ((number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
973 }