Module Name: src Committed By: rillig Date: Fri Feb 16 19:53:40 UTC 2024
Modified Files: src/common/lib/libutil: snprintb.c src/tests/lib/libutil: t_snprintb.c Log Message: snprintb: eliminate two local variables, allow zero-size buffer Like snprintf, the buffer size may be zero. Unlike snprintf, the buffer must not be NULL. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/common/lib/libutil/snprintb.c cvs rdiff -u -r1.19 -r1.20 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.32 src/common/lib/libutil/snprintb.c:1.33 --- src/common/lib/libutil/snprintb.c:1.32 Fri Feb 16 19:31:25 2024 +++ src/common/lib/libutil/snprintb.c Fri Feb 16 19:53:40 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: snprintb.c,v 1.32 2024/02/16 19:31:25 rillig Exp $ */ +/* $NetBSD: snprintb.c,v 1.33 2024/02/16 19:53:40 rillig Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ # include <sys/cdefs.h> # if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: snprintb.c,v 1.32 2024/02/16 19:31:25 rillig Exp $"); +__RCSID("$NetBSD: snprintb.c,v 1.33 2024/02/16 19:53:40 rillig Exp $"); # endif # include <sys/types.h> @@ -51,7 +51,7 @@ __RCSID("$NetBSD: snprintb.c,v 1.32 2024 # include <errno.h> # else /* ! _KERNEL */ # include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.32 2024/02/16 19:31:25 rillig Exp $"); +__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.33 2024/02/16 19:53:40 rillig Exp $"); # include <sys/param.h> # include <sys/inttypes.h> # include <sys/systm.h> @@ -63,7 +63,6 @@ int snprintb_m(char *buf, size_t bufsize, const char *bitfmt, uint64_t val, size_t line_max) { - char *bp = buf, *sep_bp = NULL; const char *num_fmt, *cur_bitfmt, *sep_bitfmt = NULL; char sep; int restart = 0; @@ -97,39 +96,33 @@ snprintb_m(char *buf, size_t bufsize, co if (line_max > 0) bufsize--; - int val_len = snprintf(bp, bufsize, num_fmt, (uintmax_t)val); + int val_len = snprintf(buf, bufsize, num_fmt, (uintmax_t)val); if (val_len < 0) goto internal; size_t total_len = val_len, line_len = val_len, sep_line_len = 0; - if (total_len < bufsize) - bp += total_len; - else - bp += bufsize - 1; - #define STORE(c) do { \ + if (total_len < bufsize) \ + buf[total_len] = (c); \ + total_len++; \ line_len++; \ - if (++total_len < bufsize) \ - *bp++ = (c); \ } while (0) #define BACKUP() do { \ - if (sep_bp != NULL) { \ - bp = sep_bp; \ - sep_bp = NULL; \ + if (sep_line_len > 0) { \ total_len -= line_len - sep_line_len; \ + sep_line_len = 0; \ restart = 1; \ bitfmt = sep_bitfmt; \ } \ STORE('>'); \ STORE('\0'); \ if (total_len < bufsize) \ - snprintf(bp, bufsize - total_len, num_fmt, \ - (uintmax_t)val); \ + snprintf(buf + total_len, bufsize - total_len, \ + num_fmt, (uintmax_t)val); \ total_len += val_len; \ line_len = val_len; \ - bp += val_len; \ } while (0) #define PUTSEP() do { \ @@ -137,10 +130,8 @@ snprintb_m(char *buf, size_t bufsize, co BACKUP(); \ STORE('<'); \ } else { \ - /* Remember separator location */ \ if (line_max > 0 && sep != '<') { \ sep_line_len = line_len; \ - sep_bp = bp; \ sep_bitfmt = cur_bitfmt; \ } \ STORE(sep); \ @@ -170,15 +161,13 @@ snprintb_m(char *buf, size_t bufsize, co } while (0) #define FMTSTR(sb, f) do { \ - size_t n = total_len < bufsize \ - ? bufsize - total_len : 0; \ + char *bp = total_len < bufsize ? buf + total_len : NULL; \ + size_t n = total_len < bufsize ? bufsize - total_len : 0; \ int fmt_len = snprintf(bp, n, sb, (uintmax_t)f); \ if (fmt_len < 0) \ goto internal; \ total_len += fmt_len; \ line_len += fmt_len; \ - if (total_len < bufsize) \ - bp += fmt_len; \ } while (0) sep = '<'; Index: src/tests/lib/libutil/t_snprintb.c diff -u src/tests/lib/libutil/t_snprintb.c:1.19 src/tests/lib/libutil/t_snprintb.c:1.20 --- src/tests/lib/libutil/t_snprintb.c:1.19 Fri Feb 16 19:20:38 2024 +++ src/tests/lib/libutil/t_snprintb.c Fri Feb 16 19:53:40 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: t_snprintb.c,v 1.19 2024/02/16 19:20:38 rillig Exp $ */ +/* $NetBSD: t_snprintb.c,v 1.20 2024/02/16 19:53:40 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\ The NetBSD Foundation, inc. All rights reserved."); -__RCSID("$NetBSD: t_snprintb.c,v 1.19 2024/02/16 19:20:38 rillig Exp $"); +__RCSID("$NetBSD: t_snprintb.c,v 1.20 2024/02/16 19:53:40 rillig Exp $"); #include <stdio.h> #include <string.h> @@ -79,9 +79,6 @@ h_snprintb_loc(const char *file, size_t { char buf[1024]; - // Calling snprintb with bufsize == 0 invokes undefined - // behavior due to out-of-range 'bp'. - ATF_REQUIRE(bufsize > 0); ATF_REQUIRE(bufsize <= sizeof(buf)); ATF_REQUIRE(reslen <= sizeof(buf)); @@ -90,8 +87,11 @@ h_snprintb_loc(const char *file, size_t ATF_REQUIRE(rv >= 0); size_t rlen = rv; + if (bufsize == 0 && reslen == 1) + reslen = 0; ATF_CHECK_MSG( - rv == exp_rv && memcmp(buf, res, reslen) == 0 + rv == exp_rv + && memcmp(buf, res, reslen) == 0 && buf[rlen < bufsize ? rlen : bufsize - 1] == '\0', "failed:\n" "\ttest case: %s:%zu\n" @@ -244,14 +244,10 @@ ATF_TC_BODY(snprintb, tc) h_snprintb_error( "\377"); - // old-style format, small buffer -#if 0 - // FIXME: Calling snprintb with buffer size 0 invokes undefined - // behavior due to out-of-bounds 'bp' pointer. + // old-style format, small buffers h_snprintb_len( 0, "\020", 0, 1, ""); -#endif h_snprintb_len( 1, "\020", 0, 1, ""); @@ -599,14 +595,10 @@ ATF_TC_BODY(snprintb, tc) expected); } - // new-style format, small buffer -#if 0 - // FIXME: Calling snprintb with buffer size 0 invokes undefined - // behavior due to out-of-bounds 'bp' pointer. + // new-style format, small buffers h_snprintb_len( 0, "\177\020", 0, 1, ""); -#endif h_snprintb_len( 1, "\177\020", 0, 1, ""); @@ -653,7 +645,7 @@ h_snprintb_m_loc(const char *file, size_ { char buf[1024]; - ATF_REQUIRE(bufsize > 1); + ATF_REQUIRE(bufsize > 0); ATF_REQUIRE(bufsize <= sizeof(buf)); ATF_REQUIRE(reslen <= sizeof(buf));