blob: 33a417f34300185f310c2f8e8a25b00cd42301b3 [file] [log] [blame]
Radek Krejcid91dbaf2018-09-21 15:51:39 +02001/*
2 * @file xml.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from xml.c
5 *
6 * Copyright (c) 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
Radek Krejcib7db73a2018-10-24 14:18:40 +020015#include "common.h"
Radek Krejcif3f47842018-11-15 11:22:15 +010016#include "../../src/set.c"
17#include "../../src/xml.c"
18#include "../../src/common.c"
19#include "../../src/log.c"
Radek Krejcib7db73a2018-10-24 14:18:40 +020020
Radek Krejcid91dbaf2018-09-21 15:51:39 +020021#include <stdarg.h>
22#include <stddef.h>
23#include <setjmp.h>
24#include <cmocka.h>
25
26#include <stdio.h>
27#include <string.h>
28
29#include "libyang.h"
Radek Krejcid91dbaf2018-09-21 15:51:39 +020030
31#define BUFSIZE 1024
32char logbuf[BUFSIZE] = {0};
33
34/* set to 0 to printing error messages to stderr instead of checking them in code */
35#define ENABLE_LOGGER_CHECKING 1
36
37static void
38logger(LY_LOG_LEVEL level, const char *msg, const char *path)
39{
40 (void) level; /* unused */
41
42 if (path) {
43 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
44 } else {
45 strncpy(logbuf, msg, BUFSIZE - 1);
46 }
47}
48
49static int
50logger_setup(void **state)
51{
52 (void) state; /* unused */
53#if ENABLE_LOGGER_CHECKING
54 ly_set_log_clb(logger, 1);
55#endif
56 return 0;
57}
58
59void
60logbuf_clean(void)
61{
62 logbuf[0] = '\0';
63}
64
65#if ENABLE_LOGGER_CHECKING
66# define logbuf_assert(str) assert_string_equal(logbuf, str)
67#else
68# define logbuf_assert(str)
69#endif
70
71static void
72test_element(void **state)
73{
74 (void) state; /* unused */
75
76 size_t name_len, prefix_len;
77 const char *name, *prefix;
78 const char *str, *p;
79
80 struct lyxml_context ctx;
81 memset(&ctx, 0, sizeof ctx);
82 ctx.line = 1;
83
84 /* empty */
85 str = "";
Radek Krejci7a7fa902018-09-25 17:08:21 +020086 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +020087 assert_null(name);
Radek Krejcib1890642018-10-03 14:05:40 +020088 assert_int_equal(LYXML_END, ctx.status);
Radek Krejcid91dbaf2018-09-21 15:51:39 +020089 assert_true(str[0] == '\0');
90
Radek Krejcib1890642018-10-03 14:05:40 +020091 /* end element */
92 str = "</element>";
93 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
94 logbuf_assert("Opening and closing elements tag missmatch (\"element>\"). Line number 1.");
95
96
Radek Krejcid91dbaf2018-09-21 15:51:39 +020097 /* no element */
98 logbuf_clean();
99 str = p = "no data present";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200100 assert_int_equal(LY_EINVAL, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200101 assert_null(name);
102 assert_ptr_equal(p, str); /* input data not eaten */
103 logbuf_assert("");
104
105 /* not supported DOCTYPE */
106 str = p = "<!DOCTYPE greeting SYSTEM \"hello.dtd\"><greeting/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200107 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200108 assert_null(name);
109 assert_ptr_equal(p, str); /* input data not eaten */
110 logbuf_assert("Document Type Declaration not supported. Line number 1.");
111
112 /* unqualified element */
113 str = " < element/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200114 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200115 assert_null(prefix);
116 assert_false(strncmp("element", name, name_len));
117 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200118 assert_int_equal(LYXML_ELEMENT, ctx.status);
119 assert_string_equal("", str);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200120
Radek Krejcifb7c6582018-09-21 16:12:45 +0200121 str = "<?xml version=\"1.0\"?> <!-- comment --> <![CDATA[<greeting>Hello, world!</greeting>]]> <?TEST xxx?> <element/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200122 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200123 assert_null(prefix);
124 assert_false(strncmp("element", name, name_len));
125 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200126 assert_int_equal(LYXML_ELEMENT, ctx.status);
127 assert_string_equal("", str);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200128
129 str = "<element xmlns=\"urn\"></element>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200130 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200131 assert_null(prefix);
132 assert_false(strncmp("element", name, name_len));
133 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200134 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
135 assert_string_equal("xmlns=\"urn\"></element>", str);
136 /* cleean context by getting closing tag */
137 str += 12;
138 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200139
140 /* qualified element */
141 str = " < yin:element/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200142 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200143 assert_false(strncmp("yin", prefix, prefix_len));
144 assert_false(strncmp("element", name, name_len));
145 assert_int_equal(3, prefix_len);
146 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200147 assert_int_equal(LYXML_ELEMENT, ctx.status);
148 assert_string_equal("", str);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200149
150 str = "<yin:element xmlns=\"urn\"></element>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200151 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200152 assert_false(strncmp("yin", prefix, prefix_len));
153 assert_false(strncmp("element", name, name_len));
154 assert_int_equal(3, prefix_len);
155 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200156 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
157 assert_string_equal("xmlns=\"urn\"></element>", str);
158 /* cleean context by getting closing tag */
159 str += 12;
160 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
161 logbuf_assert("Opening and closing elements tag missmatch (\"element>\"). Line number 1.");
Radek Krejcia93621b2018-10-18 11:13:38 +0200162 str = "</yin:element/>";
163 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
164 logbuf_assert("Unexpected data \"/>\" in closing element tag. Line number 1.");
Radek Krejcib1890642018-10-03 14:05:40 +0200165 lyxml_context_clear(&ctx);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200166
167 /* UTF8 characters */
168 str = "<𠜎€𠜎Øn:𠜎€𠜎Øn/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200169 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200170 assert_false(strncmp("𠜎€𠜎Øn", prefix, prefix_len));
171 assert_false(strncmp("𠜎€𠜎Øn", name, name_len));
172 assert_int_equal(14, prefix_len);
173 assert_int_equal(14, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200174 assert_int_equal(LYXML_ELEMENT, ctx.status);
175 assert_string_equal("", str);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200176
177 /* invalid UTF-8 character */
178 str = "<¢:element>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200179 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200180 logbuf_assert("Identifier \"¢:element>\" starts with invalid character. Line number 1.");
181 str = "<yin:c⁐element>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200182 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200183 logbuf_assert("Invalid character sequence \"⁐element>\", expected whitespace or element tag termination ('>' or '/>'. Line number 1.");
184}
185
186static void
187test_attribute(void **state)
188{
189 (void) state; /* unused */
190
191 size_t name_len, prefix_len;
192 const char *name, *prefix;
193 const char *str, *p;
194
195 struct lyxml_context ctx;
196 memset(&ctx, 0, sizeof ctx);
197 ctx.line = 1;
198
199 /* empty - without element tag termination */
200 str = "";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200201 assert_int_equal(LY_EINVAL, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200202
203 /* empty - without element tag termination */
204 str = " />";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200205 assert_int_equal(LY_SUCCESS, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200206 assert_null(name);
Radek Krejcib1890642018-10-03 14:05:40 +0200207 assert_true(str[0] == '\0');
208 assert_int_equal(LYXML_ELEMENT, ctx.status);
Radek Krejcid972c252018-09-25 13:23:39 +0200209 str = ">";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200210 assert_int_equal(LY_SUCCESS, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200211 assert_null(name);
Radek Krejcib1890642018-10-03 14:05:40 +0200212 assert_true(str[0] == '\0');
213 assert_int_equal(LYXML_ELEM_CONTENT, ctx.status);
Radek Krejcid972c252018-09-25 13:23:39 +0200214
215 /* not an attribute */
216 str = p = "unknown/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200217 assert_int_equal(LY_EVALID, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200218 assert_ptr_equal(p, str); /* input data not eaten */
219 logbuf_assert("Invalid character sequence \"/>\", expected whitespace or '='. Line number 1.");
220 str = p = "unknown />";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200221 assert_int_equal(LY_EVALID, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200222 assert_ptr_equal(p, str); /* input data not eaten */
223 logbuf_assert("Invalid character sequence \"/>\", expected '='. Line number 1.");
224 str = p = "xxx=/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200225 assert_int_equal(LY_EVALID, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200226 assert_ptr_equal(p, str); /* input data not eaten */
227 logbuf_assert("Invalid character sequence \"/>\", expected either single or double quotation mark. Line number 1.");
228 str = p = "xxx\n = yyy/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200229 assert_int_equal(LY_EVALID, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200230 assert_ptr_equal(p, str); /* input data not eaten */
231 logbuf_assert("Invalid character sequence \"yyy/>\", expected either single or double quotation mark. Line number 2.");
232
233 /* valid attribute */
234 str = "xmlns=\"urn\">";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200235 assert_int_equal(LY_SUCCESS, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200236 assert_non_null(name);
237 assert_null(prefix);
238 assert_int_equal(5, name_len);
239 assert_int_equal(0, prefix_len);
240 assert_false(strncmp("xmlns", name, name_len));
241 assert_string_equal("\"urn\">", str);
Radek Krejcib1890642018-10-03 14:05:40 +0200242 assert_int_equal(LYXML_ATTR_CONTENT, ctx.status);
Radek Krejcid972c252018-09-25 13:23:39 +0200243
244 str = "xmlns:nc\n = \'urn\'>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200245 assert_int_equal(LY_SUCCESS, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200246 assert_non_null(name);
247 assert_non_null(prefix);
248 assert_int_equal(2, name_len);
249 assert_int_equal(5, prefix_len);
250 assert_int_equal(3, ctx.line);
251 assert_false(strncmp("xmlns", prefix, prefix_len));
252 assert_false(strncmp("nc", name, name_len));
253 assert_string_equal("\'urn\'>", str);
Radek Krejcib1890642018-10-03 14:05:40 +0200254 assert_int_equal(LYXML_ATTR_CONTENT, ctx.status);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200255}
256
Radek Krejci7a7fa902018-09-25 17:08:21 +0200257static void
258test_text(void **state)
259{
260 (void) state; /* unused */
261
Radek Krejcid70d1072018-10-09 14:20:47 +0200262 size_t buf_len, len;
263 int dynamic;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200264 const char *str, *p;
Radek Krejcid70d1072018-10-09 14:20:47 +0200265 char *buf = NULL, *out = NULL;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200266
267 struct lyxml_context ctx;
268 memset(&ctx, 0, sizeof ctx);
269 ctx.line = 1;
270
271 /* empty attribute value */
Radek Krejcib1890642018-10-03 14:05:40 +0200272 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200273 str = "\"\"";
Radek Krejcid70d1072018-10-09 14:20:47 +0200274 assert_int_equal(LY_SUCCESS, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
275 assert_null(buf);
276 assert_ptr_equal(&str[-1], out);
277 assert_int_equal(0, dynamic);
278 assert_int_equal(0, len);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200279 assert_true(str[0] == '\0'); /* everything eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200280 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
281
282 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200283 str = "\'\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200284 assert_int_equal(LY_SUCCESS, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
285 assert_null(buf);
286 assert_ptr_equal(&str[-1], out);
287 assert_int_equal(0, dynamic);
288 assert_int_equal(0, len);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200289 assert_true(str[0] == '\0'); /* everything eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200290 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200291
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200292 /* empty element content - only formating before defining child */
Radek Krejcib1890642018-10-03 14:05:40 +0200293 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200294 str = "\n <";
Radek Krejcid70d1072018-10-09 14:20:47 +0200295 assert_int_equal(LY_EINVAL, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
296 assert_null(buf);
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200297 assert_string_equal("<", str);
298
Radek Krejci7a7fa902018-09-25 17:08:21 +0200299 /* empty element content is invalid - missing content terminating character < */
Radek Krejcib1890642018-10-03 14:05:40 +0200300 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200301 str = "";
Radek Krejcid70d1072018-10-09 14:20:47 +0200302 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
303 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200304 logbuf_assert("Unexpected end-of-file. Line number 2.");
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200305
Radek Krejcib1890642018-10-03 14:05:40 +0200306 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200307 str = p = "xxx";
Radek Krejcid70d1072018-10-09 14:20:47 +0200308 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
309 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200310 logbuf_assert("Unexpected end-of-file. Line number 2.");
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200311 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejci7a7fa902018-09-25 17:08:21 +0200312
Radek Krejci7a7fa902018-09-25 17:08:21 +0200313 /* valid strings */
Radek Krejcib1890642018-10-03 14:05:40 +0200314 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200315 str = "€𠜎Øn \n&lt;&amp;&quot;&apos;&gt; &#82;&#x4f;&#x4B;<";
Radek Krejcid70d1072018-10-09 14:20:47 +0200316 assert_int_equal(LY_SUCCESS, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
317 assert_int_not_equal(0, dynamic);
318 assert_non_null(buf);
319 assert_ptr_equal(out, buf);
320 assert_int_equal(22, buf_len);
321 assert_int_equal(21, len);
322 assert_string_equal("€𠜎Øn \n<&\"\'> ROK", buf);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200323 assert_string_equal("<", str);
Radek Krejcib1890642018-10-03 14:05:40 +0200324 assert_int_equal(LYXML_ELEMENT, ctx.status);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200325
Radek Krejci117d2082018-09-26 10:05:14 +0200326 /* test using n-bytes UTF8 hexadecimal code points */
Radek Krejcib1890642018-10-03 14:05:40 +0200327 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200328 str = "\'&#x0024;&#x00A2;&#x20ac;&#x10348;\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200329 assert_int_equal(LY_SUCCESS, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
330 assert_int_not_equal(0, dynamic);
331 assert_non_null(buf);
332 assert_ptr_equal(out, buf);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200333 assert_int_equal(22, buf_len);
Radek Krejcid70d1072018-10-09 14:20:47 +0200334 assert_int_equal(10, len);
335 assert_string_equal("$¢€𐍈", buf);
Radek Krejcib1890642018-10-03 14:05:40 +0200336 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
Radek Krejci117d2082018-09-26 10:05:14 +0200337
Radek Krejcid70d1072018-10-09 14:20:47 +0200338 free(buf);
339 buf = NULL;
340
Radek Krejci7a7fa902018-09-25 17:08:21 +0200341 /* invalid characters in string */
Radek Krejcib1890642018-10-03 14:05:40 +0200342 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200343 str = p = "\'&#x52\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200344 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200345 logbuf_assert("Invalid character sequence \"'\", expected ;. Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200346 assert_null(buf);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200347 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200348 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200349 str = p = "\"&#82\"";
Radek Krejcid70d1072018-10-09 14:20:47 +0200350 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200351 logbuf_assert("Invalid character sequence \"\"\", expected ;. Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200352 assert_null(buf);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200353 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200354 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200355 str = p = "\"&nonsence;\"";
Radek Krejcid70d1072018-10-09 14:20:47 +0200356 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200357 logbuf_assert("Entity reference \"&nonsence;\" not supported, only predefined references allowed. Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200358 assert_null(buf);
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200359 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200360 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200361 str = p = "&#o122;";
Radek Krejcid70d1072018-10-09 14:20:47 +0200362 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200363 logbuf_assert("Invalid character reference \"&#o122;\". Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200364 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200365 assert_ptr_equal(p, str); /* input data not eaten */
366
Radek Krejcib1890642018-10-03 14:05:40 +0200367 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200368 str = p = "\'&#x06;\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200369 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200370 logbuf_assert("Invalid character reference \"&#x06;\'\" (0x00000006). Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200371 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200372 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200373 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200374 str = p = "\'&#xfdd0;\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200375 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200376 logbuf_assert("Invalid character reference \"&#xfdd0;\'\" (0x0000fdd0). Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200377 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200378 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200379 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200380 str = p = "\'&#xffff;\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200381 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200382 logbuf_assert("Invalid character reference \"&#xffff;\'\" (0x0000ffff). Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200383 assert_null(buf);
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200384 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejci7a7fa902018-09-25 17:08:21 +0200385}
386
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200387static void
388test_ns(void **state)
389{
390 (void) state; /* unused */
391
392 const char *e1, *e2;
393 const struct lyxml_ns *ns;
394
395 struct lyxml_context ctx;
396 memset(&ctx, 0, sizeof ctx);
397 ctx.line = 1;
398
399 e1 = "element1";
400 e2 = "element2";
401 assert_int_equal(LY_SUCCESS, lyxml_ns_add(&ctx, e1, NULL, 0, strdup("urn:default")));
402 assert_int_equal(LY_SUCCESS, lyxml_ns_add(&ctx, e1, "nc", 2, strdup("urn:nc1")));
403 assert_int_equal(LY_SUCCESS, lyxml_ns_add(&ctx, e2, "nc", 2, strdup("urn:nc2")));
404 assert_int_equal(3, (&ctx)->ns.count);
405 assert_int_not_equal(0, (&ctx)->ns.size);
406
407 ns = lyxml_ns_get(&ctx, NULL, 0);
408 assert_non_null(ns);
409 assert_null(ns->prefix);
410 assert_string_equal("urn:default", ns->uri);
411
412 ns = lyxml_ns_get(&ctx, "nc", 2);
413 assert_non_null(ns);
414 assert_string_equal("nc", ns->prefix);
415 assert_string_equal("urn:nc2", ns->uri);
416
417 assert_int_equal(LY_SUCCESS, lyxml_ns_rm(&ctx, e2));
418 assert_int_equal(2, (&ctx)->ns.count);
419
420 ns = lyxml_ns_get(&ctx, "nc", 2);
421 assert_non_null(ns);
422 assert_string_equal("nc", ns->prefix);
423 assert_string_equal("urn:nc1", ns->uri);
424
425 assert_int_equal(LY_SUCCESS, lyxml_ns_rm(&ctx, e1));
426 assert_int_equal(0, (&ctx)->ns.count);
427
428 assert_null(lyxml_ns_get(&ctx, "nc", 2));
429 assert_null(lyxml_ns_get(&ctx, NULL, 0));
430}
431
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200432int main(void)
433{
434 const struct CMUnitTest tests[] = {
Radek Krejcid972c252018-09-25 13:23:39 +0200435 cmocka_unit_test_setup(test_element, logger_setup),
436 cmocka_unit_test_setup(test_attribute, logger_setup),
Radek Krejci7a7fa902018-09-25 17:08:21 +0200437 cmocka_unit_test_setup(test_text, logger_setup),
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200438 cmocka_unit_test_setup(test_ns, logger_setup),
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200439 };
440
441 return cmocka_run_group_tests(tests, NULL, NULL);
442}