printk: don't print incorrect 64-bit integers
printk is supposed to be very lean, but should at least not print garbage values. Now when a 64-bit integral value is passed in to be printed, 'ERR' will be reported if it doesn't fit in 32-bits instead of truncating it. The printk documentation was slightly out of date, this has been updated. Fixes: #7179 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
12836d9280
commit
970758408b
|
@ -33,8 +33,11 @@ extern "C" {
|
|||
* - character: \%c
|
||||
* - percent: \%\%
|
||||
*
|
||||
* No other conversion specification capabilities are supported, such as flags,
|
||||
* field width, precision, or length attributes.
|
||||
* Field width (with or without leading zeroes) are supported.
|
||||
* Length attributes such as 'h' and 'l' are supported. However,
|
||||
* integral values with %lld and %lli are only printed if they fit in 32 bits,
|
||||
* otherwise 'ERR' is printed. Full 64-bit values may be printed with %llx.
|
||||
* Flags and precision attributes are not supported.
|
||||
*
|
||||
* @param fmt Format string.
|
||||
* @param ... Optional list of format arguments.
|
||||
|
|
|
@ -82,6 +82,13 @@ void *__printk_get_hook(void)
|
|||
return _char_out;
|
||||
}
|
||||
|
||||
static void print_err(out_func_t out, void *ctx)
|
||||
{
|
||||
out('E', ctx);
|
||||
out('R', ctx);
|
||||
out('R', ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Printk internals
|
||||
*
|
||||
|
@ -141,11 +148,25 @@ void _vprintk(out_func_t out, void *ctx, const char *fmt, va_list ap)
|
|||
goto still_might_format;
|
||||
case 'd':
|
||||
case 'i': {
|
||||
long d;
|
||||
if (long_ctr < 2) {
|
||||
d = va_arg(ap, long);
|
||||
s32_t d;
|
||||
|
||||
if (long_ctr == 0) {
|
||||
d = va_arg(ap, int);
|
||||
} else if (long_ctr == 1) {
|
||||
long ld = va_arg(ap, long);
|
||||
if (ld > INT32_MAX || ld < INT32_MIN) {
|
||||
print_err(out, ctx);
|
||||
break;
|
||||
}
|
||||
d = (s32_t)ld;
|
||||
} else {
|
||||
d = (long)va_arg(ap, long long);
|
||||
long long lld = va_arg(ap, long long);
|
||||
if (lld > INT32_MAX ||
|
||||
lld < INT32_MIN) {
|
||||
print_err(out, ctx);
|
||||
break;
|
||||
}
|
||||
d = (s32_t)lld;
|
||||
}
|
||||
|
||||
if (d < 0) {
|
||||
|
@ -158,14 +179,27 @@ void _vprintk(out_func_t out, void *ctx, const char *fmt, va_list ap)
|
|||
break;
|
||||
}
|
||||
case 'u': {
|
||||
unsigned long u;
|
||||
u32_t u;
|
||||
|
||||
if (long_ctr < 2) {
|
||||
u = va_arg(ap, unsigned long);
|
||||
if (long_ctr == 0) {
|
||||
u = va_arg(ap, unsigned int);
|
||||
} else if (long_ctr == 1) {
|
||||
long lu = va_arg(ap, unsigned long);
|
||||
if (lu > INT32_MAX) {
|
||||
print_err(out, ctx);
|
||||
break;
|
||||
}
|
||||
u = (u32_t)lu;
|
||||
} else {
|
||||
u = (unsigned long)va_arg(ap,
|
||||
unsigned long long);
|
||||
unsigned long long llu =
|
||||
va_arg(ap, unsigned long long);
|
||||
if (llu > INT32_MAX) {
|
||||
print_err(out, ctx);
|
||||
break;
|
||||
}
|
||||
u = (u32_t)llu;
|
||||
}
|
||||
|
||||
_printk_dec_ulong(out, ctx, u, padding,
|
||||
min_width);
|
||||
break;
|
||||
|
|
|
@ -25,7 +25,7 @@ char *expected = "22 113 10000 32768 40000 22\n"
|
|||
"42 42 42 42\n"
|
||||
"42 42 0042 00000042\n"
|
||||
"255 42 abcdef 0x0000002a 42\n"
|
||||
"-1 4294967295 ffffffffffffffff\n"
|
||||
"ERR -1 ERR ffffffffffffffff\n"
|
||||
;
|
||||
|
||||
|
||||
|
@ -86,7 +86,7 @@ void test_printk(void)
|
|||
printk("%u %2u %4u %8u\n", 42, 42, 42, 42);
|
||||
printk("%u %02u %04u %08u\n", 42, 42, 42, 42);
|
||||
printk("%-8u%-6d%-4x%-2p%8d\n", 0xFF, 42, 0xABCDEF, (char *)42, 42);
|
||||
printk("%lld %llu %llx\n", -1LL, -1ULL, -1ULL);
|
||||
printk("%lld %lld %llu %llx\n", 0xFFFFFFFFFULL, -1LL, -1ULL, -1ULL);
|
||||
|
||||
ram_console[pos] = '\0';
|
||||
zassert_true((strcmp(ram_console, expected) == 0), "printk failed");
|
||||
|
@ -117,8 +117,8 @@ void test_printk(void)
|
|||
"%-8u%-6d%-4x%-2p%8d\n",
|
||||
0xFF, 42, 0xABCDEF, (char *)42, 42);
|
||||
count += snprintk(ram_console + count, sizeof(ram_console) - count,
|
||||
"%lld %llu %llx\n",
|
||||
-1LL, -1ULL, -1ULL);
|
||||
"%lld %lld %llu %llx\n",
|
||||
0xFFFFFFFFFULL, -1LL, -1ULL, -1ULL);
|
||||
ram_console[count] = '\0';
|
||||
zassert_true((strcmp(ram_console, expected) == 0), "snprintk failed");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue