diff options
author | Paul Janzen <pjanzen@cvs.openbsd.org> | 2002-07-01 07:48:51 +0000 |
---|---|---|
committer | Paul Janzen <pjanzen@cvs.openbsd.org> | 2002-07-01 07:48:51 +0000 |
commit | e7e0265cfd58fe5043251b6d2c20a3c17e98c612 (patch) | |
tree | b9d6c13266747aeff8a4253b93b829cc4aea8354 | |
parent | 04cf8c7c383d061d9ac275f4d5f22c3643a51de8 (diff) |
Fix strnvis(): don't truncate unnecessarily, set the return value correctly
if we had to truncate, and don't NUL-terminate if size == 0.
-rw-r--r-- | lib/libc/gen/vis.3 | 17 | ||||
-rw-r--r-- | lib/libc/gen/vis.c | 31 |
2 files changed, 31 insertions, 17 deletions
diff --git a/lib/libc/gen/vis.3 b/lib/libc/gen/vis.3 index 58e6d94f218..89487c7952e 100644 --- a/lib/libc/gen/vis.3 +++ b/lib/libc/gen/vis.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: vis.3,v 1.15 2001/11/09 19:34:46 aaron Exp $ +.\" $OpenBSD: vis.3,v 1.16 2002/07/01 07:48:50 pjanzen Exp $ .\" .\" Copyright (c) 1989, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -45,11 +45,11 @@ .Ft char * .Fn vis "char *dst" "char c" "int flag" "char nextc" .Ft int -.Fn strvis "char *dst" "char *src" "int flag" +.Fn strvis "char *dst" "const char *src" "int flag" .Ft int -.Fn strnvis "char *dst" "char *src" "size_t size" "int flag" +.Fn strnvis "char *dst" "const char *src" "size_t size" "int flag" .Ft int -.Fn strvisx "char *dst" "char *src" "size_t len" "int flag" +.Fn strvisx "char *dst" "const char *src" "size_t len" "int flag" .Sh DESCRIPTION The .Fn vis @@ -111,7 +111,14 @@ characters from (this is useful for encoding a block of data that may contain NULs). All three forms NUL terminate -.Fa dst . +.Fa dst , +except for +.Fn strnvis +when +.Fa size +is zero, in which case +.Fa dst +is not touched. For .Fn strvis and diff --git a/lib/libc/gen/vis.c b/lib/libc/gen/vis.c index 894366e8cc1..76c44acebfd 100644 --- a/lib/libc/gen/vis.c +++ b/lib/libc/gen/vis.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: vis.c,v 1.8 2002/02/19 19:39:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: vis.c,v 1.9 2002/07/01 07:48:50 pjanzen Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -168,16 +168,20 @@ strvis(dst, src, flag) int strnvis(dst, src, siz, flag) - register char *dst; - register const char *src; + char *dst; + const char *src; size_t siz; int flag; { - register char c; + char c; char *start, *end; + char tbuf[5]; + int i; + i = 0; for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { if (isvisible(c)) { + i = 1; *dst++ = c; if (c == '\\' && (flag & VIS_NOSLASH) == 0) { /* need space for the extra '\\' */ @@ -185,22 +189,25 @@ strnvis(dst, src, siz, flag) *dst++ = '\\'; else { dst--; + i = 2; break; } } src++; } else { - /* vis(3) requires up to 4 chars */ - if (dst + 3 < end) - dst = vis(dst, c, flag, *++src); - else + i = vis(tbuf, c, flag, *++src) - tbuf; + if (dst + i <= end) { + memcpy(dst, tbuf, i); + dst += i; + } else { + src--; break; + } } } - *dst = '\0'; - if (dst >= end) { - char tbuf[5]; - + if (siz > 0) + *dst = '\0'; + if (dst + i > end) { /* adjust return value for truncation */ while ((c = *src)) dst += vis(tbuf, c, flag, *++src) - tbuf; |