string_helpers.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  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/slab.h>
  14. #include <linux/string.h>
  15. #include <linux/string_helpers.h>
  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. static const unsigned int rounding[] = { 500, 50, 5 };
  47. int i = 0, j;
  48. u32 remainder = 0, sf_cap;
  49. char tmp[8];
  50. const char *unit;
  51. tmp[0] = '\0';
  52. if (blk_size == 0)
  53. size = 0;
  54. if (size == 0)
  55. goto out;
  56. /* This is Napier's algorithm. Reduce the original block size to
  57. *
  58. * coefficient * divisor[units]^i
  59. *
  60. * we do the reduction so both coefficients are just under 32 bits so
  61. * that multiplying them together won't overflow 64 bits and we keep
  62. * as much precision as possible in the numbers.
  63. *
  64. * Note: it's safe to throw away the remainders here because all the
  65. * precision is in the coefficients.
  66. */
  67. while (blk_size >> 32) {
  68. do_div(blk_size, divisor[units]);
  69. i++;
  70. }
  71. while (size >> 32) {
  72. do_div(size, divisor[units]);
  73. i++;
  74. }
  75. /* now perform the actual multiplication keeping i as the sum of the
  76. * two logarithms */
  77. size *= blk_size;
  78. /* and logarithmically reduce it until it's just under the divisor */
  79. while (size >= divisor[units]) {
  80. remainder = do_div(size, divisor[units]);
  81. i++;
  82. }
  83. /* work out in j how many digits of precision we need from the
  84. * remainder */
  85. sf_cap = size;
  86. for (j = 0; sf_cap*10 < 1000; j++)
  87. sf_cap *= 10;
  88. if (units == STRING_UNITS_2) {
  89. /* express the remainder as a decimal. It's currently the
  90. * numerator of a fraction whose denominator is
  91. * divisor[units], which is 1 << 10 for STRING_UNITS_2 */
  92. remainder *= 1000;
  93. remainder >>= 10;
  94. }
  95. /* add a 5 to the digit below what will be printed to ensure
  96. * an arithmetical round up and carry it through to size */
  97. remainder += rounding[j];
  98. if (remainder >= 1000) {
  99. remainder -= 1000;
  100. size += 1;
  101. }
  102. if (j) {
  103. snprintf(tmp, sizeof(tmp), ".%03u", remainder);
  104. tmp[j+1] = '\0';
  105. }
  106. out:
  107. if (i >= ARRAY_SIZE(units_2))
  108. unit = "UNK";
  109. else
  110. unit = units_str[units][i];
  111. snprintf(buf, len, "%u%s %s", (u32)size,
  112. tmp, unit);
  113. }
  114. EXPORT_SYMBOL(string_get_size);
  115. static bool unescape_space(char **src, char **dst)
  116. {
  117. char *p = *dst, *q = *src;
  118. switch (*q) {
  119. case 'n':
  120. *p = '\n';
  121. break;
  122. case 'r':
  123. *p = '\r';
  124. break;
  125. case 't':
  126. *p = '\t';
  127. break;
  128. case 'v':
  129. *p = '\v';
  130. break;
  131. case 'f':
  132. *p = '\f';
  133. break;
  134. default:
  135. return false;
  136. }
  137. *dst += 1;
  138. *src += 1;
  139. return true;
  140. }
  141. static bool unescape_octal(char **src, char **dst)
  142. {
  143. char *p = *dst, *q = *src;
  144. u8 num;
  145. if (isodigit(*q) == 0)
  146. return false;
  147. num = (*q++) & 7;
  148. while (num < 32 && isodigit(*q) && (q - *src < 3)) {
  149. num <<= 3;
  150. num += (*q++) & 7;
  151. }
  152. *p = num;
  153. *dst += 1;
  154. *src = q;
  155. return true;
  156. }
  157. static bool unescape_hex(char **src, char **dst)
  158. {
  159. char *p = *dst, *q = *src;
  160. int digit;
  161. u8 num;
  162. if (*q++ != 'x')
  163. return false;
  164. num = digit = hex_to_bin(*q++);
  165. if (digit < 0)
  166. return false;
  167. digit = hex_to_bin(*q);
  168. if (digit >= 0) {
  169. q++;
  170. num = (num << 4) | digit;
  171. }
  172. *p = num;
  173. *dst += 1;
  174. *src = q;
  175. return true;
  176. }
  177. static bool unescape_special(char **src, char **dst)
  178. {
  179. char *p = *dst, *q = *src;
  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. * string_unescape - unquote characters in the given string
  202. * @src: source buffer (escaped)
  203. * @dst: destination buffer (unescaped)
  204. * @size: size of the destination buffer (0 to unlimit)
  205. * @flags: combination of the flags (bitwise OR):
  206. * %UNESCAPE_SPACE:
  207. * '\f' - form feed
  208. * '\n' - new line
  209. * '\r' - carriage return
  210. * '\t' - horizontal tab
  211. * '\v' - vertical tab
  212. * %UNESCAPE_OCTAL:
  213. * '\NNN' - byte with octal value NNN (1 to 3 digits)
  214. * %UNESCAPE_HEX:
  215. * '\xHH' - byte with hexadecimal value HH (1 to 2 digits)
  216. * %UNESCAPE_SPECIAL:
  217. * '\"' - double quote
  218. * '\\' - backslash
  219. * '\a' - alert (BEL)
  220. * '\e' - escape
  221. * %UNESCAPE_ANY:
  222. * all previous together
  223. *
  224. * Description:
  225. * The function unquotes characters in the given string.
  226. *
  227. * Because the size of the output will be the same as or less than the size of
  228. * the input, the transformation may be performed in place.
  229. *
  230. * Caller must provide valid source and destination pointers. Be aware that
  231. * destination buffer will always be NULL-terminated. Source string must be
  232. * NULL-terminated as well.
  233. *
  234. * Return:
  235. * The amount of the characters processed to the destination buffer excluding
  236. * trailing '\0' is returned.
  237. */
  238. int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
  239. {
  240. char *out = dst;
  241. while (*src && --size) {
  242. if (src[0] == '\\' && src[1] != '\0' && size > 1) {
  243. src++;
  244. size--;
  245. if (flags & UNESCAPE_SPACE &&
  246. unescape_space(&src, &out))
  247. continue;
  248. if (flags & UNESCAPE_OCTAL &&
  249. unescape_octal(&src, &out))
  250. continue;
  251. if (flags & UNESCAPE_HEX &&
  252. unescape_hex(&src, &out))
  253. continue;
  254. if (flags & UNESCAPE_SPECIAL &&
  255. unescape_special(&src, &out))
  256. continue;
  257. *out++ = '\\';
  258. }
  259. *out++ = *src++;
  260. }
  261. *out = '\0';
  262. return out - dst;
  263. }
  264. EXPORT_SYMBOL(string_unescape);
  265. static bool escape_passthrough(unsigned char c, char **dst, char *end)
  266. {
  267. char *out = *dst;
  268. if (out < end)
  269. *out = c;
  270. *dst = out + 1;
  271. return true;
  272. }
  273. static bool escape_space(unsigned char c, char **dst, char *end)
  274. {
  275. char *out = *dst;
  276. unsigned char to;
  277. switch (c) {
  278. case '\n':
  279. to = 'n';
  280. break;
  281. case '\r':
  282. to = 'r';
  283. break;
  284. case '\t':
  285. to = 't';
  286. break;
  287. case '\v':
  288. to = 'v';
  289. break;
  290. case '\f':
  291. to = 'f';
  292. break;
  293. default:
  294. return false;
  295. }
  296. if (out < end)
  297. *out = '\\';
  298. ++out;
  299. if (out < end)
  300. *out = to;
  301. ++out;
  302. *dst = out;
  303. return true;
  304. }
  305. static bool escape_special(unsigned char c, char **dst, char *end)
  306. {
  307. char *out = *dst;
  308. unsigned char to;
  309. switch (c) {
  310. case '\\':
  311. to = '\\';
  312. break;
  313. case '\a':
  314. to = 'a';
  315. break;
  316. case '\e':
  317. to = 'e';
  318. break;
  319. default:
  320. return false;
  321. }
  322. if (out < end)
  323. *out = '\\';
  324. ++out;
  325. if (out < end)
  326. *out = to;
  327. ++out;
  328. *dst = out;
  329. return true;
  330. }
  331. static bool escape_null(unsigned char c, char **dst, char *end)
  332. {
  333. char *out = *dst;
  334. if (c)
  335. return false;
  336. if (out < end)
  337. *out = '\\';
  338. ++out;
  339. if (out < end)
  340. *out = '0';
  341. ++out;
  342. *dst = out;
  343. return true;
  344. }
  345. static bool escape_octal(unsigned char c, char **dst, char *end)
  346. {
  347. char *out = *dst;
  348. if (out < end)
  349. *out = '\\';
  350. ++out;
  351. if (out < end)
  352. *out = ((c >> 6) & 0x07) + '0';
  353. ++out;
  354. if (out < end)
  355. *out = ((c >> 3) & 0x07) + '0';
  356. ++out;
  357. if (out < end)
  358. *out = ((c >> 0) & 0x07) + '0';
  359. ++out;
  360. *dst = out;
  361. return true;
  362. }
  363. static bool escape_hex(unsigned char c, char **dst, char *end)
  364. {
  365. char *out = *dst;
  366. if (out < end)
  367. *out = '\\';
  368. ++out;
  369. if (out < end)
  370. *out = 'x';
  371. ++out;
  372. if (out < end)
  373. *out = hex_asc_hi(c);
  374. ++out;
  375. if (out < end)
  376. *out = hex_asc_lo(c);
  377. ++out;
  378. *dst = out;
  379. return true;
  380. }
  381. /**
  382. * string_escape_mem - quote characters in the given memory buffer
  383. * @src: source buffer (unescaped)
  384. * @isz: source buffer size
  385. * @dst: destination buffer (escaped)
  386. * @osz: destination buffer size
  387. * @flags: combination of the flags (bitwise OR):
  388. * %ESCAPE_SPACE: (special white space, not space itself)
  389. * '\f' - form feed
  390. * '\n' - new line
  391. * '\r' - carriage return
  392. * '\t' - horizontal tab
  393. * '\v' - vertical tab
  394. * %ESCAPE_SPECIAL:
  395. * '\\' - backslash
  396. * '\a' - alert (BEL)
  397. * '\e' - escape
  398. * %ESCAPE_NULL:
  399. * '\0' - null
  400. * %ESCAPE_OCTAL:
  401. * '\NNN' - byte with octal value NNN (3 digits)
  402. * %ESCAPE_ANY:
  403. * all previous together
  404. * %ESCAPE_NP:
  405. * escape only non-printable characters (checked by isprint)
  406. * %ESCAPE_ANY_NP:
  407. * all previous together
  408. * %ESCAPE_HEX:
  409. * '\xHH' - byte with hexadecimal value HH (2 digits)
  410. * @only: NULL-terminated string containing characters used to limit
  411. * the selected escape class. If characters are included in @only
  412. * that would not normally be escaped by the classes selected
  413. * in @flags, they will be copied to @dst unescaped.
  414. *
  415. * Description:
  416. * The process of escaping byte buffer includes several parts. They are applied
  417. * in the following sequence.
  418. * 1. The character is matched to the printable class, if asked, and in
  419. * case of match it passes through to the output.
  420. * 2. The character is not matched to the one from @only string and thus
  421. * must go as-is to the output.
  422. * 3. The character is checked if it falls into the class given by @flags.
  423. * %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any
  424. * character. Note that they actually can't go together, otherwise
  425. * %ESCAPE_HEX will be ignored.
  426. *
  427. * Caller must provide valid source and destination pointers. Be aware that
  428. * destination buffer will not be NULL-terminated, thus caller have to append
  429. * it if needs.
  430. *
  431. * Return:
  432. * The total size of the escaped output that would be generated for
  433. * the given input and flags. To check whether the output was
  434. * truncated, compare the return value to osz. There is room left in
  435. * dst for a '\0' terminator if and only if ret < osz.
  436. */
  437. int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
  438. unsigned int flags, const char *only)
  439. {
  440. char *p = dst;
  441. char *end = p + osz;
  442. bool is_dict = only && *only;
  443. while (isz--) {
  444. unsigned char c = *src++;
  445. /*
  446. * Apply rules in the following sequence:
  447. * - the character is printable, when @flags has
  448. * %ESCAPE_NP bit set
  449. * - the @only string is supplied and does not contain a
  450. * character under question
  451. * - the character doesn't fall into a class of symbols
  452. * defined by given @flags
  453. * In these cases we just pass through a character to the
  454. * output buffer.
  455. */
  456. if ((flags & ESCAPE_NP && isprint(c)) ||
  457. (is_dict && !strchr(only, c))) {
  458. /* do nothing */
  459. } else {
  460. if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
  461. continue;
  462. if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
  463. continue;
  464. if (flags & ESCAPE_NULL && escape_null(c, &p, end))
  465. continue;
  466. /* ESCAPE_OCTAL and ESCAPE_HEX always go last */
  467. if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
  468. continue;
  469. if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
  470. continue;
  471. }
  472. escape_passthrough(c, &p, end);
  473. }
  474. return p - dst;
  475. }
  476. EXPORT_SYMBOL(string_escape_mem);
  477. /*
  478. * Return an allocated string that has been escaped of special characters
  479. * and double quotes, making it safe to log in quotes.
  480. */
  481. char *kstrdup_quotable(const char *src, gfp_t gfp)
  482. {
  483. size_t slen, dlen;
  484. char *dst;
  485. const int flags = ESCAPE_HEX;
  486. const char esc[] = "\f\n\r\t\v\a\e\\\"";
  487. if (!src)
  488. return NULL;
  489. slen = strlen(src);
  490. dlen = string_escape_mem(src, slen, NULL, 0, flags, esc);
  491. dst = kmalloc(dlen + 1, gfp);
  492. if (!dst)
  493. return NULL;
  494. WARN_ON(string_escape_mem(src, slen, dst, dlen, flags, esc) != dlen);
  495. dst[dlen] = '\0';
  496. return dst;
  497. }
  498. EXPORT_SYMBOL_GPL(kstrdup_quotable);