Back to home page

LXR

 
 

    


0001 /*
0002  * Helpers for formatting and printing strings
0003  *
0004  * Copyright 31 August 2008 James Bottomley
0005  * Copyright (C) 2013, Intel Corporation
0006  */
0007 #include <linux/bug.h>
0008 #include <linux/kernel.h>
0009 #include <linux/math64.h>
0010 #include <linux/export.h>
0011 #include <linux/ctype.h>
0012 #include <linux/errno.h>
0013 #include <linux/fs.h>
0014 #include <linux/limits.h>
0015 #include <linux/mm.h>
0016 #include <linux/slab.h>
0017 #include <linux/string.h>
0018 #include <linux/string_helpers.h>
0019 
0020 /**
0021  * string_get_size - get the size in the specified units
0022  * @size:   The size to be converted in blocks
0023  * @blk_size:   Size of the block (use 1 for size in bytes)
0024  * @units:  units to use (powers of 1000 or 1024)
0025  * @buf:    buffer to format to
0026  * @len:    length of buffer
0027  *
0028  * This function returns a string formatted to 3 significant figures
0029  * giving the size in the required units.  @buf should have room for
0030  * at least 9 bytes and will always be zero terminated.
0031  *
0032  */
0033 void string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
0034              char *buf, int len)
0035 {
0036     static const char *const units_10[] = {
0037         "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
0038     };
0039     static const char *const units_2[] = {
0040         "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
0041     };
0042     static const char *const *const units_str[] = {
0043         [STRING_UNITS_10] = units_10,
0044         [STRING_UNITS_2] = units_2,
0045     };
0046     static const unsigned int divisor[] = {
0047         [STRING_UNITS_10] = 1000,
0048         [STRING_UNITS_2] = 1024,
0049     };
0050     static const unsigned int rounding[] = { 500, 50, 5 };
0051     int i = 0, j;
0052     u32 remainder = 0, sf_cap;
0053     char tmp[8];
0054     const char *unit;
0055 
0056     tmp[0] = '\0';
0057 
0058     if (blk_size == 0)
0059         size = 0;
0060     if (size == 0)
0061         goto out;
0062 
0063     /* This is Napier's algorithm.  Reduce the original block size to
0064      *
0065      * coefficient * divisor[units]^i
0066      *
0067      * we do the reduction so both coefficients are just under 32 bits so
0068      * that multiplying them together won't overflow 64 bits and we keep
0069      * as much precision as possible in the numbers.
0070      *
0071      * Note: it's safe to throw away the remainders here because all the
0072      * precision is in the coefficients.
0073      */
0074     while (blk_size >> 32) {
0075         do_div(blk_size, divisor[units]);
0076         i++;
0077     }
0078 
0079     while (size >> 32) {
0080         do_div(size, divisor[units]);
0081         i++;
0082     }
0083 
0084     /* now perform the actual multiplication keeping i as the sum of the
0085      * two logarithms */
0086     size *= blk_size;
0087 
0088     /* and logarithmically reduce it until it's just under the divisor */
0089     while (size >= divisor[units]) {
0090         remainder = do_div(size, divisor[units]);
0091         i++;
0092     }
0093 
0094     /* work out in j how many digits of precision we need from the
0095      * remainder */
0096     sf_cap = size;
0097     for (j = 0; sf_cap*10 < 1000; j++)
0098         sf_cap *= 10;
0099 
0100     if (units == STRING_UNITS_2) {
0101         /* express the remainder as a decimal.  It's currently the
0102          * numerator of a fraction whose denominator is
0103          * divisor[units], which is 1 << 10 for STRING_UNITS_2 */
0104         remainder *= 1000;
0105         remainder >>= 10;
0106     }
0107 
0108     /* add a 5 to the digit below what will be printed to ensure
0109      * an arithmetical round up and carry it through to size */
0110     remainder += rounding[j];
0111     if (remainder >= 1000) {
0112         remainder -= 1000;
0113         size += 1;
0114     }
0115 
0116     if (j) {
0117         snprintf(tmp, sizeof(tmp), ".%03u", remainder);
0118         tmp[j+1] = '\0';
0119     }
0120 
0121  out:
0122     if (i >= ARRAY_SIZE(units_2))
0123         unit = "UNK";
0124     else
0125         unit = units_str[units][i];
0126 
0127     snprintf(buf, len, "%u%s %s", (u32)size,
0128          tmp, unit);
0129 }
0130 EXPORT_SYMBOL(string_get_size);
0131 
0132 static bool unescape_space(char **src, char **dst)
0133 {
0134     char *p = *dst, *q = *src;
0135 
0136     switch (*q) {
0137     case 'n':
0138         *p = '\n';
0139         break;
0140     case 'r':
0141         *p = '\r';
0142         break;
0143     case 't':
0144         *p = '\t';
0145         break;
0146     case 'v':
0147         *p = '\v';
0148         break;
0149     case 'f':
0150         *p = '\f';
0151         break;
0152     default:
0153         return false;
0154     }
0155     *dst += 1;
0156     *src += 1;
0157     return true;
0158 }
0159 
0160 static bool unescape_octal(char **src, char **dst)
0161 {
0162     char *p = *dst, *q = *src;
0163     u8 num;
0164 
0165     if (isodigit(*q) == 0)
0166         return false;
0167 
0168     num = (*q++) & 7;
0169     while (num < 32 && isodigit(*q) && (q - *src < 3)) {
0170         num <<= 3;
0171         num += (*q++) & 7;
0172     }
0173     *p = num;
0174     *dst += 1;
0175     *src = q;
0176     return true;
0177 }
0178 
0179 static bool unescape_hex(char **src, char **dst)
0180 {
0181     char *p = *dst, *q = *src;
0182     int digit;
0183     u8 num;
0184 
0185     if (*q++ != 'x')
0186         return false;
0187 
0188     num = digit = hex_to_bin(*q++);
0189     if (digit < 0)
0190         return false;
0191 
0192     digit = hex_to_bin(*q);
0193     if (digit >= 0) {
0194         q++;
0195         num = (num << 4) | digit;
0196     }
0197     *p = num;
0198     *dst += 1;
0199     *src = q;
0200     return true;
0201 }
0202 
0203 static bool unescape_special(char **src, char **dst)
0204 {
0205     char *p = *dst, *q = *src;
0206 
0207     switch (*q) {
0208     case '\"':
0209         *p = '\"';
0210         break;
0211     case '\\':
0212         *p = '\\';
0213         break;
0214     case 'a':
0215         *p = '\a';
0216         break;
0217     case 'e':
0218         *p = '\e';
0219         break;
0220     default:
0221         return false;
0222     }
0223     *dst += 1;
0224     *src += 1;
0225     return true;
0226 }
0227 
0228 /**
0229  * string_unescape - unquote characters in the given string
0230  * @src:    source buffer (escaped)
0231  * @dst:    destination buffer (unescaped)
0232  * @size:   size of the destination buffer (0 to unlimit)
0233  * @flags:  combination of the flags (bitwise OR):
0234  *  %UNESCAPE_SPACE:
0235  *      '\f' - form feed
0236  *      '\n' - new line
0237  *      '\r' - carriage return
0238  *      '\t' - horizontal tab
0239  *      '\v' - vertical tab
0240  *  %UNESCAPE_OCTAL:
0241  *      '\NNN' - byte with octal value NNN (1 to 3 digits)
0242  *  %UNESCAPE_HEX:
0243  *      '\xHH' - byte with hexadecimal value HH (1 to 2 digits)
0244  *  %UNESCAPE_SPECIAL:
0245  *      '\"' - double quote
0246  *      '\\' - backslash
0247  *      '\a' - alert (BEL)
0248  *      '\e' - escape
0249  *  %UNESCAPE_ANY:
0250  *      all previous together
0251  *
0252  * Description:
0253  * The function unquotes characters in the given string.
0254  *
0255  * Because the size of the output will be the same as or less than the size of
0256  * the input, the transformation may be performed in place.
0257  *
0258  * Caller must provide valid source and destination pointers. Be aware that
0259  * destination buffer will always be NULL-terminated. Source string must be
0260  * NULL-terminated as well.
0261  *
0262  * Return:
0263  * The amount of the characters processed to the destination buffer excluding
0264  * trailing '\0' is returned.
0265  */
0266 int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
0267 {
0268     char *out = dst;
0269 
0270     while (*src && --size) {
0271         if (src[0] == '\\' && src[1] != '\0' && size > 1) {
0272             src++;
0273             size--;
0274 
0275             if (flags & UNESCAPE_SPACE &&
0276                     unescape_space(&src, &out))
0277                 continue;
0278 
0279             if (flags & UNESCAPE_OCTAL &&
0280                     unescape_octal(&src, &out))
0281                 continue;
0282 
0283             if (flags & UNESCAPE_HEX &&
0284                     unescape_hex(&src, &out))
0285                 continue;
0286 
0287             if (flags & UNESCAPE_SPECIAL &&
0288                     unescape_special(&src, &out))
0289                 continue;
0290 
0291             *out++ = '\\';
0292         }
0293         *out++ = *src++;
0294     }
0295     *out = '\0';
0296 
0297     return out - dst;
0298 }
0299 EXPORT_SYMBOL(string_unescape);
0300 
0301 static bool escape_passthrough(unsigned char c, char **dst, char *end)
0302 {
0303     char *out = *dst;
0304 
0305     if (out < end)
0306         *out = c;
0307     *dst = out + 1;
0308     return true;
0309 }
0310 
0311 static bool escape_space(unsigned char c, char **dst, char *end)
0312 {
0313     char *out = *dst;
0314     unsigned char to;
0315 
0316     switch (c) {
0317     case '\n':
0318         to = 'n';
0319         break;
0320     case '\r':
0321         to = 'r';
0322         break;
0323     case '\t':
0324         to = 't';
0325         break;
0326     case '\v':
0327         to = 'v';
0328         break;
0329     case '\f':
0330         to = 'f';
0331         break;
0332     default:
0333         return false;
0334     }
0335 
0336     if (out < end)
0337         *out = '\\';
0338     ++out;
0339     if (out < end)
0340         *out = to;
0341     ++out;
0342 
0343     *dst = out;
0344     return true;
0345 }
0346 
0347 static bool escape_special(unsigned char c, char **dst, char *end)
0348 {
0349     char *out = *dst;
0350     unsigned char to;
0351 
0352     switch (c) {
0353     case '\\':
0354         to = '\\';
0355         break;
0356     case '\a':
0357         to = 'a';
0358         break;
0359     case '\e':
0360         to = 'e';
0361         break;
0362     default:
0363         return false;
0364     }
0365 
0366     if (out < end)
0367         *out = '\\';
0368     ++out;
0369     if (out < end)
0370         *out = to;
0371     ++out;
0372 
0373     *dst = out;
0374     return true;
0375 }
0376 
0377 static bool escape_null(unsigned char c, char **dst, char *end)
0378 {
0379     char *out = *dst;
0380 
0381     if (c)
0382         return false;
0383 
0384     if (out < end)
0385         *out = '\\';
0386     ++out;
0387     if (out < end)
0388         *out = '0';
0389     ++out;
0390 
0391     *dst = out;
0392     return true;
0393 }
0394 
0395 static bool escape_octal(unsigned char c, char **dst, char *end)
0396 {
0397     char *out = *dst;
0398 
0399     if (out < end)
0400         *out = '\\';
0401     ++out;
0402     if (out < end)
0403         *out = ((c >> 6) & 0x07) + '0';
0404     ++out;
0405     if (out < end)
0406         *out = ((c >> 3) & 0x07) + '0';
0407     ++out;
0408     if (out < end)
0409         *out = ((c >> 0) & 0x07) + '0';
0410     ++out;
0411 
0412     *dst = out;
0413     return true;
0414 }
0415 
0416 static bool escape_hex(unsigned char c, char **dst, char *end)
0417 {
0418     char *out = *dst;
0419 
0420     if (out < end)
0421         *out = '\\';
0422     ++out;
0423     if (out < end)
0424         *out = 'x';
0425     ++out;
0426     if (out < end)
0427         *out = hex_asc_hi(c);
0428     ++out;
0429     if (out < end)
0430         *out = hex_asc_lo(c);
0431     ++out;
0432 
0433     *dst = out;
0434     return true;
0435 }
0436 
0437 /**
0438  * string_escape_mem - quote characters in the given memory buffer
0439  * @src:    source buffer (unescaped)
0440  * @isz:    source buffer size
0441  * @dst:    destination buffer (escaped)
0442  * @osz:    destination buffer size
0443  * @flags:  combination of the flags (bitwise OR):
0444  *  %ESCAPE_SPACE: (special white space, not space itself)
0445  *      '\f' - form feed
0446  *      '\n' - new line
0447  *      '\r' - carriage return
0448  *      '\t' - horizontal tab
0449  *      '\v' - vertical tab
0450  *  %ESCAPE_SPECIAL:
0451  *      '\\' - backslash
0452  *      '\a' - alert (BEL)
0453  *      '\e' - escape
0454  *  %ESCAPE_NULL:
0455  *      '\0' - null
0456  *  %ESCAPE_OCTAL:
0457  *      '\NNN' - byte with octal value NNN (3 digits)
0458  *  %ESCAPE_ANY:
0459  *      all previous together
0460  *  %ESCAPE_NP:
0461  *      escape only non-printable characters (checked by isprint)
0462  *  %ESCAPE_ANY_NP:
0463  *      all previous together
0464  *  %ESCAPE_HEX:
0465  *      '\xHH' - byte with hexadecimal value HH (2 digits)
0466  * @only:   NULL-terminated string containing characters used to limit
0467  *      the selected escape class. If characters are included in @only
0468  *      that would not normally be escaped by the classes selected
0469  *      in @flags, they will be copied to @dst unescaped.
0470  *
0471  * Description:
0472  * The process of escaping byte buffer includes several parts. They are applied
0473  * in the following sequence.
0474  *  1. The character is matched to the printable class, if asked, and in
0475  *     case of match it passes through to the output.
0476  *  2. The character is not matched to the one from @only string and thus
0477  *     must go as-is to the output.
0478  *  3. The character is checked if it falls into the class given by @flags.
0479  *     %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any
0480  *     character. Note that they actually can't go together, otherwise
0481  *     %ESCAPE_HEX will be ignored.
0482  *
0483  * Caller must provide valid source and destination pointers. Be aware that
0484  * destination buffer will not be NULL-terminated, thus caller have to append
0485  * it if needs.
0486  *
0487  * Return:
0488  * The total size of the escaped output that would be generated for
0489  * the given input and flags. To check whether the output was
0490  * truncated, compare the return value to osz. There is room left in
0491  * dst for a '\0' terminator if and only if ret < osz.
0492  */
0493 int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
0494               unsigned int flags, const char *only)
0495 {
0496     char *p = dst;
0497     char *end = p + osz;
0498     bool is_dict = only && *only;
0499 
0500     while (isz--) {
0501         unsigned char c = *src++;
0502 
0503         /*
0504          * Apply rules in the following sequence:
0505          *  - the character is printable, when @flags has
0506          *    %ESCAPE_NP bit set
0507          *  - the @only string is supplied and does not contain a
0508          *    character under question
0509          *  - the character doesn't fall into a class of symbols
0510          *    defined by given @flags
0511          * In these cases we just pass through a character to the
0512          * output buffer.
0513          */
0514         if ((flags & ESCAPE_NP && isprint(c)) ||
0515             (is_dict && !strchr(only, c))) {
0516             /* do nothing */
0517         } else {
0518             if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
0519                 continue;
0520 
0521             if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
0522                 continue;
0523 
0524             if (flags & ESCAPE_NULL && escape_null(c, &p, end))
0525                 continue;
0526 
0527             /* ESCAPE_OCTAL and ESCAPE_HEX always go last */
0528             if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
0529                 continue;
0530 
0531             if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
0532                 continue;
0533         }
0534 
0535         escape_passthrough(c, &p, end);
0536     }
0537 
0538     return p - dst;
0539 }
0540 EXPORT_SYMBOL(string_escape_mem);
0541 
0542 /*
0543  * Return an allocated string that has been escaped of special characters
0544  * and double quotes, making it safe to log in quotes.
0545  */
0546 char *kstrdup_quotable(const char *src, gfp_t gfp)
0547 {
0548     size_t slen, dlen;
0549     char *dst;
0550     const int flags = ESCAPE_HEX;
0551     const char esc[] = "\f\n\r\t\v\a\e\\\"";
0552 
0553     if (!src)
0554         return NULL;
0555     slen = strlen(src);
0556 
0557     dlen = string_escape_mem(src, slen, NULL, 0, flags, esc);
0558     dst = kmalloc(dlen + 1, gfp);
0559     if (!dst)
0560         return NULL;
0561 
0562     WARN_ON(string_escape_mem(src, slen, dst, dlen, flags, esc) != dlen);
0563     dst[dlen] = '\0';
0564 
0565     return dst;
0566 }
0567 EXPORT_SYMBOL_GPL(kstrdup_quotable);
0568 
0569 /*
0570  * Returns allocated NULL-terminated string containing process
0571  * command line, with inter-argument NULLs replaced with spaces,
0572  * and other special characters escaped.
0573  */
0574 char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp)
0575 {
0576     char *buffer, *quoted;
0577     int i, res;
0578 
0579     buffer = kmalloc(PAGE_SIZE, GFP_TEMPORARY);
0580     if (!buffer)
0581         return NULL;
0582 
0583     res = get_cmdline(task, buffer, PAGE_SIZE - 1);
0584     buffer[res] = '\0';
0585 
0586     /* Collapse trailing NULLs, leave res pointing to last non-NULL. */
0587     while (--res >= 0 && buffer[res] == '\0')
0588         ;
0589 
0590     /* Replace inter-argument NULLs. */
0591     for (i = 0; i <= res; i++)
0592         if (buffer[i] == '\0')
0593             buffer[i] = ' ';
0594 
0595     /* Make sure result is printable. */
0596     quoted = kstrdup_quotable(buffer, gfp);
0597     kfree(buffer);
0598     return quoted;
0599 }
0600 EXPORT_SYMBOL_GPL(kstrdup_quotable_cmdline);
0601 
0602 /*
0603  * Returns allocated NULL-terminated string containing pathname,
0604  * with special characters escaped, able to be safely logged. If
0605  * there is an error, the leading character will be "<".
0606  */
0607 char *kstrdup_quotable_file(struct file *file, gfp_t gfp)
0608 {
0609     char *temp, *pathname;
0610 
0611     if (!file)
0612         return kstrdup("<unknown>", gfp);
0613 
0614     /* We add 11 spaces for ' (deleted)' to be appended */
0615     temp = kmalloc(PATH_MAX + 11, GFP_TEMPORARY);
0616     if (!temp)
0617         return kstrdup("<no_memory>", gfp);
0618 
0619     pathname = file_path(file, temp, PATH_MAX + 11);
0620     if (IS_ERR(pathname))
0621         pathname = kstrdup("<too_long>", gfp);
0622     else
0623         pathname = kstrdup_quotable(pathname, gfp);
0624 
0625     kfree(temp);
0626     return pathname;
0627 }
0628 EXPORT_SYMBOL_GPL(kstrdup_quotable_file);