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(