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));