1 /* 2 * Helpers for formatting and printing strings 3 * 4 * Copyright 31 August 2008 James Bottomley 5 * Copyright (C) 2013, Intel Corporation 6 */ 7 #include <linux/bug.h> 8 #include <linux/kernel.h> 9 #include <linux/math64.h> 10 #include <linux/export.h> 11 #include <linux/ctype.h> 12 #include <linux/errno.h> 13 #include <linux/string.h> 14 #include <linux/string_helpers.h> 15 16 /** 17 * string_get_size - get the size in the specified units 18 * @size: The size to be converted in blocks 19 * @blk_size: Size of the block (use 1 for size in bytes) 20 * @units: units to use (powers of 1000 or 1024) 21 * @buf: buffer to format to 22 * @len: length of buffer 23 * 24 * This function returns a string formatted to 3 significant figures 25 * giving the size in the required units. @buf should have room for 26 * at least 9 bytes and will always be zero terminated. 27 * 28 */ 29 void string_get_size(u64 size, u64 blk_size, const enum string_size_units units, 30 char *buf, int len) 31 { 32 static const char *const units_10[] = { 33 "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" 34 }; 35 static const char *const units_2[] = { 36 "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" 37 }; 38 static const char *const *const units_str[] = { 39 [STRING_UNITS_10] = units_10, 40 [STRING_UNITS_2] = units_2, 41 }; 42 static const unsigned int divisor[] = { 43 [STRING_UNITS_10] = 1000, 44 [STRING_UNITS_2] = 1024, 45 }; 46 int i, j; 47 u32 remainder = 0, sf_cap, exp; 48 char tmp[8]; 49 const char *unit; 50 51 tmp[0] = '\0'; 52 i = 0; 53 if (!size) 54 goto out; 55 56 while (blk_size >= divisor[units]) { 57 remainder = do_div(blk_size, divisor[units]); 58 i++; 59 } 60 61 exp = divisor[units] / (u32)blk_size; 62 /* 63 * size must be strictly greater than exp here to ensure that remainder 64 * is greater than divisor[units] coming out of the if below. 65 */ 66 if (size > exp) { 67 remainder = do_div(size, divisor[units]); 68 remainder *= blk_size; 69 i++; 70 } else { 71 remainder *= size; 72 } 73 74 size *= blk_size; 75 size += remainder / divisor[units]; 76 remainder %= divisor[units]; 77 78 while (size >= divisor[units]) { 79 remainder = do_div(size, divisor[units]); 80 i++; 81 } 82 83 sf_cap = size; 84 for (j = 0; sf_cap*10 < 1000; j++) 85 sf_cap *= 10; 86 87 if (j) { 88 remainder *= 1000; 89 remainder /= divisor[units]; 90 snprintf(tmp, sizeof(tmp), ".%03u", remainder); 91 tmp[j+1] = '\0'; 92 } 93 94 out: 95 if (i >= ARRAY_SIZE(units_2)) 96 unit = "UNK"; 97 else 98 unit = units_str[units][i]; 99 100 snprintf(buf, len, "%u%s %s", (u32)size, 101 tmp, unit); 102 } 103 EXPORT_SYMBOL(string_get_size); 104 105 static bool unescape_space(char **src, char **dst) 106 { 107 char *p = *dst, *q = *src; 108 109 switch (*q) { 110 case 'n': 111 *p = '\n'; 112 break; 113 case 'r': 114 *p = '\r'; 115 break; 116 case 't': 117 *p = '\t'; 118 break; 119 case 'v': 120 *p = '\v'; 121 break; 122 case 'f': 123 *p = '\f'; 124 break; 125 default: 126 return false; 127 } 128 *dst += 1; 129 *src += 1; 130 return true; 131 } 132 133 static bool unescape_octal(char **src, char **dst) 134 { 135 char *p = *dst, *q = *src; 136 u8 num; 137 138 if (isodigit(*q) == 0) 139 return false; 140 141 num = (*q++) & 7; 142 while (num < 32 && isodigit(*q) && (q - *src < 3)) { 143 num <<= 3; 144 num += (*q++) & 7; 145 } 146 *p = num; 147 *dst += 1; 148 *src = q; 149 return true; 150 } 151 152 static bool unescape_hex(char **src, char **dst) 153 { 154 char *p = *dst, *q = *src; 155 int digit; 156 u8 num; 157 158 if (*q++ != 'x') 159 return false; 160 161 num = digit = hex_to_bin(*q++); 162 if (digit < 0) 163 return false; 164 165 digit = hex_to_bin(*q); 166 if (digit >= 0) { 167 q++; 168 num = (num << 4) | digit; 169 } 170 *p = num; 171 *dst += 1; 172 *src = q; 173 return true; 174 } 175 176 static bool unescape_special(char **src, char **dst) 177 { 178 char *p = *dst, *q = *src; 179 180 switch (*q) { 181 case '\"': 182 *p = '\"'; 183 break; 184 case '\\': 185 *p = '\\'; 186 break; 187 case 'a': 188 *p = '\a'; 189 break; 190 case 'e': 191 *p = '\e'; 192 break; 193 default: 194 return false; 195 } 196 *dst += 1; 197 *src += 1; 198 return true; 199 } 200 201 /** 202 * string_unescape - unquote characters in the given string 203 * @src: source buffer (escaped) 204 * @dst: destination buffer (unescaped) 205 * @size: size of the destination buffer (0 to unlimit) 206 * @flags: combination of the flags (bitwise OR): 207 * %UNESCAPE_SPACE: 208 * '\f' - form feed 209 * '\n' - new line 210 * '\r' - carriage return 211 * '\t' - horizontal tab 212 * '\v' - vertical tab 213 * %UNESCAPE_OCTAL: 214 * '\NNN' - byte with octal value NNN (1 to 3 digits) 215 * %UNESCAPE_HEX: 216 * '\xHH' - byte with hexadecimal value HH (1 to 2 digits) 217 * %UNESCAPE_SPECIAL: 218 * '\"' - double quote 219 * '\\' - backslash 220 * '\a' - alert (BEL) 221 * '\e' - escape 222 * %UNESCAPE_ANY: 223 * all previous together 224 * 225 * Description: 226 * The function unquotes characters in the given string. 227 * 228 * Because the size of the output will be the same as or less than the size of 229 * the input, the transformation may be performed in place. 230 * 231 * Caller must provide valid source and destination pointers. Be aware that 232 * destination buffer will always be NULL-terminated. Source string must be 233 * NULL-terminated as well. 234 * 235 * Return: 236 * The amount of the characters processed to the destination buffer excluding 237 * trailing '\0' is returned. 238 */ 239 int string_unescape(char *src, char *dst, size_t size, unsigned int flags) 240 { 241 char *out = dst; 242 243 while (*src && --size) { 244 if (src[0] == '\\' && src[1] != '\0' && size > 1) { 245 src++; 246 size--; 247 248 if (flags & UNESCAPE_SPACE && 249 unescape_space(&src, &out)) 250 continue; 251 252 if (flags & UNESCAPE_OCTAL && 253 unescape_octal(&src, &out)) 254 continue; 255 256 if (flags & UNESCAPE_HEX && 257 unescape_hex(&src, &out)) 258 continue; 259 260 if (flags & UNESCAPE_SPECIAL && 261 unescape_special(&src, &out)) 262 continue; 263 264 *out++ = '\\'; 265 } 266 *out++ = *src++; 267 } 268 *out = '\0'; 269 270 return out - dst; 271 } 272 EXPORT_SYMBOL(string_unescape); 273 274 static bool escape_passthrough(unsigned char c, char **dst, char *end) 275 { 276 char *out = *dst; 277 278 if (out < end) 279 *out = c; 280 *dst = out + 1; 281 return true; 282 } 283 284 static bool escape_space(unsigned char c, char **dst, char *end) 285 { 286 char *out = *dst; 287 unsigned char to; 288 289 switch (c) { 290 case '\n': 291 to = 'n'; 292 break; 293 case '\r': 294 to = 'r'; 295 break; 296 case '\t': 297 to = 't'; 298 break; 299 case '\v': 300 to = 'v'; 301 break; 302 case '\f': 303 to = 'f'; 304 break; 305 default: 306 return false; 307 } 308 309 if (out < end) 310 *out = '\\'; 311 ++out; 312 if (out < end) 313 *out = to; 314 ++out; 315 316 *dst = out; 317 return true; 318 } 319 320 static bool escape_special(unsigned char c, char **dst, char *end) 321 { 322 char *out = *dst; 323 unsigned char to; 324 325 switch (c) { 326 case '\\': 327 to = '\\'; 328 break; 329 case '\a': 330 to = 'a'; 331 break; 332 case '\e': 333 to = 'e'; 334 break; 335 default: 336 return false; 337 } 338 339 if (out < end) 340 *out = '\\'; 341 ++out; 342 if (out < end) 343 *out = to; 344 ++out; 345 346 *dst = out; 347 return true; 348 } 349 350 static bool escape_null(unsigned char c, char **dst, char *end) 351 { 352 char *out = *dst; 353 354 if (c) 355 return false; 356 357 if (out < end) 358 *out = '\\'; 359 ++out; 360 if (out < end) 361 *out = '0'; 362 ++out; 363 364 *dst = out; 365 return true; 366 } 367 368 static bool escape_octal(unsigned char c, char **dst, char *end) 369 { 370 char *out = *dst; 371 372 if (out < end) 373 *out = '\\'; 374 ++out; 375 if (out < end) 376 *out = ((c >> 6) & 0x07) + '0'; 377 ++out; 378 if (out < end) 379 *out = ((c >> 3) & 0x07) + '0'; 380 ++out; 381 if (out < end) 382 *out = ((c >> 0) & 0x07) + '0'; 383 ++out; 384 385 *dst = out; 386 return true; 387 } 388 389 static bool escape_hex(unsigned char c, char **dst, char *end) 390 { 391 char *out = *dst; 392 393 if (out < end) 394 *out = '\\'; 395 ++out; 396 if (out < end) 397 *out = 'x'; 398 ++out; 399 if (out < end) 400 *out = hex_asc_hi(c); 401 ++out; 402 if (out < end) 403 *out = hex_asc_lo(c); 404 ++out; 405 406 *dst = out; 407 return true; 408 } 409 410 /** 411 * string_escape_mem - quote characters in the given memory buffer 412 * @src: source buffer (unescaped) 413 * @isz: source buffer size 414 * @dst: destination buffer (escaped) 415 * @osz: destination buffer size 416 * @flags: combination of the flags (bitwise OR): 417 * %ESCAPE_SPACE: (special white space, not space itself) 418 * '\f' - form feed 419 * '\n' - new line 420 * '\r' - carriage return 421 * '\t' - horizontal tab 422 * '\v' - vertical tab 423 * %ESCAPE_SPECIAL: 424 * '\\' - backslash 425 * '\a' - alert (BEL) 426 * '\e' - escape 427 * %ESCAPE_NULL: 428 * '\0' - null 429 * %ESCAPE_OCTAL: 430 * '\NNN' - byte with octal value NNN (3 digits) 431 * %ESCAPE_ANY: 432 * all previous together 433 * %ESCAPE_NP: 434 * escape only non-printable characters (checked by isprint) 435 * %ESCAPE_ANY_NP: 436 * all previous together 437 * %ESCAPE_HEX: 438 * '\xHH' - byte with hexadecimal value HH (2 digits) 439 * @only: NULL-terminated string containing characters used to limit 440 * the selected escape class. If characters are included in @only 441 * that would not normally be escaped by the classes selected 442 * in @flags, they will be copied to @dst unescaped. 443 * 444 * Description: 445 * The process of escaping byte buffer includes several parts. They are applied 446 * in the following sequence. 447 * 1. The character is matched to the printable class, if asked, and in 448 * case of match it passes through to the output. 449 * 2. The character is not matched to the one from @only string and thus 450 * must go as-is to the output. 451 * 3. The character is checked if it falls into the class given by @flags. 452 * %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any 453 * character. Note that they actually can't go together, otherwise 454 * %ESCAPE_HEX will be ignored. 455 * 456 * Caller must provide valid source and destination pointers. Be aware that 457 * destination buffer will not be NULL-terminated, thus caller have to append 458 * it if needs. 459 * 460 * Return: 461 * The total size of the escaped output that would be generated for 462 * the given input and flags. To check whether the output was 463 * truncated, compare the return value to osz. There is room left in 464 * dst for a '\0' terminator if and only if ret < osz. 465 */ 466 int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz, 467 unsigned int flags, const char *only) 468 { 469 char *p = dst; 470 char *end = p + osz; 471 bool is_dict = only && *only; 472 473 while (isz--) { 474 unsigned char c = *src++; 475 476 /* 477 * Apply rules in the following sequence: 478 * - the character is printable, when @flags has 479 * %ESCAPE_NP bit set 480 * - the @only string is supplied and does not contain a 481 * character under question 482 * - the character doesn't fall into a class of symbols 483 * defined by given @flags 484 * In these cases we just pass through a character to the 485 * output buffer. 486 */ 487 if ((flags & ESCAPE_NP && isprint(c)) || 488 (is_dict && !strchr(only, c))) { 489 /* do nothing */ 490 } else { 491 if (flags & ESCAPE_SPACE && escape_space(c, &p, end)) 492 continue; 493 494 if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end)) 495 continue; 496 497 if (flags & ESCAPE_NULL && escape_null(c, &p, end)) 498 continue; 499 500 /* ESCAPE_OCTAL and ESCAPE_HEX always go last */ 501 if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end)) 502 continue; 503 504 if (flags & ESCAPE_HEX && escape_hex(c, &p, end)) 505 continue; 506 } 507 508 escape_passthrough(c, &p, end); 509 } 510 511 return p - dst; 512 } 513 EXPORT_SYMBOL(string_escape_mem); 514