Module Name:    src
Committed By:   christos
Date:           Sat Mar 12 03:24:08 UTC 2011

Modified Files:
        src/lib/libc/gen: vis.c

Log Message:
Prepare for strnvis functionality by providing a length to the encoding
functions.


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/lib/libc/gen/vis.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/gen/vis.c
diff -u src/lib/libc/gen/vis.c:1.41 src/lib/libc/gen/vis.c:1.42
--- src/lib/libc/gen/vis.c:1.41	Mon Nov 23 05:08:47 2009
+++ src/lib/libc/gen/vis.c	Fri Mar 11 22:24:08 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: vis.c,v 1.41 2009/11/23 10:08:47 plunky Exp $	*/
+/*	$NetBSD: vis.c,v 1.42 2011/03/12 03:24:08 christos Exp $	*/
 
 /*-
  * Copyright (c) 1989, 1993
@@ -57,7 +57,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: vis.c,v 1.41 2009/11/23 10:08:47 plunky Exp $");
+__RCSID("$NetBSD: vis.c,v 1.42 2011/03/12 03:24:08 christos Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
@@ -82,7 +82,7 @@
 #include <stdio.h>
 #include <string.h>
 
-static char *do_svis(char *, int, int, int, const char *);
+static char *do_svis(char *, size_t *, int, int, int, const char *);
 
 #undef BELL
 #define BELL '\a'
@@ -118,7 +118,7 @@
  * This is do_hvis, for HTTP style (RFC 1808)
  */
 static char *
-do_hvis(char *dst, int c, int flag, int nextc, const char *extra)
+do_hvis(char *dst, size_t *len, int c, int flag, int nextc, const char *extra)
 {
 
 	if ((isascii(c) && isalnum(c))
@@ -127,8 +127,13 @@
 	    /* extra */
 	    || c == '!' || c == '*' || c == '\'' || c == '(' || c == ')'
 	    || c == ',') {
-		dst = do_svis(dst, c, flag, nextc, extra);
+		dst = do_svis(dst, len, c, flag, nextc, extra);
 	} else {
+		if (len) {
+			if (*len < 3)
+				return NULL;
+			*len -= 3;
+		}
 		*dst++ = '%';
 		*dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
 		*dst++ = xtoa((unsigned int)c & 0xf);
@@ -142,7 +147,7 @@
  * NB: No handling of long lines or CRLF.
  */
 static char *
-do_mvis(char *dst, int c, int flag, int nextc, const char *extra)
+do_mvis(char *dst, size_t *len, int c, int flag, int nextc, const char *extra)
 {
 	if ((c != '\n') &&
 	    /* Space at the end of the line */
@@ -151,11 +156,16 @@
 	    (!isspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) ||
 	    /* Specific char to be escaped */ 
 	    strchr("#$@[\\]^`{|}~", c) != NULL)) {
+		if (len) {
+			if (*len < 3)
+				return NULL;
+			*len -= 3;
+		}
 		*dst++ = '=';
 		*dst++ = XTOA(((unsigned int)c >> 4) & 0xf);
 		*dst++ = XTOA((unsigned int)c & 0xf);
 	} else {
-		dst = do_svis(dst, c, flag, nextc, extra);
+		dst = do_svis(dst, len, c, flag, nextc, extra);
 	}
 	return dst;
 }
@@ -170,16 +180,27 @@
  *	      backslash-protected.
  */
 static char *
-do_svis(char *dst, int c, int flag, int nextc, const char *extra)
+do_svis(char *dst, size_t *len, int c, int flag, int nextc, const char *extra)
 {
 	int isextra;
 	isextra = strchr(extra, c) != NULL;
+	size_t olen = len ? *len : 0;
+#define HAVE(x) \
+	do { \
+		if (len) { \
+			if (*len < (x)) \
+				goto out; \
+			*len -= (x); \
+		} \
+	} while (/*CONSTCOND*/0)
 	if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||
 	    ((flag & VIS_SAFE) && issafe(c)))) {
+		HAVE(1);
 		*dst++ = c;
 		return dst;
 	}
 	if (flag & VIS_CSTYLE) {
+		HAVE(2);
 		switch (c) {
 		case '\n':
 			*dst++ = '\\'; *dst++ = 'n';
@@ -208,6 +229,7 @@
 		case '\0':
 			*dst++ = '\\'; *dst++ = '0';
 			if (isoctal(nextc)) {
+				HAVE(2);
 				*dst++ = '0';
 				*dst++ = '0';
 			}
@@ -217,32 +239,46 @@
 				*dst++ = '\\'; *dst++ = c;
 				return dst;
 			}
+			if (len)
+				*len = olen;
 		}
 	}
 	if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
+		HAVE(4);
 		*dst++ = '\\';
 		*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';
 		*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';
 		*dst++ =			     (c	      & 07) + '0';
 	} else {
-		if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\';
+		if ((flag & VIS_NOSLASH) == 0) {
+			HAVE(1);
+			*dst++ = '\\';
+		}
+
 		if (c & 0200) {
+			HAVE(1);
 			c &= 0177; *dst++ = 'M';
 		}
+
 		if (iscntrl(c)) {
+			HAVE(2);
 			*dst++ = '^';
 			if (c == 0177)
 				*dst++ = '?';
 			else
 				*dst++ = c + '@';
 		} else {
+			HAVE(2);
 			*dst++ = '-'; *dst++ = c;
 		}
 	}
 	return dst;
+out:
+	*len = olen;
+	return NULL;
 }
 
-typedef char *(*visfun_t)(char *, int, int, int, const char *);
+typedef char *(*visfun_t)(char *, size_t *, int, int, int, const char *);
 
 /*
  * Return the appropriate encoding function depending on the flags given.
@@ -275,7 +311,7 @@
 		return dst;
 	}
 	f = getvisfun(flag);
-	dst = (*f)(dst, c, flag, nextc, nextra);
+	dst = (*f)(dst, NULL, c, flag, nextc, nextra);
 	free(nextra);
 	*dst = '\0';
 	return dst;
@@ -316,7 +352,7 @@
 	}
 	f = getvisfun(flag);
 	for (start = dst; (c = *src++) != '\0'; /* empty */)
-		dst = (*f)(dst, c, flag, *src, nextra);
+		dst = (*f)(dst, NULL, c, flag, *src, nextra);
 	free(nextra);
 	*dst = '\0';
 	return (int)(dst - start);
@@ -344,7 +380,7 @@
 	f = getvisfun(flag);
 	for (start = dst; len > 0; len--) {
 		c = *src++;
-		dst = (*f)(dst, c, flag, len > 1 ? *src : '\0', nextra);
+		dst = (*f)(dst, NULL, c, flag, len > 1 ? *src : '\0', nextra);
 	}
 	free(nextra);
 	*dst = '\0';
@@ -371,7 +407,7 @@
 		return dst;
 	}
 	f = getvisfun(flag);
-	dst = (*f)(dst, uc, flag, nextc, extra);
+	dst = (*f)(dst, NULL, uc, flag, nextc, extra);
 	free(extra);
 	*dst = '\0';
 	return dst;

Reply via email to