summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Janzen <pjanzen@cvs.openbsd.org>2002-07-01 07:48:51 +0000
committerPaul Janzen <pjanzen@cvs.openbsd.org>2002-07-01 07:48:51 +0000
commite7e0265cfd58fe5043251b6d2c20a3c17e98c612 (patch)
treeb9d6c13266747aeff8a4253b93b829cc4aea8354
parent04cf8c7c383d061d9ac275f4d5f22c3643a51de8 (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.317
-rw-r--r--lib/libc/gen/vis.c31
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;