pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
pcmk__xml_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 assert_escape(const char *str, const char *reference,
20 {
21  gchar *buf = pcmk__xml_escape(str, type);
22 
23  assert_string_equal(buf, reference);
24  g_free(buf);
25 }
26 
27 static void
28 null_empty(void **state)
29 {
30  assert_null(pcmk__xml_escape(NULL, pcmk__xml_escape_text));
31  assert_null(pcmk__xml_escape(NULL, pcmk__xml_escape_attr));
33 
34  assert_escape("", "", pcmk__xml_escape_text);
35  assert_escape("", "", pcmk__xml_escape_attr);
36  assert_escape("", "", pcmk__xml_escape_attr_pretty);
37 }
38 
39 static void
40 invalid_type(void **state)
41 {
42  const enum pcmk__xml_escape_type type = (enum pcmk__xml_escape_type) -1;
43 
44  // Easier to ignore invalid type for NULL or empty string
45  assert_null(pcmk__xml_escape(NULL, type));
46  assert_escape("", "", type);
47 
48  // Otherwise, assert if we somehow passed an invalid type
50 }
51 
52 static void
53 escape_unchanged(void **state)
54 {
55  // No escaped characters (note: this string includes single quote at end)
56  const char *unchanged = "abcdefghijklmnopqrstuvwxyz"
57  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
58  "0123456789"
59  "`~!@#$%^*()-_=+/|\\[]{}?.,'";
60 
61  assert_escape(unchanged, unchanged, pcmk__xml_escape_text);
62  assert_escape(unchanged, unchanged, pcmk__xml_escape_attr);
63  assert_escape(unchanged, unchanged, pcmk__xml_escape_attr_pretty);
64 }
65 
66 // Ensure special characters get escaped at start, middle, and end
67 
68 static void
69 escape_left_angle(void **state)
70 {
71  const char *l_angle = "<abc<def<";
72  const char *l_angle_esc = PCMK__XML_ENTITY_LT "abc"
74 
75  assert_escape(l_angle, l_angle_esc, pcmk__xml_escape_text);
76  assert_escape(l_angle, l_angle_esc, pcmk__xml_escape_attr);
77  assert_escape(l_angle, l_angle, pcmk__xml_escape_attr_pretty);
78 }
79 
80 static void
81 escape_right_angle(void **state)
82 {
83  const char *r_angle = ">abc>def>";
84  const char *r_angle_esc = PCMK__XML_ENTITY_GT "abc"
86 
87  assert_escape(r_angle, r_angle_esc, pcmk__xml_escape_text);
88  assert_escape(r_angle, r_angle_esc, pcmk__xml_escape_attr);
89  assert_escape(r_angle, r_angle, pcmk__xml_escape_attr_pretty);
90 }
91 
92 static void
93 escape_ampersand(void **state)
94 {
95  const char *ampersand = "&abc&def&";
96  const char *ampersand_esc = PCMK__XML_ENTITY_AMP "abc"
98 
99  assert_escape(ampersand, ampersand_esc, pcmk__xml_escape_text);
100  assert_escape(ampersand, ampersand_esc, pcmk__xml_escape_attr);
101  assert_escape(ampersand, ampersand, pcmk__xml_escape_attr_pretty);
102 }
103 
104 static void
105 escape_double_quote(void **state)
106 {
107  const char *double_quote = "\"abc\"def\"";
108  const char *double_quote_esc_ref = PCMK__XML_ENTITY_QUOT "abc"
111  const char *double_quote_esc_backslash = "\\\"abc\\\"def\\\"";
112 
113  assert_escape(double_quote, double_quote, pcmk__xml_escape_text);
114  assert_escape(double_quote, double_quote_esc_ref, pcmk__xml_escape_attr);
115  assert_escape(double_quote, double_quote_esc_backslash,
117 }
118 
119 static void
120 escape_newline(void **state)
121 {
122  const char *newline = "\nabc\ndef\n";
123  const char *newline_esc_ref = "&#x0A;abc&#x0A;def&#x0A;";
124  const char *newline_esc_backslash = "\\nabc\\ndef\\n";
125 
126  assert_escape(newline, newline, pcmk__xml_escape_text);
127  assert_escape(newline, newline_esc_ref, pcmk__xml_escape_attr);
128  assert_escape(newline, newline_esc_backslash, pcmk__xml_escape_attr_pretty);
129 }
130 
131 static void
132 escape_tab(void **state)
133 {
134  const char *tab = "\tabc\tdef\t";
135  const char *tab_esc_ref = "&#x09;abc&#x09;def&#x09;";
136  const char *tab_esc_backslash = "\\tabc\\tdef\\t";
137 
138  assert_escape(tab, tab, pcmk__xml_escape_text);
139  assert_escape(tab, tab_esc_ref, pcmk__xml_escape_attr);
140  assert_escape(tab, tab_esc_backslash, pcmk__xml_escape_attr_pretty);
141 }
142 
143 static void
144 escape_carriage_return(void **state)
145 {
146  const char *cr = "\rabc\rdef\r";
147  const char *cr_esc_ref = "&#x0D;abc&#x0D;def&#x0D;";
148  const char *cr_esc_backslash = "\\rabc\\rdef\\r";
149 
150  assert_escape(cr, cr_esc_ref, pcmk__xml_escape_text);
151  assert_escape(cr, cr_esc_ref, pcmk__xml_escape_attr);
152  assert_escape(cr, cr_esc_backslash, pcmk__xml_escape_attr_pretty);
153 }
154 
155 static void
156 escape_nonprinting(void **state)
157 {
158  const char *nonprinting = "\a\x7F\x1B";
159  const char *nonprinting_esc = "&#x07;&#x7F;&#x1B;";
160 
161  assert_escape(nonprinting, nonprinting_esc, pcmk__xml_escape_text);
162  assert_escape(nonprinting, nonprinting_esc, pcmk__xml_escape_attr);
163  assert_escape(nonprinting, nonprinting, pcmk__xml_escape_attr_pretty);
164 }
165 
166 static void
167 escape_utf8(void **state)
168 {
169  /* Non-ASCII UTF-8 characters may be two, three, or four 8-bit bytes wide
170  * and should not be escaped.
171  */
172  const char *chinese = "仅高级使用";
173  const char *two_byte = "abc""\xCF\xA6""d<ef";
174  const char *two_byte_esc = "abc""\xCF\xA6""d" PCMK__XML_ENTITY_LT "ef";
175 
176  const char *three_byte = "abc""\xEF\x98\x98""d<ef";
177  const char *three_byte_esc = "abc""\xEF\x98\x98""d"
178  PCMK__XML_ENTITY_LT "ef";
179 
180  const char *four_byte = "abc""\xF0\x94\x81\x90""d<ef";
181  const char *four_byte_esc = "abc""\xF0\x94\x81\x90""d"
182  PCMK__XML_ENTITY_LT "ef";
183 
184  assert_escape(chinese, chinese, pcmk__xml_escape_text);
185  assert_escape(chinese, chinese, pcmk__xml_escape_attr);
186  assert_escape(chinese, chinese, pcmk__xml_escape_attr_pretty);
187 
188  assert_escape(two_byte, two_byte_esc, pcmk__xml_escape_text);
189  assert_escape(two_byte, two_byte_esc, pcmk__xml_escape_attr);
190  assert_escape(two_byte, two_byte, pcmk__xml_escape_attr_pretty);
191 
192  assert_escape(three_byte, three_byte_esc, pcmk__xml_escape_text);
193  assert_escape(three_byte, three_byte_esc, pcmk__xml_escape_attr);
194  assert_escape(three_byte, three_byte, pcmk__xml_escape_attr_pretty);
195 
196  assert_escape(four_byte, four_byte_esc, pcmk__xml_escape_text);
197  assert_escape(four_byte, four_byte_esc, pcmk__xml_escape_attr);
198  assert_escape(four_byte, four_byte, pcmk__xml_escape_attr_pretty);
199 }
200 
202  cmocka_unit_test(null_empty),
203  cmocka_unit_test(invalid_type),
204  cmocka_unit_test(escape_unchanged),
205  cmocka_unit_test(escape_left_angle),
206  cmocka_unit_test(escape_right_angle),
207  cmocka_unit_test(escape_ampersand),
208  cmocka_unit_test(escape_double_quote),
209  cmocka_unit_test(escape_newline),
210  cmocka_unit_test(escape_tab),
211  cmocka_unit_test(escape_carriage_return),
212  cmocka_unit_test(escape_nonprinting),
213  cmocka_unit_test(escape_utf8));
char * pcmk__xml_escape(const char *text, enum pcmk__xml_escape_type type)
Definition: xml.c:1110
#define PCMK__XML_ENTITY_LT
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))
enum crm_ais_msg_types type
Definition: cpg.c:51
pcmk__xml_escape_type
Definition: xml_internal.h:276
#define PCMK__XML_ENTITY_GT
int pcmk__xml_test_setup_group(void **state)
Definition: unittest.c:74
#define pcmk__assert_asserts(stmt)
#define PCMK__XML_ENTITY_QUOT
#define PCMK__XML_ENTITY_AMP