aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-18 18:41:55 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-18 18:41:55 +0000
commit5f116629d80b66bd09d8dc2b849befb1e27cd21a (patch)
treeedaa027f78c58d62edd1c75967bf86364dc581da /coreutils
parentf19817ddc2f2162803b19448ea2b23b1209911dd (diff)
downloadbusybox-w32-5f116629d80b66bd09d8dc2b849befb1e27cd21a.tar.gz
busybox-w32-5f116629d80b66bd09d8dc2b849befb1e27cd21a.tar.bz2
busybox-w32-5f116629d80b66bd09d8dc2b849befb1e27cd21a.zip
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
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/printf.c21
1 files changed, 15 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);
63 63
64static int multiconvert(const char *arg, void *result, converter convert) 64static int multiconvert(const char *arg, void *result, converter convert)
65{ 65{
66 char s[sizeof(int)*3 + 2];
67
68 if (*arg == '"' || *arg == '\'') { 66 if (*arg == '"' || *arg == '\'') {
69 sprintf(s, "%d", (unsigned char)arg[1]); 67 arg = utoa((unsigned char)arg[1]);
70 arg = s;
71 } 68 }
72 errno = 0; 69 errno = 0;
73 convert(arg, result); 70 convert(arg, result);
@@ -289,10 +286,22 @@ static char **print_formatted(char *f, char **argv)
289 } 286 }
290 } 287 }
291 } 288 }
289 /* Remove size modifiers - "%Ld" would try to printf
290 * long long, we pass long, and it spews garbage */
292 if ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') { 291 if ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') {
293 ++f; 292 strcpy(f, f + 1);
294 ++direc_length;
295 } 293 }
294//FIXME: actually, the same happens with bare "%d":
295//it printfs an int, but we pass long!
296//What saves us is that on most arches stack slot
297//is pointer-sized -> long-sized -> ints are promoted to longs
298// for variadic functions -> printf("%d", int_v) is in reality
299// indistinqushable from printf("%d", long_v) ->
300// since printf("%d", int_v) works, printf("%d", long_v) has to work.
301//But "clean" solution would be to add "l" to d,i,o,x,X.
302//Probably makes sense to go all the way to "ll" then.
303//Coreutils support long long-sized arguments.
304
296 /* needed - try "printf %" without it */ 305 /* needed - try "printf %" without it */
297 if (!strchr("diouxXfeEgGcs", *f)) { 306 if (!strchr("diouxXfeEgGcs", *f)) {
298 bb_error_msg("%s: invalid format", direc_start); 307 bb_error_msg("%s: invalid format", direc_start);