diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-18 18:41:55 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-18 18:41:55 +0000 |
commit | 5f116629d80b66bd09d8dc2b849befb1e27cd21a (patch) | |
tree | edaa027f78c58d62edd1c75967bf86364dc581da | |
parent | f19817ddc2f2162803b19448ea2b23b1209911dd (diff) |
printf: do not print garbage on "%Ld". closes bug 4214.
function old new delta
printf_main 633 637 +4
multiconvert 99 79 -20
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 4/-20) Total: -16 bytes
-rw-r--r-- | coreutils/printf.c | 21 | ||||
-rwxr-xr-x | testsuite/printf.tests | 5 |
2 files changed, 20 insertions, 6 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c index ca035cc48..7f6235a87 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -63,11 +63,8 @@ typedef void FAST_FUNC (*converter)(const char *arg, void *result); static int multiconvert(const char *arg, void *result, converter convert) { - char s[sizeof(int)*3 + 2]; - if (*arg == '"' || *arg == '\'') { - sprintf(s, "%d", (unsigned char)arg[1]); - arg = s; + arg = utoa((unsigned char)arg[1]); } errno = 0; convert(arg, result); @@ -289,10 +286,22 @@ static char **print_formatted(char *f, char **argv) } } } + /* Remove size modifiers - "%Ld" would try to printf + * long long, we pass long, and it spews garbage */ if ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') { - ++f; - ++direc_length; + strcpy(f, f + 1); } +//FIXME: actually, the same happens with bare "%d": +//it printfs an int, but we pass long! +//What saves us is that on most arches stack slot +//is pointer-sized -> long-sized -> ints are promoted to longs +// for variadic functions -> printf("%d", int_v) is in reality +// indistinqushable from printf("%d", long_v) -> +// since printf("%d", int_v) works, printf("%d", long_v) has to work. +//But "clean" solution would be to add "l" to d,i,o,x,X. +//Probably makes sense to go all the way to "ll" then. +//Coreutils support long long-sized arguments. + /* needed - try "printf %" without it */ if (!strchr("diouxXfeEgGcs", *f)) { bb_error_msg("%s: invalid format", direc_start); diff --git a/testsuite/printf.tests b/testsuite/printf.tests index a5c71ec9d..f9d1decae 100755 --- a/testsuite/printf.tests +++ b/testsuite/printf.tests @@ -74,6 +74,11 @@ testing "printf understands %ld" \ "-5\n""0\n" \ "" "" +testing "printf understands %Ld" \ + "${bb}printf '%Ld\n' -5 2>&1; echo \$?" \ + "-5\n""0\n" \ + "" "" + # We are "more correct" here than bash/coreutils: they happily print -2 # as if it is a huge unsigned number testing "printf handles %u -N" \ |