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(