pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
pcmk__xml_needs_escape_test.c
Go to the documentation of this file.
1 /*
2  * Copyright 2024 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU General Public License version 2
7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
14 
15 #include "crmcommon_private.h"
16 
17 static void
18 null_empty(void **state)
19 {
20  assert_false(pcmk__xml_needs_escape(NULL, pcmk__xml_escape_text));
21  assert_false(pcmk__xml_needs_escape(NULL, pcmk__xml_escape_attr));
23 
27 }
28 
29 static void
30 invalid_type(void **state)
31 {
32  const enum pcmk__xml_escape_type type = (enum pcmk__xml_escape_type) -1;
33 
34  // Easier to ignore invalid type for NULL or empty string
35  assert_false(pcmk__xml_needs_escape(NULL, type));
36  assert_false(pcmk__xml_needs_escape("", type));
37 
38  // Otherwise, assert if we somehow passed an invalid type
40 }
41 
42 static void
43 escape_unchanged(void **state)
44 {
45  // No escaped characters (note: this string includes single quote at end)
46  const char *unchanged = "abcdefghijklmnopqrstuvwxyz"
47  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
48  "0123456789"
49  "`~!@#$%^*()-_=+/|\\[]{}?.,'";
50 
51  assert_false(pcmk__xml_needs_escape(unchanged, pcmk__xml_escape_text));
52  assert_false(pcmk__xml_needs_escape(unchanged, pcmk__xml_escape_attr));
53  assert_false(pcmk__xml_needs_escape(unchanged,
55 }
56 
57 // Ensure special characters get escaped at start, middle, and end
58 
59 static void
60 escape_left_angle(void **state)
61 {
62  const char *l_angle_left = "<abcdef";
63  const char *l_angle_mid = "abc<def";
64  const char *l_angle_right = "abcdef<";
65 
66  assert_true(pcmk__xml_needs_escape(l_angle_left, pcmk__xml_escape_text));
67  assert_true(pcmk__xml_needs_escape(l_angle_mid, pcmk__xml_escape_text));
68  assert_true(pcmk__xml_needs_escape(l_angle_right, pcmk__xml_escape_text));
69 
70  assert_true(pcmk__xml_needs_escape(l_angle_left, pcmk__xml_escape_attr));
71  assert_true(pcmk__xml_needs_escape(l_angle_mid, pcmk__xml_escape_attr));
72  assert_true(pcmk__xml_needs_escape(l_angle_right, pcmk__xml_escape_attr));
73 
74  assert_false(pcmk__xml_needs_escape(l_angle_left,
76  assert_false(pcmk__xml_needs_escape(l_angle_mid,
78  assert_false(pcmk__xml_needs_escape(l_angle_right,
80 }
81 
82 static void
83 escape_right_angle(void **state)
84 {
85  const char *r_angle_left = ">abcdef";
86  const char *r_angle_mid = "abc>def";
87  const char *r_angle_right = "abcdef>";
88 
89  assert_true(pcmk__xml_needs_escape(r_angle_left, pcmk__xml_escape_text));
90  assert_true(pcmk__xml_needs_escape(r_angle_mid, pcmk__xml_escape_text));
91  assert_true(pcmk__xml_needs_escape(r_angle_right, pcmk__xml_escape_text));
92 
93  assert_true(pcmk__xml_needs_escape(r_angle_left, pcmk__xml_escape_attr));
94  assert_true(pcmk__xml_needs_escape(r_angle_mid, pcmk__xml_escape_attr));
95  assert_true(pcmk__xml_needs_escape(r_angle_right, pcmk__xml_escape_attr));
96 
97  assert_false(pcmk__xml_needs_escape(r_angle_left,
99  assert_false(pcmk__xml_needs_escape(r_angle_mid,
101  assert_false(pcmk__xml_needs_escape(r_angle_right,
103 }
104 
105 static void
106 escape_ampersand(void **state)
107 {
108  const char *ampersand_left = "&abcdef";
109  const char *ampersand_mid = "abc&def";
110  const char *ampersand_right = "abcdef&";
111 
112  assert_true(pcmk__xml_needs_escape(ampersand_left, pcmk__xml_escape_text));
113  assert_true(pcmk__xml_needs_escape(ampersand_mid, pcmk__xml_escape_text));
114  assert_true(pcmk__xml_needs_escape(ampersand_right, pcmk__xml_escape_text));
115 
116  assert_true(pcmk__xml_needs_escape(ampersand_left, pcmk__xml_escape_attr));
117  assert_true(pcmk__xml_needs_escape(ampersand_mid, pcmk__xml_escape_attr));
118  assert_true(pcmk__xml_needs_escape(ampersand_right, pcmk__xml_escape_attr));
119 
120  assert_false(pcmk__xml_needs_escape(ampersand_left,
122  assert_false(pcmk__xml_needs_escape(ampersand_mid,
124  assert_false(pcmk__xml_needs_escape(ampersand_right,
126 }
127 
128 static void
129 escape_double_quote(void **state)
130 {
131  const char *double_quote_left = "\"abcdef";
132  const char *double_quote_mid = "abc\"def";
133  const char *double_quote_right = "abcdef\"";
134 
135  assert_false(pcmk__xml_needs_escape(double_quote_left,
137  assert_false(pcmk__xml_needs_escape(double_quote_mid,
139  assert_false(pcmk__xml_needs_escape(double_quote_right,
141 
142  assert_true(pcmk__xml_needs_escape(double_quote_left,
144  assert_true(pcmk__xml_needs_escape(double_quote_mid,
146  assert_true(pcmk__xml_needs_escape(double_quote_right,
148 
149  assert_true(pcmk__xml_needs_escape(double_quote_left,
151  assert_true(pcmk__xml_needs_escape(double_quote_mid,
153  assert_true(pcmk__xml_needs_escape(double_quote_right,
155 }
156 
157 static void
158 escape_newline(void **state)
159 {
160  const char *newline_left = "\nabcdef";
161  const char *newline_mid = "abc\ndef";
162  const char *newline_right = "abcdef\n";
163 
164  assert_false(pcmk__xml_needs_escape(newline_left, pcmk__xml_escape_text));
165  assert_false(pcmk__xml_needs_escape(newline_mid, pcmk__xml_escape_text));
166  assert_false(pcmk__xml_needs_escape(newline_right, pcmk__xml_escape_text));
167 
168  assert_true(pcmk__xml_needs_escape(newline_left, pcmk__xml_escape_attr));
169  assert_true(pcmk__xml_needs_escape(newline_mid, pcmk__xml_escape_attr));
170  assert_true(pcmk__xml_needs_escape(newline_right, pcmk__xml_escape_attr));
171 
172  assert_true(pcmk__xml_needs_escape(newline_left,
174  assert_true(pcmk__xml_needs_escape(newline_mid,
176  assert_true(pcmk__xml_needs_escape(newline_right,
178 }
179 
180 static void
181 escape_tab(void **state)
182 {
183  const char *tab_left = "\tabcdef";
184  const char *tab_mid = "abc\tdef";
185  const char *tab_right = "abcdef\t";
186 
187  assert_false(pcmk__xml_needs_escape(tab_left, pcmk__xml_escape_text));
188  assert_false(pcmk__xml_needs_escape(tab_mid, pcmk__xml_escape_text));
189  assert_false(pcmk__xml_needs_escape(tab_right, pcmk__xml_escape_text));
190 
191  assert_true(pcmk__xml_needs_escape(tab_left, pcmk__xml_escape_attr));
192  assert_true(pcmk__xml_needs_escape(tab_mid, pcmk__xml_escape_attr));
193  assert_true(pcmk__xml_needs_escape(tab_right, pcmk__xml_escape_attr));
194 
197  assert_true(pcmk__xml_needs_escape(tab_right,
199 }
200 
201 static void
202 escape_carriage_return(void **state)
203 {
204  const char *cr_left = "\rabcdef";
205  const char *cr_mid = "abc\rdef";
206  const char *cr_right = "abcdef\r";
207 
208  assert_true(pcmk__xml_needs_escape(cr_left, pcmk__xml_escape_text));
209  assert_true(pcmk__xml_needs_escape(cr_mid, pcmk__xml_escape_text));
210  assert_true(pcmk__xml_needs_escape(cr_right, pcmk__xml_escape_text));
211 
212  assert_true(pcmk__xml_needs_escape(cr_left, pcmk__xml_escape_attr));
213  assert_true(pcmk__xml_needs_escape(cr_mid, pcmk__xml_escape_attr));
214  assert_true(pcmk__xml_needs_escape(cr_right, pcmk__xml_escape_attr));
215 
219 }
220 
221 static void
222 escape_nonprinting(void **state)
223 {
224  const char *alert_left = "\aabcdef";
225  const char *alert_mid = "abc\adef";
226  const char *alert_right = "abcdef\a";
227 
228  const char *delete_left = "\x7F""abcdef";
229  const char *delete_mid = "abc\x7F""def";
230  const char *delete_right = "abcdef\x7F";
231 
232  const char *nonprinting_all = "\a\x7F\x1B";
233 
234  assert_true(pcmk__xml_needs_escape(alert_left, pcmk__xml_escape_text));
235  assert_true(pcmk__xml_needs_escape(alert_mid, pcmk__xml_escape_text));
236  assert_true(pcmk__xml_needs_escape(alert_right, pcmk__xml_escape_text));
237 
238  assert_true(pcmk__xml_needs_escape(alert_left, pcmk__xml_escape_attr));
239  assert_true(pcmk__xml_needs_escape(alert_mid, pcmk__xml_escape_attr));
240  assert_true(pcmk__xml_needs_escape(alert_right, pcmk__xml_escape_attr));
241 
242  assert_false(pcmk__xml_needs_escape(alert_left,
244  assert_false(pcmk__xml_needs_escape(alert_mid,
246  assert_false(pcmk__xml_needs_escape(alert_right,
248 
249  assert_true(pcmk__xml_needs_escape(delete_left, pcmk__xml_escape_text));
250  assert_true(pcmk__xml_needs_escape(delete_mid, pcmk__xml_escape_text));
251  assert_true(pcmk__xml_needs_escape(delete_right, pcmk__xml_escape_text));
252 
253  assert_true(pcmk__xml_needs_escape(delete_left, pcmk__xml_escape_attr));
254  assert_true(pcmk__xml_needs_escape(delete_mid, pcmk__xml_escape_attr));
255  assert_true(pcmk__xml_needs_escape(delete_right, pcmk__xml_escape_attr));
256 
257  assert_false(pcmk__xml_needs_escape(delete_left,
259  assert_false(pcmk__xml_needs_escape(delete_mid,
261  assert_false(pcmk__xml_needs_escape(delete_right,
263 
264  assert_true(pcmk__xml_needs_escape(nonprinting_all, pcmk__xml_escape_text));
265  assert_true(pcmk__xml_needs_escape(nonprinting_all, pcmk__xml_escape_attr));
266  assert_false(pcmk__xml_needs_escape(nonprinting_all,
268 }
269 
270 static void
271 escape_utf8(void **state)
272 {
273  /* Non-ASCII UTF-8 characters may be two, three, or four 8-bit bytes wide
274  * and should not be escaped.
275  */
276  const char *chinese = "仅高级使用";
277  const char *two_byte = "abc""\xCF\xA6""def";
278  const char *two_byte_special = "abc""\xCF\xA6""d<ef";
279  const char *three_byte = "abc""\xEF\x98\x98""def";
280  const char *three_byte_special = "abc""\xEF\x98\x98""d<ef";
281  const char *four_byte = "abc""\xF0\x94\x81\x90""def";
282  const char *four_byte_special = "abc""\xF0\x94\x81\x90""d<ef";
283 
284  assert_false(pcmk__xml_needs_escape(chinese, pcmk__xml_escape_text));
285  assert_false(pcmk__xml_needs_escape(chinese, pcmk__xml_escape_attr));
287 
288  assert_false(pcmk__xml_needs_escape(two_byte, pcmk__xml_escape_text));
289  assert_false(pcmk__xml_needs_escape(two_byte, pcmk__xml_escape_attr));
290  assert_false(pcmk__xml_needs_escape(two_byte,
292 
293  assert_true(pcmk__xml_needs_escape(two_byte_special,
295  assert_true(pcmk__xml_needs_escape(two_byte_special,
297  assert_false(pcmk__xml_needs_escape(two_byte_special,
299 
300  assert_false(pcmk__xml_needs_escape(three_byte, pcmk__xml_escape_text));
301  assert_false(pcmk__xml_needs_escape(three_byte, pcmk__xml_escape_attr));
302  assert_false(pcmk__xml_needs_escape(three_byte,
304 
305  assert_true(pcmk__xml_needs_escape(three_byte_special,
307  assert_true(pcmk__xml_needs_escape(three_byte_special,
309  assert_false(pcmk__xml_needs_escape(three_byte_special,
311 
312  assert_false(pcmk__xml_needs_escape(four_byte, pcmk__xml_escape_text));
313  assert_false(pcmk__xml_needs_escape(four_byte, pcmk__xml_escape_attr));
314  assert_false(pcmk__xml_needs_escape(four_byte,
316 
317  assert_true(pcmk__xml_needs_escape(four_byte_special,
319  assert_true(pcmk__xml_needs_escape(four_byte_special,
321  assert_false(pcmk__xml_needs_escape(four_byte_special,
323 }
324 
326  cmocka_unit_test(null_empty),
327  cmocka_unit_test(invalid_type),
328  cmocka_unit_test(escape_unchanged),
329  cmocka_unit_test(escape_left_angle),
330  cmocka_unit_test(escape_right_angle),
331  cmocka_unit_test(escape_ampersand),
332  cmocka_unit_test(escape_double_quote),
333  cmocka_unit_test(escape_newline),
334  cmocka_unit_test(escape_tab),
335  cmocka_unit_test(escape_carriage_return),
336  cmocka_unit_test(escape_nonprinting),
337  cmocka_unit_test(escape_utf8));
bool pcmk__xml_needs_escape(const char *text, enum pcmk__xml_escape_type type)
Definition: xml.c:1028
enum crm_ais_msg_types type
Definition: cpg.c:51
pcmk__xml_escape_type
Definition: xml_internal.h:276
int pcmk__xml_test_setup_group(void **state)
Definition: unittest.c:74
#define pcmk__assert_asserts(stmt)
PCMK__UNIT_TEST(pcmk__xml_test_setup_group, NULL, cmocka_unit_test(null_empty), cmocka_unit_test(invalid_type), cmocka_unit_test(escape_unchanged), cmocka_unit_test(escape_left_angle), cmocka_unit_test(escape_right_angle), cmocka_unit_test(escape_ampersand), cmocka_unit_test(escape_double_quote), cmocka_unit_test(escape_newline), cmocka_unit_test(escape_tab), cmocka_unit_test(escape_carriage_return), cmocka_unit_test(escape_nonprinting), cmocka_unit_test(escape_utf8))