Fixed (un)sign extension bugs in %+n format. -4 became

(long)(u_long)(u_int)-4 = 0x00000000fffffffc on machines with 32-bit
ints and 64-bit longs.

Restored %z format for printing signed hex.  %+x shouldn't have been
used since it is an error in userland.

Prepared to nuke %n format by cloning it to %r.  %n shouldn't have
been used because it means something completely different in
userland.  Now %+r is equivalent to ddb's original %r, and %r is
equivalent to ddb's original %n.

Ignore '+' flag in combination with unsigned formats %{o,p,u,x}.
This commit is contained in:
bde 1998-07-08 10:41:32 +00:00
parent eee2789d0f
commit b5d9d2e706

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
* $Id: subr_prf.c,v 1.45 1998/05/19 08:58:51 phk Exp $
* $Id: subr_prf.c,v 1.46 1998/05/28 09:30:20 phk Exp $
*/
#include <sys/param.h>
@ -490,18 +490,20 @@ reswitch: switch (ch = (u_char)*fmt++) {
case 'l':
lflag = 1;
goto reswitch;
case 'n':
ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
base = radix;
goto number;
case 'o':
ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
base = 8;
goto number;
goto nosign;
case 'p':
ul = (u_long)va_arg(ap, void *);
base = 16;
sharpflag = 1;
goto nosign;
case 'n':
case 'r':
ul = lflag ? va_arg(ap, u_long) :
sign ? (u_long)va_arg(ap, int) : va_arg(ap, u_int);
base = radix;
goto number;
case 's':
p = va_arg(ap, char *);
@ -527,10 +529,17 @@ reswitch: switch (ch = (u_char)*fmt++) {
case 'u':
ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
base = 10;
goto number;
goto nosign;
case 'x':
ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
base = 16;
goto nosign;
case 'z':
ul = lflag ? va_arg(ap, u_long) :
sign ? (u_long)va_arg(ap, int) : va_arg(ap, u_int);
base = 16;
goto number;
nosign: sign = 0;
number: if (sign && (long)ul < 0L) {
neg = 1;
ul = -(long)ul;