root/lib/common/tests/xml/pcmk__xml_needs_escape_test.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. null_empty
  2. invalid_type
  3. escape_unchanged
  4. escape_left_angle
  5. escape_right_angle
  6. escape_ampersand
  7. escape_double_quote
  8. escape_newline
  9. escape_tab
  10. escape_carriage_return
  11. escape_nonprinting
  12. escape_utf8

   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 
  12 #include <crm/common/unittest_internal.h>
  13 #include <crm/common/xml_internal.h>
  14 
  15 #include "crmcommon_private.h"
  16 
  17 static void
  18 null_empty(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
  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));
  22     assert_false(pcmk__xml_needs_escape(NULL, pcmk__xml_escape_attr_pretty));
  23 
  24     assert_false(pcmk__xml_needs_escape("", pcmk__xml_escape_text));
  25     assert_false(pcmk__xml_needs_escape("", pcmk__xml_escape_attr));
  26     assert_false(pcmk__xml_needs_escape("", pcmk__xml_escape_attr_pretty));
  27 }
  28 
  29 static void
  30 invalid_type(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
  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
  39     pcmk__assert_asserts(pcmk__xml_needs_escape("he<>llo", type));
  40 }
  41 
  42 static void
  43 escape_unchanged(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
  54                                         pcmk__xml_escape_attr_pretty));
  55 }
  56 
  57 // Ensure special characters get escaped at start, middle, and end
  58 
  59 static void
  60 escape_left_angle(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
  75                                         pcmk__xml_escape_attr_pretty));
  76     assert_false(pcmk__xml_needs_escape(l_angle_mid,
  77                                         pcmk__xml_escape_attr_pretty));
  78     assert_false(pcmk__xml_needs_escape(l_angle_right,
  79                                         pcmk__xml_escape_attr_pretty));
  80 }
  81 
  82 static void
  83 escape_right_angle(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
  98                                         pcmk__xml_escape_attr_pretty));
  99     assert_false(pcmk__xml_needs_escape(r_angle_mid,
 100                                         pcmk__xml_escape_attr_pretty));
 101     assert_false(pcmk__xml_needs_escape(r_angle_right,
 102                                         pcmk__xml_escape_attr_pretty));
 103 }
 104 
 105 static void
 106 escape_ampersand(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
 121                                         pcmk__xml_escape_attr_pretty));
 122     assert_false(pcmk__xml_needs_escape(ampersand_mid,
 123                                         pcmk__xml_escape_attr_pretty));
 124     assert_false(pcmk__xml_needs_escape(ampersand_right,
 125                                         pcmk__xml_escape_attr_pretty));
 126 }
 127 
 128 static void
 129 escape_double_quote(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
 136                                         pcmk__xml_escape_text));
 137     assert_false(pcmk__xml_needs_escape(double_quote_mid,
 138                                         pcmk__xml_escape_text));
 139     assert_false(pcmk__xml_needs_escape(double_quote_right,
 140                                         pcmk__xml_escape_text));
 141 
 142     assert_true(pcmk__xml_needs_escape(double_quote_left,
 143                                        pcmk__xml_escape_attr));
 144     assert_true(pcmk__xml_needs_escape(double_quote_mid,
 145                                        pcmk__xml_escape_attr));
 146     assert_true(pcmk__xml_needs_escape(double_quote_right,
 147                                        pcmk__xml_escape_attr));
 148 
 149     assert_true(pcmk__xml_needs_escape(double_quote_left,
 150                                        pcmk__xml_escape_attr_pretty));
 151     assert_true(pcmk__xml_needs_escape(double_quote_mid,
 152                                        pcmk__xml_escape_attr_pretty));
 153     assert_true(pcmk__xml_needs_escape(double_quote_right,
 154                                        pcmk__xml_escape_attr_pretty));
 155 }
 156 
 157 static void
 158 escape_newline(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
 173                                        pcmk__xml_escape_attr_pretty));
 174     assert_true(pcmk__xml_needs_escape(newline_mid,
 175                                        pcmk__xml_escape_attr_pretty));
 176     assert_true(pcmk__xml_needs_escape(newline_right,
 177                                        pcmk__xml_escape_attr_pretty));
 178 }
 179 
 180 static void
 181 escape_tab(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 195     assert_true(pcmk__xml_needs_escape(tab_left, pcmk__xml_escape_attr_pretty));
 196     assert_true(pcmk__xml_needs_escape(tab_mid, pcmk__xml_escape_attr_pretty));
 197     assert_true(pcmk__xml_needs_escape(tab_right,
 198                                        pcmk__xml_escape_attr_pretty));
 199 }
 200 
 201 static void
 202 escape_carriage_return(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 216     assert_true(pcmk__xml_needs_escape(cr_left, pcmk__xml_escape_attr_pretty));
 217     assert_true(pcmk__xml_needs_escape(cr_mid, pcmk__xml_escape_attr_pretty));
 218     assert_true(pcmk__xml_needs_escape(cr_right, pcmk__xml_escape_attr_pretty));
 219 }
 220 
 221 static void
 222 escape_nonprinting(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
 243                                         pcmk__xml_escape_attr_pretty));
 244     assert_false(pcmk__xml_needs_escape(alert_mid,
 245                                         pcmk__xml_escape_attr_pretty));
 246     assert_false(pcmk__xml_needs_escape(alert_right,
 247                                         pcmk__xml_escape_attr_pretty));
 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,
 258                                         pcmk__xml_escape_attr_pretty));
 259     assert_false(pcmk__xml_needs_escape(delete_mid,
 260                                         pcmk__xml_escape_attr_pretty));
 261     assert_false(pcmk__xml_needs_escape(delete_right,
 262                                         pcmk__xml_escape_attr_pretty));
 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,
 267                                         pcmk__xml_escape_attr_pretty));
 268 }
 269 
 270 static void
 271 escape_utf8(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 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));
 286     assert_false(pcmk__xml_needs_escape(chinese, pcmk__xml_escape_attr_pretty));
 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,
 291                                         pcmk__xml_escape_attr_pretty));
 292 
 293     assert_true(pcmk__xml_needs_escape(two_byte_special,
 294                                        pcmk__xml_escape_text));
 295     assert_true(pcmk__xml_needs_escape(two_byte_special,
 296                                        pcmk__xml_escape_attr));
 297     assert_false(pcmk__xml_needs_escape(two_byte_special,
 298                                         pcmk__xml_escape_attr_pretty));
 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,
 303                                         pcmk__xml_escape_attr_pretty));
 304 
 305     assert_true(pcmk__xml_needs_escape(three_byte_special,
 306                                        pcmk__xml_escape_text));
 307     assert_true(pcmk__xml_needs_escape(three_byte_special,
 308                                        pcmk__xml_escape_attr));
 309     assert_false(pcmk__xml_needs_escape(three_byte_special,
 310                                         pcmk__xml_escape_attr_pretty));
 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,
 315                                         pcmk__xml_escape_attr_pretty));
 316 
 317     assert_true(pcmk__xml_needs_escape(four_byte_special,
 318                                        pcmk__xml_escape_text));
 319     assert_true(pcmk__xml_needs_escape(four_byte_special,
 320                                        pcmk__xml_escape_attr));
 321     assert_false(pcmk__xml_needs_escape(four_byte_special,
 322                                         pcmk__xml_escape_attr_pretty));
 323 }
 324 
 325 PCMK__UNIT_TEST(pcmk__xml_test_setup_group, pcmk__xml_test_teardown_group,
 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));

/* [previous][next][first][last][top][bottom][index][help] */