Module Name:    src
Committed By:   rillig
Date:           Sun Apr  7 10:10:54 UTC 2024

Modified Files:
        src/common/lib/libutil: snprintb.c
        src/tests/lib/libutil: t_snprintb.c

Log Message:
snprintb: reject empty descriptions

In cases where the snprintb output is garbled, it is not trustworthy, so
make sure the mistakes in the bitfmt are fixed early.


To generate a diff of this commit:
cvs rdiff -u -r1.45 -r1.46 src/common/lib/libutil/snprintb.c
cvs rdiff -u -r1.32 -r1.33 src/tests/lib/libutil/t_snprintb.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/common/lib/libutil/snprintb.c
diff -u src/common/lib/libutil/snprintb.c:1.45 src/common/lib/libutil/snprintb.c:1.46
--- src/common/lib/libutil/snprintb.c:1.45	Mon Apr  1 08:53:42 2024
+++ src/common/lib/libutil/snprintb.c	Sun Apr  7 10:10:54 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: snprintb.c,v 1.45 2024/04/01 08:53:42 rillig Exp $	*/
+/*	$NetBSD: snprintb.c,v 1.46 2024/04/07 10:10:54 rillig Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2024 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #  include <sys/cdefs.h>
 #  if defined(LIBC_SCCS)
-__RCSID("$NetBSD: snprintb.c,v 1.45 2024/04/01 08:53:42 rillig Exp $");
+__RCSID("$NetBSD: snprintb.c,v 1.46 2024/04/07 10:10:54 rillig Exp $");
 #  endif
 
 #  include <sys/types.h>
@@ -46,7 +46,7 @@ __RCSID("$NetBSD: snprintb.c,v 1.45 2024
 #  include <errno.h>
 # else /* ! _KERNEL */
 #  include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.45 2024/04/01 08:53:42 rillig Exp $");
+__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.46 2024/04/07 10:10:54 rillig Exp $");
 #  include <sys/param.h>
 #  include <sys/inttypes.h>
 #  include <sys/systm.h>
@@ -162,6 +162,8 @@ new_style(state *s)
 			uint8_t b_bit = cur_bitfmt[1];
 			if (b_bit >= 64)
 				return -1;
+			if (cur_bitfmt[2] == '\0')
+				return -1;
 			s->bitfmt += 2;
 			if (((s->val >> b_bit) & 1) == 0)
 				goto skip_description;
@@ -180,6 +182,8 @@ new_style(state *s)
 			uint8_t f_width = cur_bitfmt[2];
 			if (f_width > 64)
 				return -1;
+			if (kind == 'f' && cur_bitfmt[3] == '\0')
+				return -1;
 			field = s->val >> f_lsb;
 			if (f_width < 64)
 				field &= ((uint64_t) 1 << f_width) - 1;
@@ -197,6 +201,8 @@ new_style(state *s)
 		case ':':
 			s->bitfmt += 2;
 			uint8_t cmp = cur_bitfmt[1];
+			if (cur_bitfmt[2] == '\0')
+				return -1;
 			if (field != cmp)
 				goto skip_description;
 			matched = 1;
@@ -207,6 +213,8 @@ new_style(state *s)
 			maybe_wrap_line(s, prev_bitfmt);
 			break;
 		case '*':
+			if (cur_bitfmt[1] == '\0')
+				return -1;
 			s->bitfmt++;
 			if (matched)
 				goto skip_description;

Index: src/tests/lib/libutil/t_snprintb.c
diff -u src/tests/lib/libutil/t_snprintb.c:1.32 src/tests/lib/libutil/t_snprintb.c:1.33
--- src/tests/lib/libutil/t_snprintb.c:1.32	Mon Apr  1 09:15:51 2024
+++ src/tests/lib/libutil/t_snprintb.c	Sun Apr  7 10:10:54 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: t_snprintb.c,v 1.32 2024/04/01 09:15:51 rillig Exp $ */
+/* $NetBSD: t_snprintb.c,v 1.33 2024/04/07 10:10:54 rillig Exp $ */
 
 /*
  * Copyright (c) 2002, 2004, 2008, 2010, 2024 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 #include <sys/cdefs.h>
 __COPYRIGHT("@(#) Copyright (c) 2008, 2010, 2024\
  The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_snprintb.c,v 1.32 2024/04/01 09:15:51 rillig Exp $");
+__RCSID("$NetBSD: t_snprintb.c,v 1.33 2024/04/07 10:10:54 rillig Exp $");
 
 #include <stdio.h>
 #include <string.h>
@@ -415,16 +415,20 @@ ATF_TC_BODY(snprintb, tc)
 	    0xff,
 	    "0xff<lsb,lsb,lsb>");
 
-	// new style single bits, empty description
-	h_snprintb(
+	// new style single bits, 'b' with empty description
+	//
+	// The description of a 'b' conversion must not be empty, as the
+	// output would contain several commas in a row.
+	h_snprintb_len(
+	    1024,
 	    "\177\020"
 	    "b\000lsb\0"
 	    "b\001\0"
 	    "b\002\0"
-	    "b\007msb\0"
-	    ,
+	    "b\007msb\0",
 	    0xff,
-	    "0xff<lsb,,,msb>");
+	    -1,
+	    "0xff<lsb#");
 
 	// new style single bits, bit number too large
 	h_snprintb_error(
@@ -583,16 +587,18 @@ ATF_TC_BODY(snprintb, tc)
 	    "f\101\000uint0\0",
 	    "0#");
 
-	// new style bit-field, empty field description
+	// new style bit-field, 'f' with empty description
 	//
-	// An empty field description results in an isolated '=', which is a
-	// mistake.
-	h_snprintb(
+	// The description of an 'f' conversion must not be empty, as the
+	// output would contain an isolated '='.
+	h_snprintb_len(
+	    1024,
 	    "\177\020"
 	    "f\000\004\0"
 		"=\001one\0",
 	    0x1,
-	    "0x1<=0x1=one>");
+	    -1,
+	    "0x1#");
 
 	// new style bit-field, non-printable description
 	//
@@ -612,41 +618,48 @@ ATF_TC_BODY(snprintb, tc)
 
 	// new style bit-field, '=' with empty description
 	//
-	// The description of a '=' directive should not be empty, as the
-	// outputs contains several '=' in a row.
-	h_snprintb(
+	// The description of a '=' conversion must not be empty, as the
+	// output would contain several '=' in a row.
+	h_snprintb_len(
+	    1024,
 	    "\177\020"
 	    "f\000\004f\0"
 		"=\001one\0"
 		"=\001\0"
 		"=\001\0",
 	    0x1,
-	    "0x1<f=0x1=one==>");
+	    -1,
+	    "0x1<f=0x1=one#");
 
 	// new style bit-field, 'F' followed by ':' with empty description
 	//
-	// An empty description of a ':' directive that doesn't match results
-	// in empty angle brackets, which is a mistake.
-	h_snprintb(
+	// The description of a ':' conversion must not be empty, as the
+	// output would contain empty angle brackets.
+	h_snprintb_len(
+	    1024,
 	    "\177\020"
 	    "F\000\004\0"
 		":\001\0"
 		"*default\0",
 	    0x1,
-	    "0x1<>");
+	    -1,
+	    "0x1<#");
 
 	// new style bit-field, 'F', ':' with empty description, '*'
 	//
-	// An empty description of a ':' directive that matches results in
-	// normal-looking output, but if it didn't match, the output would
-	// contain empty angle brackets, which is a mistake.
-	h_snprintb(
+	// The description of a ':' conversion must not be empty, as the
+	// output would contain empty angle brackets. Not in this particular
+	// test case, as the value is different, but the structural error is
+	// detected nevertheless.
+	h_snprintb_len(
+	    1024,
 	    "\177\020"
 	    "F\000\004\0"
 		":\001\0"
 		"*default\0",
 	    0x2,
-	    "0x2<default>");
+	    -1,
+	    "0x2<#");
 
 	// new style bit-field, 'f' with non-exhaustive '='
 	h_snprintb(

Reply via email to