If we get an invalid conversion specifier, bail out instead of trying to
fix it up. The format string likely has a typo or assumed we support
something that we don't, in either case the remaining arguments won't
match up with the remaining format string.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200518190716.751506-16-nivedita@alum.mit.edu
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Consolidate the actual output of the formatted text into one place.
Fix a couple of edge cases:
1. If 0 is printed with a precision of 0, the printf specification says
that nothing should be output, with one exception (2b).
2. The specification for octal alternate format (%#o) adds the leading
zero not as a prefix as the 0x for hexadecimal is, but by increasing
the precision if necessary to add the zero. This means that
a. %#.2o turns 8 into "010", but 1 into "01" rather than "001".
b. %#.o prints 0 as "0" rather than "", unlike the situation for
decimal, hexadecimal and regular octal format, which all output an
empty string.
Reduce the space allocated for printing a number to the maximum actually
required (22 bytes for a 64-bit number in octal), instead of the 66
bytes previously allocated.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200518190716.751506-15-nivedita@alum.mit.edu
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
A negative precision should be ignored completely, and the presence of a
valid precision should turn off the 0 flag.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200518190716.751506-10-nivedita@alum.mit.edu
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Move flags parsing code out into a helper function.
The '%%' case can be handled up front: it is not allowed to have flags,
width etc.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200518190716.751506-9-nivedita@alum.mit.edu
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Support 'll' qualifier for long long by copying the decimal printing
code from lib/vsprintf.c. For simplicity, the 32-bit code is used on
64-bit architectures as well.
Support 'hh' qualifier for signed/unsigned char type integers.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200518190716.751506-8-nivedita@alum.mit.edu
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Copy vsprintf from arch/x86/boot/printf.c to get a simple printf
implementation.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200518190716.751506-5-nivedita@alum.mit.edu
[ardb: add some missing braces in if...else clauses]
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>