blob: 25aed03ef87cc2ebdf21a913396943dd0ecb579f [file] [log] [blame]
Michal Vaskof20ad112023-02-10 15:12:12 +01001/**
aPiecek023f83a2021-05-11 07:37:03 +02002 * @file test_xml.c
Radek Krejcid91dbaf2018-09-21 15:51:39 +02003 * @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 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
15#include "utests.h"
Radek Krejcid91dbaf2018-09-21 15:51:39 +020016
Radek Krejcif8dc59a2020-11-25 13:47:44 +010017#define _POSIX_C_SOURCE 200809L /* strdup */
Radek Krejcib7db73a2018-10-24 14:18:40 +020018
Radek Krejcid91dbaf2018-09-21 15:51:39 +020019#include <string.h>
20
Radek Krejci70593c12020-06-13 20:48:09 +020021#include "context.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020022#include "in_internal.h"
Michal Vasko63f3d842020-07-08 10:10:14 +020023#include "xml.h"
Radek Krejci2d7a47b2019-05-16 13:34:10 +020024
Michal Vaskob36053d2020-03-26 15:49:30 +010025LY_ERR lyxml_ns_add(struct lyxml_ctx *xmlctx, const char *prefix, size_t prefix_len, char *uri);
Michal Vaskob36053d2020-03-26 15:49:30 +010026
Radek Krejcid91dbaf2018-09-21 15:51:39 +020027static void
28test_element(void **state)
29{
Michal Vaskob36053d2020-03-26 15:49:30 +010030 struct lyxml_ctx *xmlctx;
Michal Vasko63f3d842020-07-08 10:10:14 +020031 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +010032 const char *str;
Radek Krejcid91dbaf2018-09-21 15:51:39 +020033
34 /* empty */
35 str = "";
Michal Vasko63f3d842020-07-08 10:10:14 +020036 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +020037 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +010038 assert_int_equal(LYXML_END, xmlctx->status);
Michal Vaskob36053d2020-03-26 15:49:30 +010039 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +020040 ly_in_free(in, 0);
Radek Krejcid91dbaf2018-09-21 15:51:39 +020041
Radek Krejcib1890642018-10-03 14:05:40 +020042 /* end element */
43 str = "</element>";
Michal Vasko63f3d842020-07-08 10:10:14 +020044 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +020045 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +010046 CHECK_LOG_CTX("Stray closing element tag (\"element\").", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +020047 ly_in_free(in, 0);
Radek Krejcib1890642018-10-03 14:05:40 +020048
Radek Krejcid91dbaf2018-09-21 15:51:39 +020049 /* no element */
Michal Vaskob36053d2020-03-26 15:49:30 +010050 str = "no data present";
Michal Vasko63f3d842020-07-08 10:10:14 +020051 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +020052 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +010053 CHECK_LOG_CTX("Invalid character sequence \"no data present\", expected element tag start ('<').", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +020054 ly_in_free(in, 0);
Radek Krejcid91dbaf2018-09-21 15:51:39 +020055
56 /* not supported DOCTYPE */
Michal Vaskob36053d2020-03-26 15:49:30 +010057 str = "<!DOCTYPE greeting SYSTEM \"hello.dtd\"><greeting/>";
Michal Vasko63f3d842020-07-08 10:10:14 +020058 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +020059 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +010060 CHECK_LOG_CTX("Document Type Declaration not supported.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +020061 ly_in_free(in, 0);
Radek Krejcid91dbaf2018-09-21 15:51:39 +020062
Radek Krejcic5c31bb2019-04-08 14:40:52 +020063 /* invalid XML */
Michal Vaskob36053d2020-03-26 15:49:30 +010064 str = "<!NONSENSE/>";
Michal Vasko63f3d842020-07-08 10:10:14 +020065 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +020066 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +010067 CHECK_LOG_CTX("Unknown XML section \"<!NONSENSE/>\".", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +020068 ly_in_free(in, 0);
Radek Krejcic5c31bb2019-04-08 14:40:52 +020069
Michal Vasko4b3f2952022-08-26 09:24:04 +020070 /* namespace ambiguity */
71 str = "<element xmlns=\"urn1\" xmlns=\"urn2\"/>";
72 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
73 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +010074 CHECK_LOG_CTX("Duplicate default XML namespaces \"urn1\" and \"urn2\".", NULL, 1);
Michal Vasko4b3f2952022-08-26 09:24:04 +020075 ly_in_free(in, 0);
76
77 /* prefix duplicate */
78 str = "<element xmlns:a=\"urn1\" xmlns:a=\"urn2\"/>";
79 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
80 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +010081 CHECK_LOG_CTX("Duplicate XML NS prefix \"a\" used for namespaces \"urn1\" and \"urn2\".", NULL, 1);
Michal Vasko4b3f2952022-08-26 09:24:04 +020082 ly_in_free(in, 0);
83
Radek Krejcid91dbaf2018-09-21 15:51:39 +020084 /* unqualified element */
85 str = " < element/>";
Michal Vasko63f3d842020-07-08 10:10:14 +020086 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +020087 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +010088 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
89 assert_null(xmlctx->prefix);
90 assert_true(!strncmp("element", xmlctx->name, xmlctx->name_len));
91 assert_int_equal(1, xmlctx->elements.count);
Radek Krejci28e8cb52019-03-08 11:31:31 +010092
Michal Vaskob36053d2020-03-26 15:49:30 +010093 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
94 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
95 assert_true(!strncmp("", xmlctx->value, xmlctx->value_len));
96
97 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
98 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
99
100 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
101 assert_int_equal(LYXML_END, xmlctx->status);
102 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200103 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100104
105 /* element with attribute */
Radek Krejci28e8cb52019-03-08 11:31:31 +0100106 str = " < element attr=\'x\'/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200107 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200108 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100109 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
110 assert_true(!strncmp("element", xmlctx->name, xmlctx->name_len));
111 assert_null(xmlctx->prefix);
112 assert_int_equal(1, xmlctx->elements.count);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200113
Michal Vaskob36053d2020-03-26 15:49:30 +0100114 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
115 assert_int_equal(LYXML_ATTRIBUTE, xmlctx->status);
116 assert_true(!strncmp("attr", xmlctx->name, xmlctx->name_len));
117 assert_null(xmlctx->prefix);
118
119 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
120 assert_int_equal(LYXML_ATTR_CONTENT, xmlctx->status);
121 assert_int_equal(1, xmlctx->elements.count);
122 assert_true(!strncmp("x", xmlctx->value, xmlctx->value_len));
123
124 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
125 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
126
127 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
128 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
129 assert_int_equal(0, xmlctx->elements.count);
130
131 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
132 assert_int_equal(LYXML_END, xmlctx->status);
133 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200134 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100135
136 /* headers and comments */
Michal Vasko8cf6f722022-02-18 13:08:23 +0100137 str = "<?xml version=\"1.0\"?> <!-- comment --> <?TEST xxx?> <element/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200138 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200139 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100140 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
141 assert_true(!strncmp("element", xmlctx->name, xmlctx->name_len));
142 assert_null(xmlctx->prefix);
143 assert_int_equal(1, xmlctx->elements.count);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200144
Michal Vaskob36053d2020-03-26 15:49:30 +0100145 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
146 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
147
148 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
149 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
150
151 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
152 assert_int_equal(LYXML_END, xmlctx->status);
153 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200154 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100155
156 /* separate opening and closing tags, neamespaced parsed internally */
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200157 str = "<element xmlns=\"urn\"></element>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200158 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200159 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100160 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
161 assert_true(!strncmp("element", xmlctx->name, xmlctx->name_len));
162 assert_null(xmlctx->prefix);
163 assert_int_equal(1, xmlctx->elements.count);
164 assert_int_equal(1, xmlctx->ns.count);
165
166 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
167 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
168
169 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
170 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
171 assert_int_equal(0, xmlctx->elements.count);
172 assert_int_equal(0, xmlctx->ns.count);
173
174 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
175 assert_int_equal(LYXML_END, xmlctx->status);
176 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200177 ly_in_free(in, 0);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200178
179 /* qualified element */
180 str = " < yin:element/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200181 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200182 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100183 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
184 assert_true(!strncmp("element", xmlctx->name, xmlctx->name_len));
185 assert_true(!strncmp("yin", xmlctx->prefix, xmlctx->prefix_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200186
Michal Vaskob36053d2020-03-26 15:49:30 +0100187 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
188 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
189
190 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
191 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
192
193 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
194 assert_int_equal(LYXML_END, xmlctx->status);
195 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200196 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100197
198 /* non-matching closing tag */
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200199 str = "<yin:element xmlns=\"urn\"></element>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200200 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200201 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100202 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
203 assert_true(!strncmp("element", xmlctx->name, xmlctx->name_len));
204 assert_true(!strncmp("yin", xmlctx->prefix, xmlctx->prefix_len));
205 assert_int_equal(1, xmlctx->elements.count);
206 assert_int_equal(1, xmlctx->ns.count);
207
208 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
209 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
210
211 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100212 CHECK_LOG_CTX("Opening (\"yin:element\") and closing (\"element\") elements tag mismatch.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200213 lyxml_ctx_free(xmlctx);
214 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100215
Michal Vasko63f3d842020-07-08 10:10:14 +0200216 /* invalid closing tag */
217 str = "<yin:element xmlns=\"urn\"></yin:element/>";
218 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200219 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko63f3d842020-07-08 10:10:14 +0200220 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100221 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100222 CHECK_LOG_CTX("Invalid character sequence \"/>\", expected element tag termination ('>').", NULL, 1);
Michal Vaskob36053d2020-03-26 15:49:30 +0100223 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200224 ly_in_free(in, 0);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200225
226 /* UTF8 characters */
227 str = "<𠜎€𠜎Øn:𠜎€𠜎Øn/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200228 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200229 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100230 assert_true(!strncmp("𠜎€𠜎Øn", xmlctx->name, xmlctx->name_len));
231 assert_true(!strncmp("𠜎€𠜎Øn", xmlctx->prefix, xmlctx->prefix_len));
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200232
Michal Vaskob36053d2020-03-26 15:49:30 +0100233 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
234 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
235
236 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
237 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
238
239 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
240 assert_int_equal(LYXML_END, xmlctx->status);
241 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200242 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100243
244 /* invalid UTF-8 characters */
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200245 str = "<¢:element>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200246 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200247 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100248 CHECK_LOG_CTX("Identifier \"¢:element>\" starts with an invalid character.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200249 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100250
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200251 str = "<yin:c⁐element>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200252 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200253 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100254 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100255 CHECK_LOG_CTX("Invalid character sequence \"⁐element>\", expected element tag end ('>' or '/>') or an attribute.", NULL, 1);
Michal Vaskob36053d2020-03-26 15:49:30 +0100256 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200257 ly_in_free(in, 0);
Radek Krejci339e2de2019-05-17 14:28:24 +0200258
259 /* mixed content */
260 str = "<a>text <b>x</b></a>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200261 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200262 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100263 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
264 assert_true(!strncmp("a", xmlctx->name, xmlctx->name_len));
265 assert_null(xmlctx->prefix);
Radek Krejci339e2de2019-05-17 14:28:24 +0200266
Michal Vaskob36053d2020-03-26 15:49:30 +0100267 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
268 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
269 assert_true(!strncmp("text ", xmlctx->value, xmlctx->value_len));
270
271 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
272 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
273 assert_true(!strncmp("b", xmlctx->name, xmlctx->name_len));
274 assert_null(xmlctx->prefix);
275
276 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
277 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
278 assert_true(!strncmp("x", xmlctx->value, xmlctx->value_len));
279
280 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
281 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
282
283 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
284 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
285
286 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
287 assert_int_equal(LYXML_END, xmlctx->status);
288 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200289 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100290
291 /* tag mismatch */
David Sedlák54a6f132019-07-16 15:14:18 +0200292 str = "<a>text</b>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200293 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200294 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100295 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
296 assert_true(!strncmp("a", xmlctx->name, xmlctx->name_len));
297 assert_null(xmlctx->prefix);
David Sedlák54a6f132019-07-16 15:14:18 +0200298
Michal Vaskob36053d2020-03-26 15:49:30 +0100299 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
300 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
301 assert_true(!strncmp("text", xmlctx->value, xmlctx->value_len));
302
303 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100304 CHECK_LOG_CTX("Opening (\"a\") and closing (\"b\") elements tag mismatch.", NULL, 1);
Michal Vaskob36053d2020-03-26 15:49:30 +0100305 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200306 ly_in_free(in, 0);
Radek Krejcid972c252018-09-25 13:23:39 +0200307}
308
309static void
310test_attribute(void **state)
311{
Michal Vaskob36053d2020-03-26 15:49:30 +0100312 const char *str;
313 struct lyxml_ctx *xmlctx;
Michal Vasko63f3d842020-07-08 10:10:14 +0200314 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +0100315 struct lyxml_ns *ns;
Radek Krejcid972c252018-09-25 13:23:39 +0200316
Radek Krejcid972c252018-09-25 13:23:39 +0200317 /* not an attribute */
Michal Vaskob36053d2020-03-26 15:49:30 +0100318 str = "<e unknown/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200319 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200320 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100321 CHECK_LOG_CTX("Invalid character sequence \"/>\", expected '='.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200322 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100323
324 str = "<e xxx=/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200325 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200326 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100327 CHECK_LOG_CTX("Invalid character sequence \"/>\", expected either single or double quotation mark.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200328 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100329
330 str = "<e xxx\n = yyy/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200331 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200332 assert_int_equal(LY_EVALID, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100333 CHECK_LOG_CTX("Invalid character sequence \"yyy/>\", expected either single or double quotation mark.", NULL, 2);
Michal Vasko63f3d842020-07-08 10:10:14 +0200334 ly_in_free(in, 0);
Radek Krejcid972c252018-09-25 13:23:39 +0200335
336 /* valid attribute */
Michal Vaskob36053d2020-03-26 15:49:30 +0100337 str = "<e attr=\"val\"";
Michal Vasko63f3d842020-07-08 10:10:14 +0200338 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200339 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100340 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
341 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
342 assert_int_equal(LYXML_ATTRIBUTE, xmlctx->status);
343 assert_true(!strncmp("attr", xmlctx->name, xmlctx->name_len));
344 assert_null(xmlctx->prefix);
Radek Krejcid972c252018-09-25 13:23:39 +0200345
Michal Vaskob36053d2020-03-26 15:49:30 +0100346 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
347 assert_int_equal(LYXML_ATTR_CONTENT, xmlctx->status);
Radek Iša85a55232021-02-16 10:44:43 +0100348 assert_true(!strncmp("val", xmlctx->value, xmlctx->value_len));
Michal Vaskob36053d2020-03-26 15:49:30 +0100349 assert_int_equal(xmlctx->ws_only, 0);
350 assert_int_equal(xmlctx->dynamic, 0);
351 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200352 ly_in_free(in, 0);
Radek Krejci28e8cb52019-03-08 11:31:31 +0100353
Michal Vaskob36053d2020-03-26 15:49:30 +0100354 /* valid namespace with prefix */
355 str = "<e xmlns:nc\n = \'urn\'/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200356 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200357 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100358 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
359 assert_int_equal(1, xmlctx->ns.count);
360 ns = (struct lyxml_ns *)xmlctx->ns.objs[0];
361 assert_string_equal(ns->prefix, "nc");
362 assert_string_equal(ns->uri, "urn");
363 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200364 ly_in_free(in, 0);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200365}
366
Radek Krejci7a7fa902018-09-25 17:08:21 +0200367static void
368test_text(void **state)
369{
Michal Vaskob36053d2020-03-26 15:49:30 +0100370 const char *str;
371 struct lyxml_ctx *xmlctx;
Michal Vasko63f3d842020-07-08 10:10:14 +0200372 struct ly_in *in;
Radek Krejci7a7fa902018-09-25 17:08:21 +0200373
374 /* empty attribute value */
Michal Vaskob36053d2020-03-26 15:49:30 +0100375 str = "<e a=\"\"";
Michal Vasko63f3d842020-07-08 10:10:14 +0200376 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200377 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100378 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
379 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
380 assert_int_equal(LYXML_ATTRIBUTE, xmlctx->status);
Radek Krejcib1890642018-10-03 14:05:40 +0200381
Michal Vaskob36053d2020-03-26 15:49:30 +0100382 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
383 assert_int_equal(LYXML_ATTR_CONTENT, xmlctx->status);
384 assert_true(!strncmp("", xmlctx->value, xmlctx->value_len));
385 assert_int_equal(xmlctx->ws_only, 1);
386 assert_int_equal(xmlctx->dynamic, 0);
Michal Vasko63f3d842020-07-08 10:10:14 +0200387 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100388
389 /* empty value but in single quotes */
Michal Vasko63f3d842020-07-08 10:10:14 +0200390 assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'\'", &in));
391 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100392 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100393 xmlctx->status = LYXML_ATTRIBUTE;
Michal Vaskob36053d2020-03-26 15:49:30 +0100394 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
395 assert_int_equal(LYXML_ATTR_CONTENT, xmlctx->status);
396 assert_true(!strncmp("", xmlctx->value, xmlctx->value_len));
397 assert_int_equal(xmlctx->ws_only, 1);
398 assert_int_equal(xmlctx->dynamic, 0);
Michal Vasko63f3d842020-07-08 10:10:14 +0200399 ly_in_free(in, 0);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200400
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200401 /* empty element content - only formating before defining child */
Michal Vasko63f3d842020-07-08 10:10:14 +0200402 assert_int_equal(LY_SUCCESS, ly_in_new_memory(">\n <y>", &in));
403 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100404 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100405 xmlctx->status = LYXML_ELEMENT;
Michal Vaskob36053d2020-03-26 15:49:30 +0100406 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
407 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
408 assert_true(!strncmp("\n ", xmlctx->value, xmlctx->value_len));
409 assert_int_equal(xmlctx->ws_only, 1);
410 assert_int_equal(xmlctx->dynamic, 0);
Michal Vasko63f3d842020-07-08 10:10:14 +0200411 ly_in_free(in, 0);
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200412
Radek Krejci7a7fa902018-09-25 17:08:21 +0200413 /* empty element content is invalid - missing content terminating character < */
Michal Vasko63f3d842020-07-08 10:10:14 +0200414 assert_int_equal(LY_SUCCESS, ly_in_new_memory("", &in));
415 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100416 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100417 xmlctx->status = LYXML_ELEM_CONTENT;
Michal Vaskob36053d2020-03-26 15:49:30 +0100418 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100419 CHECK_LOG_CTX("Unexpected end-of-input.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200420 ly_in_free(in, 0);
Radek Krejcied6c6ad2018-09-26 09:10:18 +0200421
Michal Vasko63f3d842020-07-08 10:10:14 +0200422 assert_int_equal(LY_SUCCESS, ly_in_new_memory("xxx", &in));
423 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100424 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100425 xmlctx->status = LYXML_ELEM_CONTENT;
Michal Vaskob36053d2020-03-26 15:49:30 +0100426 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100427 CHECK_LOG_CTX("Invalid character sequence \"xxx\", expected element tag start ('<').", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200428 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100429
430 lyxml_ctx_free(xmlctx);
Michal Vasko7a266772024-01-23 11:02:38 +0100431 ly_log_location_revert(0, 0, 0, 4);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200432
Radek Krejci7a7fa902018-09-25 17:08:21 +0200433 /* valid strings */
Radek Krejci339e2de2019-05-17 14:28:24 +0200434 str = "<a>€𠜎Øn \n&lt;&amp;&quot;&apos;&gt; &#82;&#x4f;&#x4B;</a>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200435 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200436 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100437 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
438
439 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
440 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
441 assert_true(!strncmp("€𠜎Øn \n<&\"\'> ROK", xmlctx->value, xmlctx->value_len));
442 assert_int_equal(xmlctx->ws_only, 0);
443 assert_int_equal(xmlctx->dynamic, 1);
444 free((char *)xmlctx->value);
Michal Vasko63f3d842020-07-08 10:10:14 +0200445 ly_in_free(in, 0);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200446
Radek Krejci117d2082018-09-26 10:05:14 +0200447 /* test using n-bytes UTF8 hexadecimal code points */
Michal Vasko63f3d842020-07-08 10:10:14 +0200448 assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'&#x0024;&#x00A2;&#x20ac;&#x10348;\'", &in));
449 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100450 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100451 xmlctx->status = LYXML_ATTRIBUTE;
Michal Vaskob36053d2020-03-26 15:49:30 +0100452 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
453 assert_int_equal(LYXML_ATTR_CONTENT, xmlctx->status);
454 assert_true(!strncmp("$¢€𐍈", xmlctx->value, xmlctx->value_len));
455 assert_int_equal(xmlctx->ws_only, 0);
456 assert_int_equal(xmlctx->dynamic, 1);
Michal Vasko8cf6f722022-02-18 13:08:23 +0100457 ly_in_free(in, 0);
458
459 /* CDATA value */
460 assert_int_equal(LY_SUCCESS, ly_in_new_memory("> <![CDATA[ special non-escaped chars <>&\"' ]]> </a>", &in));
461 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100462 ly_log_location(NULL, NULL, NULL, in);
Michal Vasko8cf6f722022-02-18 13:08:23 +0100463 xmlctx->status = LYXML_ATTR_CONTENT;
464 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
465 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
466 assert_true(!strncmp(" special non-escaped chars <>&\"' ", xmlctx->value, xmlctx->value_len));
467 assert_int_equal(xmlctx->ws_only, 0);
468 assert_int_equal(xmlctx->dynamic, 1);
Michal Vaskob36053d2020-03-26 15:49:30 +0100469 free((char *)xmlctx->value);
Michal Vasko63f3d842020-07-08 10:10:14 +0200470 ly_in_free(in, 0);
Radek Krejcid70d1072018-10-09 14:20:47 +0200471
Radek Krejci7a7fa902018-09-25 17:08:21 +0200472 /* invalid characters in string */
Michal Vasko63f3d842020-07-08 10:10:14 +0200473 assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'&#x52\'", &in));
474 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100475 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100476 xmlctx->status = LYXML_ATTRIBUTE;
Michal Vaskob36053d2020-03-26 15:49:30 +0100477 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100478 CHECK_LOG_CTX("Invalid character sequence \"'\", expected ;.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200479 ly_in_free(in, 0);
Radek Krejci117d2082018-09-26 10:05:14 +0200480
Michal Vasko63f3d842020-07-08 10:10:14 +0200481 assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\"&#82\"", &in));
482 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100483 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100484 xmlctx->status = LYXML_ATTRIBUTE;
Michal Vaskob36053d2020-03-26 15:49:30 +0100485 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100486 CHECK_LOG_CTX("Invalid character sequence \"\"\", expected ;.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200487 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100488
Michal Vasko63f3d842020-07-08 10:10:14 +0200489 assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\"&nonsense;\"", &in));
490 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100491 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100492 xmlctx->status = LYXML_ATTRIBUTE;
Michal Vaskob36053d2020-03-26 15:49:30 +0100493 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100494 CHECK_LOG_CTX("Entity reference \"&nonsense;\" not supported, only predefined references allowed.", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200495 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100496
Michal Vasko63f3d842020-07-08 10:10:14 +0200497 assert_int_equal(LY_SUCCESS, ly_in_new_memory(">&#o122;", &in));
498 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100499 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100500 xmlctx->status = LYXML_ELEMENT;
Michal Vaskob36053d2020-03-26 15:49:30 +0100501 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100502 CHECK_LOG_CTX("Invalid character reference \"&#o122;\".", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200503 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100504
Michal Vasko63f3d842020-07-08 10:10:14 +0200505 assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'&#x06;\'", &in));
506 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100507 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100508 xmlctx->status = LYXML_ATTRIBUTE;
Michal Vaskob36053d2020-03-26 15:49:30 +0100509 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100510 CHECK_LOG_CTX("Invalid character reference \"&#x06;\'\" (0x00000006).", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200511 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100512
Michal Vasko63f3d842020-07-08 10:10:14 +0200513 assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'&#xfdd0;\'", &in));
514 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100515 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100516 xmlctx->status = LYXML_ATTRIBUTE;
Michal Vaskob36053d2020-03-26 15:49:30 +0100517 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100518 CHECK_LOG_CTX("Invalid character reference \"&#xfdd0;\'\" (0x0000fdd0).", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200519 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100520
Michal Vasko63f3d842020-07-08 10:10:14 +0200521 assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'&#xffff;\'", &in));
522 xmlctx->in = in;
Michal Vasko7a266772024-01-23 11:02:38 +0100523 ly_log_location(NULL, NULL, NULL, in);
Michal Vaskob36053d2020-03-26 15:49:30 +0100524 xmlctx->status = LYXML_ATTRIBUTE;
Michal Vaskob36053d2020-03-26 15:49:30 +0100525 assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
Michal Vasko7a266772024-01-23 11:02:38 +0100526 CHECK_LOG_CTX("Invalid character reference \"&#xffff;\'\" (0x0000ffff).", NULL, 1);
Michal Vasko63f3d842020-07-08 10:10:14 +0200527 ly_in_free(in, 0);
Michal Vaskob36053d2020-03-26 15:49:30 +0100528
529 lyxml_ctx_free(xmlctx);
Michal Vasko7a266772024-01-23 11:02:38 +0100530 ly_log_location_revert(0, 0, 0, 9);
Radek Krejci7a7fa902018-09-25 17:08:21 +0200531}
532
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200533static void
534test_ns(void **state)
535{
Michal Vaskob36053d2020-03-26 15:49:30 +0100536 const char *str;
537 struct lyxml_ctx *xmlctx;
Michal Vasko63f3d842020-07-08 10:10:14 +0200538 struct ly_in *in;
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200539 const struct lyxml_ns *ns;
540
Michal Vaskob36053d2020-03-26 15:49:30 +0100541 /* opening element1 */
542 str = "<element1/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200543 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200544 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200545
Radek Krejcie0734d22019-04-05 15:54:28 +0200546 /* processing namespace definitions */
Michal Vaskob36053d2020-03-26 15:49:30 +0100547 assert_int_equal(LY_SUCCESS, lyxml_ns_add(xmlctx, NULL, 0, strdup("urn:default")));
548 assert_int_equal(LY_SUCCESS, lyxml_ns_add(xmlctx, "nc", 2, strdup("urn:nc1")));
Radek Krejcie0734d22019-04-05 15:54:28 +0200549 /* simulate adding open element2 into context */
Michal Vaskob36053d2020-03-26 15:49:30 +0100550 xmlctx->elements.count++;
Radek Krejcie0734d22019-04-05 15:54:28 +0200551 /* processing namespace definitions */
Michal Vaskob36053d2020-03-26 15:49:30 +0100552 assert_int_equal(LY_SUCCESS, lyxml_ns_add(xmlctx, "nc", 2, strdup("urn:nc2")));
553 assert_int_equal(3, xmlctx->ns.count);
554 assert_int_not_equal(0, xmlctx->ns.size);
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200555
Michal Vaskoc8a230d2020-08-14 12:17:10 +0200556 ns = lyxml_ns_get(&xmlctx->ns, NULL, 0);
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200557 assert_non_null(ns);
558 assert_null(ns->prefix);
559 assert_string_equal("urn:default", ns->uri);
560
Michal Vaskoc8a230d2020-08-14 12:17:10 +0200561 ns = lyxml_ns_get(&xmlctx->ns, "nc", 2);
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200562 assert_non_null(ns);
563 assert_string_equal("nc", ns->prefix);
564 assert_string_equal("urn:nc2", ns->uri);
565
Radek Krejcie0734d22019-04-05 15:54:28 +0200566 /* simulate closing element2 */
Michal Vaskob36053d2020-03-26 15:49:30 +0100567 xmlctx->elements.count--;
568 lyxml_ns_rm(xmlctx);
569 assert_int_equal(2, xmlctx->ns.count);
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200570
Michal Vaskoc8a230d2020-08-14 12:17:10 +0200571 ns = lyxml_ns_get(&xmlctx->ns, "nc", 2);
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200572 assert_non_null(ns);
573 assert_string_equal("nc", ns->prefix);
574 assert_string_equal("urn:nc1", ns->uri);
575
Michal Vaskob36053d2020-03-26 15:49:30 +0100576 /* close element1 */
577 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
578 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
579 assert_int_equal(0, xmlctx->ns.count);
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200580
Michal Vaskoc8a230d2020-08-14 12:17:10 +0200581 assert_null(lyxml_ns_get(&xmlctx->ns, "nc", 2));
582 assert_null(lyxml_ns_get(&xmlctx->ns, NULL, 0));
Michal Vaskob36053d2020-03-26 15:49:30 +0100583
584 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200585 ly_in_free(in, 0);
Radek Krejci4b74d5e2018-09-26 14:30:55 +0200586}
587
David Sedlákb3bed7a2019-03-08 11:53:37 +0100588static void
Radek Krejcie0734d22019-04-05 15:54:28 +0200589test_ns2(void **state)
590{
Michal Vaskob36053d2020-03-26 15:49:30 +0100591 const char *str;
592 struct lyxml_ctx *xmlctx;
Michal Vasko63f3d842020-07-08 10:10:14 +0200593 struct ly_in *in;
Radek Krejcie0734d22019-04-05 15:54:28 +0200594
Michal Vaskob36053d2020-03-26 15:49:30 +0100595 /* opening element1 */
596 str = "<element1/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200597 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200598 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Radek Krejcie0734d22019-04-05 15:54:28 +0200599
Radek Krejcie0734d22019-04-05 15:54:28 +0200600 /* default namespace defined in parent element1 */
Michal Vaskob36053d2020-03-26 15:49:30 +0100601 assert_int_equal(LY_SUCCESS, lyxml_ns_add(xmlctx, NULL, 0, strdup("urn:default")));
602 assert_int_equal(1, xmlctx->ns.count);
Radek Krejcie0734d22019-04-05 15:54:28 +0200603 /* going into child element1 */
Radek Krejcie0734d22019-04-05 15:54:28 +0200604 /* simulate adding open element1 into context */
Michal Vaskob36053d2020-03-26 15:49:30 +0100605 xmlctx->elements.count++;
Radek Krejcie0734d22019-04-05 15:54:28 +0200606 /* no namespace defined, going out (first, simulate closing of so far open element) */
Michal Vaskob36053d2020-03-26 15:49:30 +0100607 xmlctx->elements.count--;
608 lyxml_ns_rm(xmlctx);
609 assert_int_equal(1, xmlctx->ns.count);
610
611 /* nothing else, going out of the parent element1 */
612 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
613 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
614 assert_int_equal(0, xmlctx->ns.count);
615
616 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200617 ly_in_free(in, 0);
Radek Krejcie0734d22019-04-05 15:54:28 +0200618}
619
Radek Krejcifad79c92019-06-04 11:43:30 +0200620static void
621test_simple_xml(void **state)
622{
Michal Vaskob36053d2020-03-26 15:49:30 +0100623 struct lyxml_ctx *xmlctx;
Michal Vasko63f3d842020-07-08 10:10:14 +0200624 struct ly_in *in;
Radek Krejcie553e6d2019-06-07 15:33:18 +0200625 const char *test_input = "<elem1 attr1=\"value\"> <elem2 attr2=\"value\" /> </elem1>";
Radek Krejcifad79c92019-06-04 11:43:30 +0200626
Michal Vasko63f3d842020-07-08 10:10:14 +0200627 assert_int_equal(LY_SUCCESS, ly_in_new_memory(test_input, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200628 assert_int_equal(LY_SUCCESS, lyxml_ctx_new(UTEST_LYCTX, in, &xmlctx));
Michal Vaskob36053d2020-03-26 15:49:30 +0100629 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200630 assert_string_equal(xmlctx->in->current, "attr1=\"value\"> <elem2 attr2=\"value\" /> </elem1>");
Radek Krejcifad79c92019-06-04 11:43:30 +0200631
Michal Vaskob36053d2020-03-26 15:49:30 +0100632 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
633 assert_int_equal(LYXML_ATTRIBUTE, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200634 assert_string_equal(xmlctx->in->current, "=\"value\"> <elem2 attr2=\"value\" /> </elem1>");
Radek Krejcifad79c92019-06-04 11:43:30 +0200635
Michal Vaskob36053d2020-03-26 15:49:30 +0100636 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
637 assert_int_equal(LYXML_ATTR_CONTENT, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200638 assert_string_equal(xmlctx->in->current, "> <elem2 attr2=\"value\" /> </elem1>");
Radek Krejcifad79c92019-06-04 11:43:30 +0200639
Michal Vaskob36053d2020-03-26 15:49:30 +0100640 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
641 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200642 assert_string_equal(xmlctx->in->current, "<elem2 attr2=\"value\" /> </elem1>");
Radek Krejcifad79c92019-06-04 11:43:30 +0200643
Michal Vaskob36053d2020-03-26 15:49:30 +0100644 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
645 assert_int_equal(LYXML_ELEMENT, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200646 assert_string_equal(xmlctx->in->current, "attr2=\"value\" /> </elem1>");
Radek Krejcifad79c92019-06-04 11:43:30 +0200647
Michal Vaskob36053d2020-03-26 15:49:30 +0100648 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
649 assert_int_equal(LYXML_ATTRIBUTE, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200650 assert_string_equal(xmlctx->in->current, "=\"value\" /> </elem1>");
Radek Krejcie553e6d2019-06-07 15:33:18 +0200651
Michal Vaskob36053d2020-03-26 15:49:30 +0100652 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
653 assert_int_equal(LYXML_ATTR_CONTENT, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200654 assert_string_equal(xmlctx->in->current, " /> </elem1>");
Radek Krejcie553e6d2019-06-07 15:33:18 +0200655
Michal Vaskob36053d2020-03-26 15:49:30 +0100656 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
657 assert_int_equal(LYXML_ELEM_CONTENT, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200658 assert_string_equal(xmlctx->in->current, "/> </elem1>");
Radek Krejcie553e6d2019-06-07 15:33:18 +0200659
Michal Vaskob36053d2020-03-26 15:49:30 +0100660 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
661 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200662 assert_string_equal(xmlctx->in->current, " </elem1>");
Radek Krejcifad79c92019-06-04 11:43:30 +0200663
Michal Vaskob36053d2020-03-26 15:49:30 +0100664 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
665 assert_int_equal(LYXML_ELEM_CLOSE, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200666 assert_string_equal(xmlctx->in->current, "");
Michal Vaskob36053d2020-03-26 15:49:30 +0100667
668 assert_int_equal(LY_SUCCESS, lyxml_ctx_next(xmlctx));
669 assert_int_equal(LYXML_END, xmlctx->status);
Michal Vasko63f3d842020-07-08 10:10:14 +0200670 assert_string_equal(xmlctx->in->current, "");
Michal Vaskob36053d2020-03-26 15:49:30 +0100671
672 lyxml_ctx_free(xmlctx);
Michal Vasko63f3d842020-07-08 10:10:14 +0200673 ly_in_free(in, 0);
Radek Krejcifad79c92019-06-04 11:43:30 +0200674}
675
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100676int
677main(void)
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200678{
679 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200680 UTEST(test_element),
681 UTEST(test_attribute),
682 UTEST(test_text),
683 UTEST(test_ns),
684 UTEST(test_ns2),
685 UTEST(test_simple_xml),
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200686 };
687
Radek Iša56ca9e42020-09-08 18:42:00 +0200688 return cmocka_run_group_tests(tests, NULL, NULL);
Radek Krejcid91dbaf2018-09-21 15:51:39 +0200689}