Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

printf(1) incorrect output

2 views
Skip to first unread message

fa...@cock.li

unread,
Jul 26, 2016, 9:05:24 PM7/26/16
to
I was getting odd behavior with printf(1) when using ' or "
with a value of 128 or more, but only on some systems.

On amd64 where CHAR_MAX 127
$ printf %x\\n "'$(printf \\200)"
ffffffffffffffb0
$ printf %o\\n "'$(printf \\200)"
1777777777777777777600
$ printf %u\\n "'$(printf \\200)"
18446744073709551488
$ printf %d\\n "'$(printf \\200)"
-128

On macppc where CHAR_MAX 255
$ printf %x\\n "'$(printf \\200)"
80
$ printf %o\\n "'$(printf \\200)"
200
$ printf %u\\n "'$(printf \\200)"
128
$ printf %d\\n "'$(printf \\200)"
128

This patch adds casts to unsigned char to avoid problems when char
is signed. With this patch applied the correct values of 80, 200, 128
and 128 are printed for the above examples.

Index: printf.c
===================================================================
RCS file: /cvs/src/usr.bin/printf/printf.c,v
retrieving revision 1.24
diff -u -p -r1.24 printf.c
--- printf.c 9 Oct 2015 01:37:08 -0000 1.24
+++ printf.c 22 Jun 2016 21:9:11 -0000
@@ -439,7 +439,7 @@ getlong(void)
return(0L);

if (**gargv == '\"' || **gargv == '\'')
- return (long) *((*gargv++)+1);
+ return (unsigned char)*((*gargv++)+1);

errno = 0;
val = strtol (*gargv, &ep, 0);
@@ -457,7 +457,7 @@ getulong(void)
return(0UL);

if (**gargv == '\"' || **gargv == '\'')
- return (unsigned long) *((*gargv++)+1);
+ return (unsigned char)*((*gargv++)+1);

errno = 0;
val = strtoul (*gargv, &ep, 0);
@@ -475,7 +475,7 @@ getdouble(void)
return(0.0);

if (**gargv == '\"' || **gargv == '\'')
- return (double) *((*gargv++)+1);
+ return (unsigned char)*((*gargv++)+1);

errno = 0;
val = strtod (*gargv, &ep);

Philip Guenther

unread,
Jul 26, 2016, 9:40:37 PM7/26/16
to
On Tue, 26 Jul 2016, fa...@cock.li wrote:
> I was getting odd behavior with printf(1) when using ' or " with a value
> of 128 or more, but only on some systems.
...
> This patch adds casts to unsigned char to avoid problems when char is
> signed. With this patch applied the correct values of 80, 200, 128 and
> 128 are printed for the above examples.

This is a step forward, but we should look at snagging the (misnamed, IMO)
asciicode() function from FreeBSD to correctly handle conversion of
multibyte characters.


Philip

0 new messages