1 /******************************************************************************* 2 * 3 * Module Name: utstring - Common functions for strings and characters 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acnamesp.h" 47 48 #define _COMPONENT ACPI_UTILITIES 49 ACPI_MODULE_NAME("utstring") 50 51 /******************************************************************************* 52 * 53 * FUNCTION: acpi_ut_print_string 54 * 55 * PARAMETERS: string - Null terminated ASCII string 56 * max_length - Maximum output length. Used to constrain the 57 * length of strings during debug output only. 58 * 59 * RETURN: None 60 * 61 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 62 * sequences. 63 * 64 ******************************************************************************/ 65 void acpi_ut_print_string(char *string, u16 max_length) 66 { 67 u32 i; 68 69 if (!string) { 70 acpi_os_printf("<\"NULL STRING PTR\">"); 71 return; 72 } 73 74 acpi_os_printf("\""); 75 for (i = 0; (i < max_length) && string[i]; i++) { 76 77 /* Escape sequences */ 78 79 switch (string[i]) { 80 case 0x07: 81 82 acpi_os_printf("\\a"); /* BELL */ 83 break; 84 85 case 0x08: 86 87 acpi_os_printf("\\b"); /* BACKSPACE */ 88 break; 89 90 case 0x0C: 91 92 acpi_os_printf("\\f"); /* FORMFEED */ 93 break; 94 95 case 0x0A: 96 97 acpi_os_printf("\\n"); /* LINEFEED */ 98 break; 99 100 case 0x0D: 101 102 acpi_os_printf("\\r"); /* CARRIAGE RETURN */ 103 break; 104 105 case 0x09: 106 107 acpi_os_printf("\\t"); /* HORIZONTAL TAB */ 108 break; 109 110 case 0x0B: 111 112 acpi_os_printf("\\v"); /* VERTICAL TAB */ 113 break; 114 115 case '\'': /* Single Quote */ 116 case '\"': /* Double Quote */ 117 case '\\': /* Backslash */ 118 119 acpi_os_printf("\\%c", (int)string[i]); 120 break; 121 122 default: 123 124 /* Check for printable character or hex escape */ 125 126 if (isprint((int)string[i])) { 127 /* This is a normal character */ 128 129 acpi_os_printf("%c", (int)string[i]); 130 } else { 131 /* All others will be Hex escapes */ 132 133 acpi_os_printf("\\x%2.2X", (s32) string[i]); 134 } 135 break; 136 } 137 } 138 139 acpi_os_printf("\""); 140 141 if (i == max_length && string[i]) { 142 acpi_os_printf("..."); 143 } 144 } 145 146 /******************************************************************************* 147 * 148 * FUNCTION: acpi_ut_valid_acpi_char 149 * 150 * PARAMETERS: char - The character to be examined 151 * position - Byte position (0-3) 152 * 153 * RETURN: TRUE if the character is valid, FALSE otherwise 154 * 155 * DESCRIPTION: Check for a valid ACPI character. Must be one of: 156 * 1) Upper case alpha 157 * 2) numeric 158 * 3) underscore 159 * 160 * We allow a '!' as the last character because of the ASF! table 161 * 162 ******************************************************************************/ 163 164 u8 acpi_ut_valid_acpi_char(char character, u32 position) 165 { 166 167 if (!((character >= 'A' && character <= 'Z') || 168 (character >= '0' && character <= '9') || (character == '_'))) { 169 170 /* Allow a '!' in the last position */ 171 172 if (character == '!' && position == 3) { 173 return (TRUE); 174 } 175 176 return (FALSE); 177 } 178 179 return (TRUE); 180 } 181 182 /******************************************************************************* 183 * 184 * FUNCTION: acpi_ut_valid_acpi_name 185 * 186 * PARAMETERS: name - The name to be examined. Does not have to 187 * be NULL terminated string. 188 * 189 * RETURN: TRUE if the name is valid, FALSE otherwise 190 * 191 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 192 * 1) Upper case alpha 193 * 2) numeric 194 * 3) underscore 195 * 196 ******************************************************************************/ 197 198 u8 acpi_ut_valid_acpi_name(char *name) 199 { 200 u32 i; 201 202 ACPI_FUNCTION_ENTRY(); 203 204 for (i = 0; i < ACPI_NAME_SIZE; i++) { 205 if (!acpi_ut_valid_acpi_char(name[i], i)) { 206 return (FALSE); 207 } 208 } 209 210 return (TRUE); 211 } 212 213 /******************************************************************************* 214 * 215 * FUNCTION: acpi_ut_repair_name 216 * 217 * PARAMETERS: name - The ACPI name to be repaired 218 * 219 * RETURN: Repaired version of the name 220 * 221 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 222 * return the new name. NOTE: the Name parameter must reside in 223 * read/write memory, cannot be a const. 224 * 225 * An ACPI Name must consist of valid ACPI characters. We will repair the name 226 * if necessary because we don't want to abort because of this, but we want 227 * all namespace names to be printable. A warning message is appropriate. 228 * 229 * This issue came up because there are in fact machines that exhibit 230 * this problem, and we want to be able to enable ACPI support for them, 231 * even though there are a few bad names. 232 * 233 ******************************************************************************/ 234 235 void acpi_ut_repair_name(char *name) 236 { 237 u32 i; 238 u8 found_bad_char = FALSE; 239 u32 original_name; 240 241 ACPI_FUNCTION_NAME(ut_repair_name); 242 243 /* 244 * Special case for the root node. This can happen if we get an 245 * error during the execution of module-level code. 246 */ 247 if (ACPI_COMPARE_NAME(name, "\\___")) { 248 return; 249 } 250 251 ACPI_MOVE_NAME(&original_name, name); 252 253 /* Check each character in the name */ 254 255 for (i = 0; i < ACPI_NAME_SIZE; i++) { 256 if (acpi_ut_valid_acpi_char(name[i], i)) { 257 continue; 258 } 259 260 /* 261 * Replace a bad character with something printable, yet technically 262 * still invalid. This prevents any collisions with existing "good" 263 * names in the namespace. 264 */ 265 name[i] = '*'; 266 found_bad_char = TRUE; 267 } 268 269 if (found_bad_char) { 270 271 /* Report warning only if in strict mode or debug mode */ 272 273 if (!acpi_gbl_enable_interpreter_slack) { 274 ACPI_WARNING((AE_INFO, 275 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 276 original_name, name)); 277 } else { 278 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 279 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 280 original_name, name)); 281 } 282 } 283 } 284 285 #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP 286 /******************************************************************************* 287 * 288 * FUNCTION: ut_convert_backslashes 289 * 290 * PARAMETERS: pathname - File pathname string to be converted 291 * 292 * RETURN: Modifies the input Pathname 293 * 294 * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within 295 * the entire input file pathname string. 296 * 297 ******************************************************************************/ 298 299 void ut_convert_backslashes(char *pathname) 300 { 301 302 if (!pathname) { 303 return; 304 } 305 306 while (*pathname) { 307 if (*pathname == '\\') { 308 *pathname = '/'; 309 } 310 311 pathname++; 312 } 313 } 314 #endif 315