diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-02-10 14:35:36 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-02-10 14:35:36 -0500 |
| commit | 4ba24fef3eb3b142197135223b90ced2f319cd53 (patch) | |
| tree | a20c125b27740ec7b4c761b11d801108e1b316b2 /lib/vsprintf.c | |
| parent | 47c1ffb2b6b630894e9a16442611c056ab21c057 (diff) | |
| parent | 98a4a59ee31a12105a2b84f5b8b515ac2cb208ef (diff) | |
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.20.
Diffstat (limited to 'lib/vsprintf.c')
| -rw-r--r-- | lib/vsprintf.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6fe2c84eb055..ec337f64f52d 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <asm/page.h> /* for PAGE_SIZE */ | 33 | #include <asm/page.h> /* for PAGE_SIZE */ |
| 34 | #include <asm/sections.h> /* for dereference_function_descriptor() */ | 34 | #include <asm/sections.h> /* for dereference_function_descriptor() */ |
| 35 | 35 | ||
| 36 | #include <linux/string_helpers.h> | ||
| 36 | #include "kstrtox.h" | 37 | #include "kstrtox.h" |
| 37 | 38 | ||
| 38 | /** | 39 | /** |
| @@ -1101,6 +1102,62 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, | |||
| 1101 | } | 1102 | } |
| 1102 | 1103 | ||
| 1103 | static noinline_for_stack | 1104 | static noinline_for_stack |
| 1105 | char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | ||
| 1106 | const char *fmt) | ||
| 1107 | { | ||
| 1108 | bool found = true; | ||
| 1109 | int count = 1; | ||
| 1110 | unsigned int flags = 0; | ||
| 1111 | int len; | ||
| 1112 | |||
| 1113 | if (spec.field_width == 0) | ||
| 1114 | return buf; /* nothing to print */ | ||
| 1115 | |||
| 1116 | if (ZERO_OR_NULL_PTR(addr)) | ||
| 1117 | return string(buf, end, NULL, spec); /* NULL pointer */ | ||
| 1118 | |||
| 1119 | |||
| 1120 | do { | ||
| 1121 | switch (fmt[count++]) { | ||
| 1122 | case 'a': | ||
| 1123 | flags |= ESCAPE_ANY; | ||
| 1124 | break; | ||
| 1125 | case 'c': | ||
| 1126 | flags |= ESCAPE_SPECIAL; | ||
| 1127 | break; | ||
| 1128 | case 'h': | ||
| 1129 | flags |= ESCAPE_HEX; | ||
| 1130 | break; | ||
| 1131 | case 'n': | ||
| 1132 | flags |= ESCAPE_NULL; | ||
| 1133 | break; | ||
| 1134 | case 'o': | ||
| 1135 | flags |= ESCAPE_OCTAL; | ||
| 1136 | break; | ||
| 1137 | case 'p': | ||
| 1138 | flags |= ESCAPE_NP; | ||
| 1139 | break; | ||
| 1140 | case 's': | ||
| 1141 | flags |= ESCAPE_SPACE; | ||
| 1142 | break; | ||
| 1143 | default: | ||
| 1144 | found = false; | ||
| 1145 | break; | ||
| 1146 | } | ||
| 1147 | } while (found); | ||
| 1148 | |||
| 1149 | if (!flags) | ||
| 1150 | flags = ESCAPE_ANY_NP; | ||
| 1151 | |||
| 1152 | len = spec.field_width < 0 ? 1 : spec.field_width; | ||
| 1153 | |||
| 1154 | /* Ignore the error. We print as many characters as we can */ | ||
| 1155 | string_escape_mem(addr, len, &buf, end - buf, flags, NULL); | ||
| 1156 | |||
| 1157 | return buf; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | static noinline_for_stack | ||
| 1104 | char *uuid_string(char *buf, char *end, const u8 *addr, | 1161 | char *uuid_string(char *buf, char *end, const u8 *addr, |
| 1105 | struct printf_spec spec, const char *fmt) | 1162 | struct printf_spec spec, const char *fmt) |
| 1106 | { | 1163 | { |
| @@ -1221,6 +1278,17 @@ int kptr_restrict __read_mostly; | |||
| 1221 | * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order | 1278 | * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order |
| 1222 | * - 'I[6S]c' for IPv6 addresses printed as specified by | 1279 | * - 'I[6S]c' for IPv6 addresses printed as specified by |
| 1223 | * http://tools.ietf.org/html/rfc5952 | 1280 | * http://tools.ietf.org/html/rfc5952 |
| 1281 | * - 'E[achnops]' For an escaped buffer, where rules are defined by combination | ||
| 1282 | * of the following flags (see string_escape_mem() for the | ||
| 1283 | * details): | ||
| 1284 | * a - ESCAPE_ANY | ||
| 1285 | * c - ESCAPE_SPECIAL | ||
| 1286 | * h - ESCAPE_HEX | ||
| 1287 | * n - ESCAPE_NULL | ||
| 1288 | * o - ESCAPE_OCTAL | ||
| 1289 | * p - ESCAPE_NP | ||
| 1290 | * s - ESCAPE_SPACE | ||
| 1291 | * By default ESCAPE_ANY_NP is used. | ||
| 1224 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form | 1292 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form |
| 1225 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | 1293 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" |
| 1226 | * Options for %pU are: | 1294 | * Options for %pU are: |
| @@ -1321,6 +1389,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
| 1321 | }} | 1389 | }} |
| 1322 | } | 1390 | } |
| 1323 | break; | 1391 | break; |
| 1392 | case 'E': | ||
| 1393 | return escaped_string(buf, end, ptr, spec, fmt); | ||
| 1324 | case 'U': | 1394 | case 'U': |
| 1325 | return uuid_string(buf, end, ptr, spec, fmt); | 1395 | return uuid_string(buf, end, ptr, spec, fmt); |
| 1326 | case 'V': | 1396 | case 'V': |
| @@ -1633,6 +1703,7 @@ qualifier: | |||
| 1633 | * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address | 1703 | * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address |
| 1634 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper | 1704 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper |
| 1635 | * case. | 1705 | * case. |
| 1706 | * %*pE[achnops] print an escaped buffer | ||
| 1636 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 | 1707 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 |
| 1637 | * bytes of the input) | 1708 | * bytes of the input) |
| 1638 | * %n is ignored | 1709 | * %n is ignored |
| @@ -1937,7 +2008,7 @@ EXPORT_SYMBOL(sprintf); | |||
| 1937 | * @args: Arguments for the format string | 2008 | * @args: Arguments for the format string |
| 1938 | * | 2009 | * |
| 1939 | * The format follows C99 vsnprintf, except %n is ignored, and its argument | 2010 | * The format follows C99 vsnprintf, except %n is ignored, and its argument |
| 1940 | * is skiped. | 2011 | * is skipped. |
| 1941 | * | 2012 | * |
| 1942 | * The return value is the number of words(32bits) which would be generated for | 2013 | * The return value is the number of words(32bits) which would be generated for |
| 1943 | * the given input. | 2014 | * the given input. |
