Module Name: src Committed By: rillig Date: Sun Apr 7 15:20:17 UTC 2024
Modified Files: src/common/lib/libutil: snprintb.c src/tests/lib/libutil: t_snprintb.c Log Message: snprintb: reject empty bit descriptions and wrongly placed defaults To generate a diff of this commit: cvs rdiff -u -r1.47 -r1.48 src/common/lib/libutil/snprintb.c cvs rdiff -u -r1.34 -r1.35 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.47 src/common/lib/libutil/snprintb.c:1.48 --- src/common/lib/libutil/snprintb.c:1.47 Sun Apr 7 12:05:23 2024 +++ src/common/lib/libutil/snprintb.c Sun Apr 7 15:20:16 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: snprintb.c,v 1.47 2024/04/07 12:05:23 rillig Exp $ */ +/* $NetBSD: snprintb.c,v 1.48 2024/04/07 15:20:16 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.47 2024/04/07 12:05:23 rillig Exp $"); +__RCSID("$NetBSD: snprintb.c,v 1.48 2024/04/07 15:20:16 rillig Exp $"); # endif # include <sys/types.h> @@ -46,7 +46,7 @@ __RCSID("$NetBSD: snprintb.c,v 1.47 2024 # include <errno.h> # else /* ! _KERNEL */ # include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.47 2024/04/07 12:05:23 rillig Exp $"); +__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.48 2024/04/07 15:20:16 rillig Exp $"); # include <sys/param.h> # include <sys/inttypes.h> # include <sys/systm.h> @@ -133,15 +133,17 @@ old_style(state *s) while (*s->bitfmt != '\0') { const char *cur_bitfmt = s->bitfmt; uint8_t bit = *s->bitfmt; - if (bit > ' ') + if (bit > 32) + return -1; + if ((uint8_t)cur_bitfmt[1] <= 32) return -1; if (s->val & (1U << (bit - 1))) { store_delimiter(s); - while ((uint8_t)*++s->bitfmt > ' ') + while ((uint8_t)*++s->bitfmt > 32) store(s, *s->bitfmt); maybe_wrap_line(s, cur_bitfmt); } else - while ((uint8_t)*++s->bitfmt > ' ') + while ((uint8_t)*++s->bitfmt > 32) continue; } return 0; @@ -222,6 +224,7 @@ new_style(state *s) case '*': if (field_kind == 0) return -1; + field_kind = 0; if (cur_bitfmt[1] == '\0') return -1; s->bitfmt++; Index: src/tests/lib/libutil/t_snprintb.c diff -u src/tests/lib/libutil/t_snprintb.c:1.34 src/tests/lib/libutil/t_snprintb.c:1.35 --- src/tests/lib/libutil/t_snprintb.c:1.34 Sun Apr 7 12:05:23 2024 +++ src/tests/lib/libutil/t_snprintb.c Sun Apr 7 15:20:17 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: t_snprintb.c,v 1.34 2024/04/07 12:05:23 rillig Exp $ */ +/* $NetBSD: t_snprintb.c,v 1.35 2024/04/07 15:20:17 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.34 2024/04/07 12:05:23 rillig Exp $"); +__RCSID("$NetBSD: t_snprintb.c,v 1.35 2024/04/07 15:20:17 rillig Exp $"); #include <stdio.h> #include <string.h> @@ -309,16 +309,16 @@ ATF_TC_BODY(snprintb, tc) // old style, empty description // - // Empty descriptions result in multiple commas in a row, which is a - // mistake. - h_snprintb( + // The description of a bit in the old format must not be empty, + // to prevent multiple commas in a row. + h_snprintb_val_error( "\020" "\001lsb" "\004" "\005" "\010msb", 0xff, - "0xff<lsb,,,msb>"); + "0xff<lsb#"); // old style, buffer size 0, null buffer // @@ -679,8 +679,8 @@ ATF_TC_BODY(snprintb, tc) // new style bit-field, 'F' with non-exhaustive ':' // // A bit-field that does not match any values generates multiple commas - // in a row, which looks confusing. The ':' directives should either be - // exhaustive, or there should be a '*' catch-all directive. + // in a row, which looks confusing. The ':' conversions should either be + // exhaustive, or there should be a '*' catch-all conversion. h_snprintb( "\177\020" "b\000bit0\0" @@ -741,7 +741,7 @@ ATF_TC_BODY(snprintb, tc) // new style bit-field, difference between '=' and ':' // - // The ':' directive can almost emulate the '=' directive, without the + // The ':' conversion can almost emulate the '=' conversion, without the // numeric output and with a different separator. It's best to use // either 'f' with '=', or 'F' with ':', but not mix them. h_snprintb( @@ -757,9 +757,9 @@ ATF_TC_BODY(snprintb, tc) // new style bit-field default, fixed string // - // The 'f' directive pairs up with the '=' directive, - // the 'F' directive pairs up with the ':' directive, - // but there's only one 'default' directive for both variants, + // The 'f' conversion pairs up with the '=' conversion, + // the 'F' conversion pairs up with the ':' conversion, + // but there's only one 'default' conversion for both variants, // so its description should include the '=' when used with 'f' but // not with 'F'. h_snprintb( @@ -787,7 +787,7 @@ ATF_TC_BODY(snprintb, tc) // new style bit-field default, can never match // - // The '=' directive are exhaustive, making the '*' redundant. + // The '=' conversion are exhaustive, making the '*' redundant. h_snprintb( "\177\020" "f\010\002f\0" @@ -811,14 +811,14 @@ ATF_TC_BODY(snprintb, tc) 0xff, "0xff<f=0xff=000000000000000000000000000255%>"); - // new style unknown directive, at the beginning + // new style unknown conversion, at the beginning h_snprintb_val_error( "\177\020" "unknown\0", 0xff, "0xff#"); - // new style unknown directive, after a known directive + // new style unknown conversion, after a known conversion h_snprintb_val_error( "\177\020" "b\007msb\0" @@ -946,42 +946,51 @@ ATF_TC_BODY(snprintb, tc) // new style combinations, 'f' '*' '=' // - // After a catch-all '*' directive, any following '=' directive - // generates misleading output, which is a mistake. - h_snprintb( + // After a catch-all '*' conversions, there must not be further '=' + // conversions. + h_snprintb_val_error( "\177\020" "f\000\010f\0" "*=default\0" "=\245match\0", 0xa5, - "0xa5<f=0xa5=default=match>"); + "0xa5<f=0xa5=default#"); // new style combinations, 'F' '*' ':' // - // After a catch-all '*' directive, any following ':' directive - // generates misleading output, which is a mistake. - h_snprintb( + // After a catch-all '*' conversion, there must not be further ':' + // conversions. + h_snprintb_val_error( "\177\020" "F\000\010F\0" "*default\0" ":\245-match\0", 0xa5, - "0xa5<default-match>"); + "0xa5<default#"); - // new style combinations, '*' '*' + // new style combinations, 'f' '*' '*' // - // After a catch-all '*' directive, any further '*' directive is - // ignored and thus redundant, which is a mistake. - h_snprintb( + // After a catch-all '*' conversion, there must not be further '=' or + // '*' conversions. + h_snprintb_val_error( "\177\020" "f\000\010f\0" "*=default-f\0" - "*ignored\0" + "*ignored\0", + 0xa5, + "0xa5<f=0xa5=default-f#"); + + // new style combinations, 'F' '*' '*' + // + // After a catch-all '*' conversion, there must not be further ':' or + // '*' conversions. + h_snprintb_val_error( + "\177\020" "F\000\010\0" "*default-F\0" "*ignored\0", 0xa5, - "0xa5<f=0xa5=default-f,default-F>"); + "0xa5<default-F#"); // example from the manual page, old style octal h_snprintb(