diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/vsprintf.c | 52 |
1 files changed, 23 insertions, 29 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index cdfb9224e0ad..a3790c43a0ab 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -582,17 +582,18 @@ char *number(char *buf, char *end, unsigned long long num, return buf; } +#define special_hex_spec(size) \ +(struct printf_spec) { \ + .field_width = 2 + 2 * (size), /* 0x + hex */ \ + .flags = SPECIAL | SMALL | ZEROPAD, \ + .base = 16, \ + .precision = -1, \ +} + static noinline_for_stack char *special_hex_number(char *buf, char *end, unsigned long long num, int size) { - struct printf_spec spec; - - spec.field_width = 2 + 2 * size; /* 0x + hex */ - spec.flags = SPECIAL | SMALL | ZEROPAD; - spec.base = 16; - spec.precision = -1; - - return number(buf, end, num, spec); + return number(buf, end, num, special_hex_spec(size)); } static void move_right(char *buf, char *end, unsigned len, unsigned spaces) @@ -1164,18 +1165,11 @@ char *range_string(char *buf, char *end, const struct range *range, char sym[sizeof("[range 0x0123456789abcdef-0x0123456789abcdef]")]; char *p = sym, *pend = sym + sizeof(sym); - struct printf_spec range_spec = { - .field_width = 2 + 2 * sizeof(range->start), /* 0x + 2 * 8 */ - .flags = SPECIAL | SMALL | ZEROPAD, - .base = 16, - .precision = -1, - }; - if (check_pointer(&buf, end, range, spec)) return buf; p = string_nocheck(p, pend, "[range ", default_str_spec); - p = hex_range(p, pend, range->start, range->end, range_spec); + p = hex_range(p, pend, range->start, range->end, special_hex_spec(sizeof(range->start))); *p++ = ']'; *p = '\0'; @@ -1928,9 +1922,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, bool found = true; int count = 2; - if (check_pointer(&buf, end, tm, spec)) - return buf; - switch (fmt[count]) { case 'd': have_t = false; @@ -2018,6 +2009,9 @@ static noinline_for_stack char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, const char *fmt) { + if (check_pointer(&buf, end, ptr, spec)) + return buf; + switch (fmt[1]) { case 'R': return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); @@ -2909,10 +2903,11 @@ int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args) case FORMAT_STATE_NUM: { unsigned long long num; - if (fmt.size <= sizeof(int)) - num = convert_num_spec(va_arg(args, int), fmt.size, spec); - else + + if (fmt.size > sizeof(int)) num = va_arg(args, long long); + else + num = convert_num_spec(va_arg(args, int), fmt.size, spec); str = number(str, end, num, spec); continue; } @@ -3080,8 +3075,8 @@ EXPORT_SYMBOL(scnprintf); * @fmt: The format string to use * @args: Arguments for the format string * - * The function returns the number of characters written - * into @buf. Use vsnprintf() or vscnprintf() in order to avoid + * The return value is the number of characters written into @buf not including + * the trailing '\0'. Use vsnprintf() or vscnprintf() in order to avoid * buffer overflows. * * If you're not already dealing with a va_list consider using sprintf(). @@ -3100,8 +3095,8 @@ EXPORT_SYMBOL(vsprintf); * @fmt: The format string to use * @...: Arguments for the format string * - * The function returns the number of characters written - * into @buf. Use snprintf() or scnprintf() in order to avoid + * The return value is the number of characters written into @buf not including + * the trailing '\0'. Use snprintf() or scnprintf() in order to avoid * buffer overflows. * * See the vsnprintf() documentation for format string extensions over C99. @@ -3420,11 +3415,10 @@ int bstr_printf(char *buf, size_t size, const char *fmt_str, const u32 *bin_buf) goto out; case FORMAT_STATE_NUM: - if (fmt.size > sizeof(int)) { + if (fmt.size > sizeof(int)) num = get_arg(long long); - } else { + else num = convert_num_spec(get_arg(int), fmt.size, spec); - } str = number(str, end, num, spec); continue; } |
