blob: 568e55e7d94a2404eda0723831a5f87ae2366d1f [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
15#define _BSD_SOURCE
16#define _DEFAULT_SOURCE
17#include <stdarg.h>
18#include <stddef.h>
19#include <setjmp.h>
20#include <cmocka.h>
21
22#include <stdio.h>
23#include <string.h>
24
25#include "libyang.h"
26#include "../../src/xml.c"
27
28#define BUFSIZE 1024
29char logbuf[BUFSIZE] = {0};
30
31/* set to 0 to printing error messages to stderr instead of checking them in code */
32#define ENABLE_LOGGER_CHECKING 1
33
34static void
35logger(LY_LOG_LEVEL level, const char *msg, const char *path)
36{
37 (void) level; /* unused */
38
39 if (path) {
40 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
41 } else {
42 strncpy(logbuf, msg, BUFSIZE - 1);
43 }
44}
45
46static int
47logger_setup(void **state)
48{
49 (void) state; /* unused */
50#if ENABLE_LOGGER_CHECKING
51 ly_set_log_clb(logger, 1);
52#endif
53 return 0;
54}
55
56void
57logbuf_clean(void)
58{
59 logbuf[0] = '\0';
60}
61
62#if ENABLE_LOGGER_CHECKING
63# define logbuf_assert(str) assert_string_equal(logbuf, str)
64#else
65# define logbuf_assert(str)
66#endif
67
68static void
69test_element(void **state)
70{
71 (void) state; /* unused */
72
73 size_t name_len, prefix_len;
74 const char *name, *prefix;
75 const char *str, *p;
76
77 struct lyxml_context ctx;
78 memset(&ctx, 0, sizeof ctx);
79 ctx.line = 1;
80
81 /* empty */
82 str = "";
Radek Krejci7a7fa902018-09-25 17:08:21 +020083 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +020084 assert_null(name);
Radek Krejcib1890642018-10-03 14:05:40 +020085 assert_int_equal(LYXML_END, ctx.status);
Radek Krejcid91dbaf2018-09-21 15:51:39 +020086 assert_true(str[0] == '\0');
87
Radek Krejcib1890642018-10-03 14:05:40 +020088 /* end element */
89 str = "</element>";
90 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
91 logbuf_assert("Opening and closing elements tag missmatch (\"element>\"). Line number 1.");
92
93
Radek Krejcid91dbaf2018-09-21 15:51:39 +020094 /* no element */
95 logbuf_clean();
96 str = p = "no data present";
Radek Krejci7a7fa902018-09-25 17:08:21 +020097 assert_int_equal(LY_EINVAL, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +020098 assert_null(name);
99 assert_ptr_equal(p, str); /* input data not eaten */
100 logbuf_assert("");
101
102 /* not supported DOCTYPE */
103 str = p = "<!DOCTYPE greeting SYSTEM \"hello.dtd\"><greeting/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200104 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200105 assert_null(name);
106 assert_ptr_equal(p, str); /* input data not eaten */
107 logbuf_assert("Document Type Declaration not supported. Line number 1.");
108
109 /* unqualified element */
110 str = " < element/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200111 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200112 assert_null(prefix);
113 assert_false(strncmp("element", name, name_len));
114 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200115 assert_int_equal(LYXML_ELEMENT, ctx.status);
116 assert_string_equal("", str);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200117
Radek Krejcifb7c6582018-09-21 16:12:45 +0200118 str = "<?xml version=\"1.0\"?> <!-- comment --> <![CDATA[<greeting>Hello, world!</greeting>]]> <?TEST xxx?> <element/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200119 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200120 assert_null(prefix);
121 assert_false(strncmp("element", name, name_len));
122 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200123 assert_int_equal(LYXML_ELEMENT, ctx.status);
124 assert_string_equal("", str);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200125
126 str = "<element xmlns=\"urn\"></element>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200127 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200128 assert_null(prefix);
129 assert_false(strncmp("element", name, name_len));
130 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200131 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
132 assert_string_equal("xmlns=\"urn\"></element>", str);
133 /* cleean context by getting closing tag */
134 str += 12;
135 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200136
137 /* qualified element */
138 str = " < yin:element/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200139 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200140 assert_false(strncmp("yin", prefix, prefix_len));
141 assert_false(strncmp("element", name, name_len));
142 assert_int_equal(3, prefix_len);
143 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200144 assert_int_equal(LYXML_ELEMENT, ctx.status);
145 assert_string_equal("", str);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200146
147 str = "<yin:element xmlns=\"urn\"></element>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200148 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200149 assert_false(strncmp("yin", prefix, prefix_len));
150 assert_false(strncmp("element", name, name_len));
151 assert_int_equal(3, prefix_len);
152 assert_int_equal(7, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200153 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
154 assert_string_equal("xmlns=\"urn\"></element>", str);
155 /* cleean context by getting closing tag */
156 str += 12;
157 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
158 logbuf_assert("Opening and closing elements tag missmatch (\"element>\"). Line number 1.");
Radek Krejcia93621b2018-10-18 11:13:38 +0200159 str = "</yin:element/>";
160 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
161 logbuf_assert("Unexpected data \"/>\" in closing element tag. Line number 1.");
Radek Krejcib1890642018-10-03 14:05:40 +0200162 lyxml_context_clear(&ctx);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200163
164 /* UTF8 characters */
165 str = "<𠜎€𠜎Øn:𠜎€𠜎Øn/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200166 assert_int_equal(LY_SUCCESS, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200167 assert_false(strncmp("𠜎€𠜎Øn", prefix, prefix_len));
168 assert_false(strncmp("𠜎€𠜎Øn", name, name_len));
169 assert_int_equal(14, prefix_len);
170 assert_int_equal(14, name_len);
Radek Krejcib1890642018-10-03 14:05:40 +0200171 assert_int_equal(LYXML_ELEMENT, ctx.status);
172 assert_string_equal("", str);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200173
174 /* invalid UTF-8 character */
175 str = "<¢:element>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200176 assert_int_equal(LY_EVALID, lyxml_get_element(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200177 logbuf_assert("Identifier \"¢:element>\" starts with invalid character. Line number 1.");
178 str = "<yin:c⁐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 Krejcid972c252018-09-25 13:23:39 +0200180 logbuf_assert("Invalid character sequence \"⁐element>\", expected whitespace or element tag termination ('>' or '/>'. Line number 1.");
181}
182
183static void
184test_attribute(void **state)
185{
186 (void) state; /* unused */
187
188 size_t name_len, prefix_len;
189 const char *name, *prefix;
190 const char *str, *p;
191
192 struct lyxml_context ctx;
193 memset(&ctx, 0, sizeof ctx);
194 ctx.line = 1;
195
196 /* empty - without element tag termination */
197 str = "";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200198 assert_int_equal(LY_EINVAL, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200199
200 /* empty - without element tag termination */
201 str = " />";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200202 assert_int_equal(LY_SUCCESS, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200203 assert_null(name);
Radek Krejcib1890642018-10-03 14:05:40 +0200204 assert_true(str[0] == '\0');
205 assert_int_equal(LYXML_ELEMENT, ctx.status);
Radek Krejcid972c252018-09-25 13:23:39 +0200206 str = ">";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200207 assert_int_equal(LY_SUCCESS, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200208 assert_null(name);
Radek Krejcib1890642018-10-03 14:05:40 +0200209 assert_true(str[0] == '\0');
210 assert_int_equal(LYXML_ELEM_CONTENT, ctx.status);
Radek Krejcid972c252018-09-25 13:23:39 +0200211
212 /* not an attribute */
213 str = p = "unknown/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200214 assert_int_equal(LY_EVALID, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200215 assert_ptr_equal(p, str); /* input data not eaten */
216 logbuf_assert("Invalid character sequence \"/>\", expected whitespace or '='. Line number 1.");
217 str = p = "unknown />";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200218 assert_int_equal(LY_EVALID, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200219 assert_ptr_equal(p, str); /* input data not eaten */
220 logbuf_assert("Invalid character sequence \"/>\", expected '='. Line number 1.");
221 str = p = "xxx=/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200222 assert_int_equal(LY_EVALID, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200223 assert_ptr_equal(p, str); /* input data not eaten */
224 logbuf_assert("Invalid character sequence \"/>\", expected either single or double quotation mark. Line number 1.");
225 str = p = "xxx\n = yyy/>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200226 assert_int_equal(LY_EVALID, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200227 assert_ptr_equal(p, str); /* input data not eaten */
228 logbuf_assert("Invalid character sequence \"yyy/>\", expected either single or double quotation mark. Line number 2.");
229
230 /* valid attribute */
231 str = "xmlns=\"urn\">";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200232 assert_int_equal(LY_SUCCESS, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200233 assert_non_null(name);
234 assert_null(prefix);
235 assert_int_equal(5, name_len);
236 assert_int_equal(0, prefix_len);
237 assert_false(strncmp("xmlns", name, name_len));
238 assert_string_equal("\"urn\">", str);
Radek Krejcib1890642018-10-03 14:05:40 +0200239 assert_int_equal(LYXML_ATTR_CONTENT, ctx.status);
Radek Krejcid972c252018-09-25 13:23:39 +0200240
241 str = "xmlns:nc\n = \'urn\'>";
Radek Krejci7a7fa902018-09-25 17:08:21 +0200242 assert_int_equal(LY_SUCCESS, lyxml_get_attribute(&ctx, &str, &prefix, &prefix_len, &name, &name_len));
Radek Krejcid972c252018-09-25 13:23:39 +0200243 assert_non_null(name);
244 assert_non_null(prefix);
245 assert_int_equal(2, name_len);
246 assert_int_equal(5, prefix_len);
247 assert_int_equal(3, ctx.line);
248 assert_false(strncmp("xmlns", prefix, prefix_len));
249 assert_false(strncmp("nc", name, name_len));
250 assert_string_equal("\'urn\'>", str);
Radek Krejcib1890642018-10-03 14:05:40 +0200251 assert_int_equal(LYXML_ATTR_CONTENT, ctx.status);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200252}
253
Radek Krejci7a7fa902018-09-25 17:08:21 +0200254static void
255test_text(void **state)
256{
257 (void) state; /* unused */
258
Radek Krejcid70d1072018-10-09 14:20:47 +0200259 size_t buf_len, len;
260 int dynamic;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200261 const char *str, *p;
Radek Krejcid70d1072018-10-09 14:20:47 +0200262 char *buf = NULL, *out = NULL;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200263
264 struct lyxml_context ctx;
265 memset(&ctx, 0, sizeof ctx);
266 ctx.line = 1;
267
268 /* empty attribute value */
Radek Krejcib1890642018-10-03 14:05:40 +0200269 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200270 str = "\"\"";
Radek Krejcid70d1072018-10-09 14:20:47 +0200271 assert_int_equal(LY_SUCCESS, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
272 assert_null(buf);
273 assert_ptr_equal(&str[-1], out);
274 assert_int_equal(0, dynamic);
275 assert_int_equal(0, len);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200276 assert_true(str[0] == '\0'); /* everything eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200277 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
278
279 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200280 str = "\'\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200281 assert_int_equal(LY_SUCCESS, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
282 assert_null(buf);
283 assert_ptr_equal(&str[-1], out);
284 assert_int_equal(0, dynamic);
285 assert_int_equal(0, len);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200286 assert_true(str[0] == '\0'); /* everything eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200287 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200288
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200289 /* empty element content - only formating before defining child */
Radek Krejcib1890642018-10-03 14:05:40 +0200290 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200291 str = "\n <";
Radek Krejcid70d1072018-10-09 14:20:47 +0200292 assert_int_equal(LY_EINVAL, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
293 assert_null(buf);
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200294 assert_string_equal("<", str);
295
Radek Krejci7a7fa902018-09-25 17:08:21 +0200296 /* empty element content is invalid - missing content terminating character < */
Radek Krejcib1890642018-10-03 14:05:40 +0200297 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200298 str = "";
Radek Krejcid70d1072018-10-09 14:20:47 +0200299 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
300 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200301 logbuf_assert("Unexpected end-of-file. Line number 2.");
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200302
Radek Krejcib1890642018-10-03 14:05:40 +0200303 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200304 str = p = "xxx";
Radek Krejcid70d1072018-10-09 14:20:47 +0200305 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
306 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200307 logbuf_assert("Unexpected end-of-file. Line number 2.");
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200308 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejci7a7fa902018-09-25 17:08:21 +0200309
Radek Krejci7a7fa902018-09-25 17:08:21 +0200310 /* valid strings */
Radek Krejcib1890642018-10-03 14:05:40 +0200311 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200312 str = "€𠜎Øn \n&lt;&amp;&quot;&apos;&gt; &#82;&#x4f;&#x4B;<";
Radek Krejcid70d1072018-10-09 14:20:47 +0200313 assert_int_equal(LY_SUCCESS, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
314 assert_int_not_equal(0, dynamic);
315 assert_non_null(buf);
316 assert_ptr_equal(out, buf);
317 assert_int_equal(22, buf_len);
318 assert_int_equal(21, len);
319 assert_string_equal("€𠜎Øn \n<&\"\'> ROK", buf);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200320 assert_string_equal("<", str);
Radek Krejcib1890642018-10-03 14:05:40 +0200321 assert_int_equal(LYXML_ELEMENT, ctx.status);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200322
Radek Krejci117d2082018-09-26 10:05:14 +0200323 /* test using n-bytes UTF8 hexadecimal code points */
Radek Krejcib1890642018-10-03 14:05:40 +0200324 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200325 str = "\'&#x0024;&#x00A2;&#x20ac;&#x10348;\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200326 assert_int_equal(LY_SUCCESS, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
327 assert_int_not_equal(0, dynamic);
328 assert_non_null(buf);
329 assert_ptr_equal(out, buf);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200330 assert_int_equal(22, buf_len);
Radek Krejcid70d1072018-10-09 14:20:47 +0200331 assert_int_equal(10, len);
332 assert_string_equal("$¢€𐍈", buf);
Radek Krejcib1890642018-10-03 14:05:40 +0200333 assert_int_equal(LYXML_ATTRIBUTE, ctx.status);
Radek Krejci117d2082018-09-26 10:05:14 +0200334
Radek Krejcid70d1072018-10-09 14:20:47 +0200335 free(buf);
336 buf = NULL;
337
Radek Krejci7a7fa902018-09-25 17:08:21 +0200338 /* invalid characters in string */
Radek Krejcib1890642018-10-03 14:05:40 +0200339 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200340 str = p = "\'&#x52\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200341 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200342 logbuf_assert("Invalid character sequence \"'\", expected ;. Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200343 assert_null(buf);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200344 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200345 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200346 str = p = "\"&#82\"";
Radek Krejcid70d1072018-10-09 14:20:47 +0200347 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200348 logbuf_assert("Invalid character sequence \"\"\", expected ;. Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200349 assert_null(buf);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200350 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200351 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200352 str = p = "\"&nonsence;\"";
Radek Krejcid70d1072018-10-09 14:20:47 +0200353 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200354 logbuf_assert("Entity reference \"&nonsence;\" not supported, only predefined references allowed. Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200355 assert_null(buf);
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200356 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200357 ctx.status = LYXML_ELEM_CONTENT;
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200358 str = p = "&#o122;";
Radek Krejcid70d1072018-10-09 14:20:47 +0200359 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200360 logbuf_assert("Invalid character reference \"&#o122;\". Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200361 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200362 assert_ptr_equal(p, str); /* input data not eaten */
363
Radek Krejcib1890642018-10-03 14:05:40 +0200364 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200365 str = p = "\'&#x06;\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200366 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200367 logbuf_assert("Invalid character reference \"&#x06;\'\" (0x00000006). Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200368 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200369 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200370 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200371 str = p = "\'&#xfdd0;\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200372 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200373 logbuf_assert("Invalid character reference \"&#xfdd0;\'\" (0x0000fdd0). Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200374 assert_null(buf);
Radek Krejci117d2082018-09-26 10:05:14 +0200375 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejcib1890642018-10-03 14:05:40 +0200376 ctx.status = LYXML_ATTR_CONTENT;
Radek Krejci117d2082018-09-26 10:05:14 +0200377 str = p = "\'&#xffff;\'";
Radek Krejcid70d1072018-10-09 14:20:47 +0200378 assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
Radek Krejci117d2082018-09-26 10:05:14 +0200379 logbuf_assert("Invalid character reference \"&#xffff;\'\" (0x0000ffff). Line number 3.");
Radek Krejcid70d1072018-10-09 14:20:47 +0200380 assert_null(buf);
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200381 assert_ptr_equal(p, str); /* input data not eaten */
Radek Krejci7a7fa902018-09-25 17:08:21 +0200382}
383
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200384static void
385test_ns(void **state)
386{
387 (void) state; /* unused */
388
389 const char *e1, *e2;
390 const struct lyxml_ns *ns;
391
392 struct lyxml_context ctx;
393 memset(&ctx, 0, sizeof ctx);
394 ctx.line = 1;
395
396 e1 = "element1";
397 e2 = "element2";
398 assert_int_equal(LY_SUCCESS, lyxml_ns_add(&ctx, e1, NULL, 0, strdup("urn:default")));
399 assert_int_equal(LY_SUCCESS, lyxml_ns_add(&ctx, e1, "nc", 2, strdup("urn:nc1")));
400 assert_int_equal(LY_SUCCESS, lyxml_ns_add(&ctx, e2, "nc", 2, strdup("urn:nc2")));
401 assert_int_equal(3, (&ctx)->ns.count);
402 assert_int_not_equal(0, (&ctx)->ns.size);
403
404 ns = lyxml_ns_get(&ctx, NULL, 0);
405 assert_non_null(ns);
406 assert_null(ns->prefix);
407 assert_string_equal("urn:default", ns->uri);
408
409 ns = lyxml_ns_get(&ctx, "nc", 2);
410 assert_non_null(ns);
411 assert_string_equal("nc", ns->prefix);
412 assert_string_equal("urn:nc2", ns->uri);
413
414 assert_int_equal(LY_SUCCESS, lyxml_ns_rm(&ctx, e2));
415 assert_int_equal(2, (&ctx)->ns.count);
416
417 ns = lyxml_ns_get(&ctx, "nc", 2);
418 assert_non_null(ns);
419 assert_string_equal("nc", ns->prefix);
420 assert_string_equal("urn:nc1", ns->uri);
421
422 assert_int_equal(LY_SUCCESS, lyxml_ns_rm(&ctx, e1));
423 assert_int_equal(0, (&ctx)->ns.count);
424
425 assert_null(lyxml_ns_get(&ctx, "nc", 2));
426 assert_null(lyxml_ns_get(&ctx, NULL, 0));
427}
428
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200429int main(void)
430{
431 const struct CMUnitTest tests[] = {
Radek Krejcid972c252018-09-25 13:23:39 +0200432 cmocka_unit_test_setup(test_element, logger_setup),
433 cmocka_unit_test_setup(test_attribute, logger_setup),
Radek Krejci7a7fa902018-09-25 17:08:21 +0200434 cmocka_unit_test_setup(test_text, logger_setup),
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200435 cmocka_unit_test_setup(test_ns, logger_setup),
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200436 };
437
438 return cmocka_run_group_tests(tests, NULL, NULL);
439}