Skip site navigation (1)Skip section navigation (2)
Date:      25 May 2002 15:29:11 +0200
From:      Dag-Erling Smorgrav <des@ofug.org>
To:        Dima Dorfman <dima@trit.org>
Cc:        audit@freebsd.org
Subject:   Re: %j for printf(9)
Message-ID:  <xzpr8k08ifs.fsf@flood.ping.uio.no>
In-Reply-To: <20020523050017.E3A2A3E22@turbine.trit.org>
References:  <20020523050017.E3A2A3E22@turbine.trit.org>

next in thread | previous in thread | raw e-mail | index | archive | help
--=-=-=

Dima Dorfman <dima@trit.org> writes:
> Attached is a patch that implements the %j length modifier in
> printf(9).

Here's an alternative (IMHO less disruptive) patch, which also fixes
the default case.

DES
-- 
Dag-Erling Smorgrav - des@ofug.org


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=kvprintf.diff

Index: subr_prf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/subr_prf.c,v
retrieving revision 1.81
diff -u -r1.81 subr_prf.c
--- subr_prf.c	29 Apr 2002 09:15:38 -0000	1.81
+++ subr_prf.c	25 May 2002 13:25:11 -0000
@@ -48,6 +48,7 @@
 #include <sys/msgbuf.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
+#include <sys/stdint.h>
 #include <sys/sysctl.h>
 #include <sys/tty.h>
 #include <sys/syslog.h>
@@ -65,7 +66,7 @@
 #define TOLOG	0x04
 
 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
-#define MAXNBUF	(sizeof(quad_t) * NBBY + 1)
+#define MAXNBUF	(sizeof(intmax_t) * NBBY + 1)
 
 struct putchar_arg {
 	int	flags;
@@ -86,8 +87,7 @@
 static void  msglogchar(int c, int pri);
 static void  msgaddchar(int c, void *dummy);
 static void  putchar(int ch, void *arg);
-static char *ksprintn(char *nbuf, u_long num, int base, int *len);
-static char *ksprintqn(char *nbuf, u_quad_t num, int base, int *len);
+static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len);
 static void  snprintf_func(int ch, void *arg);
 
 static int consintr = 1;		/* Ok to handle console interrupts? */
@@ -426,9 +426,9 @@
  * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
  */
 static char *
-ksprintn(nbuf, ul, base, lenp)
+ksprintn(nbuf, num, base, lenp)
 	char *nbuf;
-	u_long ul;
+	uintmax_t num;
 	int base, *lenp;
 {
 	char *p;
@@ -436,26 +436,8 @@
 	p = nbuf;
 	*p = '\0';
 	do {
-		*++p = hex2ascii(ul % base);
-	} while (ul /= base);
-	if (lenp)
-		*lenp = p - nbuf;
-	return (p);
-}
-/* ksprintn, but for a quad_t. */
-static char *
-ksprintqn(nbuf, uq, base, lenp)
-	char *nbuf;
-	u_quad_t uq;
-	int base, *lenp;
-{
-	char *p;
-
-	p = nbuf;
-	*p = '\0';
-	do {
-		*++p = hex2ascii(uq % base);
-	} while (uq /= base);
+		*++p = hex2ascii(num % base);
+	} while (num /= base);
 	if (lenp)
 		*lenp = p - nbuf;
 	return (p);
@@ -491,19 +473,19 @@
 kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
 {
 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
+	const char *percent;
 	char nbuf[MAXNBUF];
 	char *p, *q, *d;
 	u_char *up;
 	int ch, n;
-	u_long ul;
-	u_quad_t uq;
-	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+	uintmax_t num;
+	int base, lflag, jflag, qflag, tmp, width;
+	int ladjust, sharpflag, neg, sign, dot;
 	int dwidth;
 	char padc;
 	int retval = 0;
 
-	ul = 0;
-	uq = 0;
+	num = 0;
 	if (!func)
 		d = (char *) arg;
 	else
@@ -523,9 +505,11 @@
 				return (retval);
 			PCHAR(ch);
 		}
-		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
-		sign = 0; dot = 0; dwidth = 0;
-reswitch:	switch (ch = (u_char)*fmt++) {
+		percent = fmt - 1;
+		qflag = jflag = lflag = ladjust = sharpflag =
+		    neg = sign = dot = dwidth = 0;
+reswitch:
+		switch (ch = (u_char)*fmt++) {
 		case '.':
 			dot = 1;
 			goto reswitch;
@@ -571,17 +555,17 @@
 				width = n;
 			goto reswitch;
 		case 'b':
-			ul = va_arg(ap, int);
+			num = va_arg(ap, int);
 			p = va_arg(ap, char *);
-			for (q = ksprintn(nbuf, ul, *p++, NULL); *q;)
+			for (q = ksprintn(nbuf, num, *p++, NULL); *q;)
 				PCHAR(*q--);
 
-			if (!ul)
+			if (num == 0)
 				break;
 
 			for (tmp = 0; *p;) {
 				n = *p++;
-				if (ul & (1 << (n - 1))) {
+				if (num & (1 << (n - 1))) {
 					PCHAR(tmp ? ',' : '<');
 					for (; (n = *p) > ' '; ++p)
 						PCHAR(n);
@@ -611,15 +595,12 @@
 			}
 			break;
 		case 'd':
-			if (qflag)
-				uq = va_arg(ap, quad_t);
-			else if (lflag)
-				ul = va_arg(ap, long);
-			else
-				ul = va_arg(ap, int);
 			sign = 1;
 			base = 10;
-			goto number;
+			goto fetch_number;
+                case 'j':
+			jflag = 1;
+			goto reswitch;
 		case 'l':
 			if (lflag) {
 				lflag = 0;
@@ -628,16 +609,10 @@
 				lflag = 1;
 			goto reswitch;
 		case 'o':
-			if (qflag)
-				uq = va_arg(ap, u_quad_t);
-			else if (lflag)
-				ul = va_arg(ap, u_long);
-			else
-				ul = va_arg(ap, u_int);
 			base = 8;
-			goto nosign;
+			goto fetch_nosign;
 		case 'p':
-			ul = (uintptr_t)va_arg(ap, void *);
+			num = (uintptr_t)va_arg(ap, void *);
 			base = 16;
 			sharpflag = (width == 0);
 			goto nosign;
@@ -646,15 +621,8 @@
 			goto reswitch;
 		case 'n':
 		case 'r':
-			if (qflag)
-				uq = va_arg(ap, u_quad_t);
-			else if (lflag)
-				ul = va_arg(ap, u_long);
-			else
-				ul = sign ?
-				    (u_long)va_arg(ap, int) : va_arg(ap, u_int);
 			base = radix;
-			goto number;
+			goto fetch_number;
 		case 's':
 			p = va_arg(ap, char *);
 			if (p == NULL)
@@ -677,50 +645,45 @@
 					PCHAR(padc);
 			break;
 		case 'u':
-			if (qflag)
-				uq = va_arg(ap, u_quad_t);
-			else if (lflag)
-				ul = va_arg(ap, u_long);
-			else
-				ul = va_arg(ap, u_int);
 			base = 10;
-			goto nosign;
+			goto fetch_nosign;
 		case 'x':
 		case 'X':
-			if (qflag)
-				uq = va_arg(ap, u_quad_t);
+			base = 16;
+			goto fetch_nosign;
+		case 'z':
+			base = 16;
+			goto fetch_number;
+fetch_nosign:
+			if (jflag)
+				num = va_arg(ap, uintmax_t);
+			else if (qflag)
+				num = va_arg(ap, u_quad_t);
 			else if (lflag)
-				ul = va_arg(ap, u_long);
+				num = va_arg(ap, u_long);
 			else
-				ul = va_arg(ap, u_int);
-			base = 16;
+				num = va_arg(ap, u_int);
 			goto nosign;
-		case 'z':
-			if (qflag)
-				uq = va_arg(ap, u_quad_t);
+fetch_number:
+			if (jflag)
+				num = va_arg(ap, uintmax_t);
+			else if (qflag)
+				num = va_arg(ap, u_quad_t);
 			else if (lflag)
-				ul = va_arg(ap, u_long);
+				num = va_arg(ap, u_long);
 			else
-				ul = sign ?
-				    (u_long)va_arg(ap, int) : va_arg(ap, u_int);
-			base = 16;
+				num = sign ? (uintmax_t)va_arg(ap, int) :
+				    va_arg(ap, u_int);
 			goto number;
-nosign:			sign = 0;
-number:			
-			if (qflag) {
-				if (sign && (quad_t)uq < 0) {
-					neg = 1;
-					uq = -(quad_t)uq;
-				}
-				p = ksprintqn(nbuf, uq, base, &tmp);
-			} else {
-				if (sign && (long)ul < 0) {
-					neg = 1;
-					ul = -(long)ul;
-				}
-				p = ksprintn(nbuf, ul, base, &tmp);
+nosign:
+			sign = 0;
+number:
+			if (sign && (intmax_t)num < 0) {
+				neg = 1;
+				num = -(intmax_t)num;
 			}
-			if (sharpflag && (qflag ? uq != 0 : ul != 0)) {
+			p = ksprintn(nbuf, num, base, &tmp);
+			if (sharpflag && num != 0) {
 				if (base == 8)
 					tmp++;
 				else if (base == 16)
@@ -734,7 +697,7 @@
 					PCHAR(padc);
 			if (neg)
 				PCHAR('-');
-			if (sharpflag && (qflag ? uq != 0 : ul != 0)) {
+			if (sharpflag && num != 0) {
 				if (base == 8) {
 					PCHAR('0');
 				} else if (base == 16) {
@@ -752,10 +715,8 @@
 
 			break;
 		default:
-			PCHAR('%');
-			if (lflag)
-				PCHAR('l');
-			PCHAR(ch);
+			while (percent < fmt)
+				PCHAR(*percent++);
 			break;
 		}
 	}
@@ -783,7 +744,7 @@
 			dangling = 0;
 		}
 		msgaddchar('<', NULL);
-		for (p = ksprintn(nbuf, (u_long)pri, 10, NULL); *p;)
+		for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL); *p;)
 			msgaddchar(*p--, NULL);
 		msgaddchar('>', NULL);
 		lastpri = pri;

--=-=-=--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzpr8k08ifs.fsf>