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

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

DEFINITIONS

This source file includes following definitions.
  1. assert_escape
  2. null_empty
  3. invalid_type
  4. escape_unchanged
  5. escape_left_angle
  6. escape_right_angle
  7. escape_ampersand
  8. escape_double_quote
  9. escape_newline
  10. escape_tab
  11. escape_carriage_return
  12. escape_nonprinting
  13. 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 assert_escape(const char *str, const char *reference,
     /* [previous][next][first][last][top][bottom][index][help] */
  19               enum pcmk__xml_escape_type type)
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  29 {
  30     assert_null(pcmk__xml_escape(NULL, pcmk__xml_escape_text));
  31     assert_null(pcmk__xml_escape(NULL, pcmk__xml_escape_attr));
  32     assert_null(pcmk__xml_escape(NULL, pcmk__xml_escape_attr_pretty));
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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
  49     pcmk__assert_asserts(pcmk__xml_escape("he<>llo", type));
  50 }
  51 
  52 static void
  53 escape_unchanged(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  70 {
  71     const char *l_angle = "<abc<def<";
  72     const char *l_angle_esc = PCMK__XML_ENTITY_LT "abc"
  73                               PCMK__XML_ENTITY_LT "def" PCMK__XML_ENTITY_LT;
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  82 {
  83     const char *r_angle = ">abc>def>";
  84     const char *r_angle_esc = PCMK__XML_ENTITY_GT "abc"
  85                               PCMK__XML_ENTITY_GT "def" PCMK__XML_ENTITY_GT;
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95     const char *ampersand = "&abc&def&";
  96     const char *ampersand_esc = PCMK__XML_ENTITY_AMP "abc"
  97                                 PCMK__XML_ENTITY_AMP "def" PCMK__XML_ENTITY_AMP;
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107     const char *double_quote = "\"abc\"def\"";
 108     const char *double_quote_esc_ref = PCMK__XML_ENTITY_QUOT "abc"
 109                                        PCMK__XML_ENTITY_QUOT "def"
 110                                        PCMK__XML_ENTITY_QUOT;
 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,
 116                   pcmk__xml_escape_attr_pretty);
 117 }
 118 
 119 static void
 120 escape_newline(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 201 PCMK__UNIT_TEST(pcmk__xml_test_setup_group, NULL,
 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));

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