From 2ebef95994953e49ae84862a65f9ee649a72e200 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 1 Sep 2015 21:08:19 +0100 Subject: [PATCH] Sync up vis.* for stravis(). --- compat/vis.c | 56 ++++++++++++++++++++++++++++++++++++---------------- compat/vis.h | 10 +++++++++- configure.ac | 14 ++++++------- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/compat/vis.c b/compat/vis.c index 97eb5271..82b42be9 100644 --- a/compat/vis.c +++ b/compat/vis.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vis.c,v 1.19 2005/09/01 17:15:49 millert Exp $ */ +/* $OpenBSD: vis.c,v 1.24 2015/07/20 01:52:28 millert Exp $ */ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -29,14 +29,17 @@ */ #include -#include +#include #include +#include #include +#include #include "tmux.h" #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define isvisible(c) \ +#define isvisible(c,flag) \ + (((c) == '\\' || (flag & VIS_ALL) == 0) && \ (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \ (((c) != '*' && (c) != '?' && (c) != '[' && (c) != '#') || \ (flag & VIS_GLOB) == 0) && isgraph((u_char)(c))) || \ @@ -45,7 +48,7 @@ ((flag & VIS_NL) == 0 && (c) == '\n') || \ ((flag & VIS_SAFE) && ((c) == '\b' || \ (c) == '\007' || (c) == '\r' || \ - isgraph((u_char)(c))))) + isgraph((u_char)(c)))))) /* * vis - visually encode characters @@ -53,10 +56,11 @@ char * vis(char *dst, int c, int flag, int nextc) { - if (isvisible(c)) { - *dst++ = c; - if (c == '\\' && (flag & VIS_NOSLASH) == 0) + if (isvisible(c, flag)) { + if ((c == '"' && (flag & VIS_DQ) != 0) || + (c == '\\' && (flag & VIS_NOSLASH) == 0)) *dst++ = '\\'; + *dst++ = c; *dst = '\0'; return (dst); } @@ -136,10 +140,10 @@ done: /* * strvis, strnvis, strvisx - visually encode characters from src into dst - * + * * Dst must be 4 times the size of src to account for possible * expansion. The length of dst, not including the trailing NULL, - * is returned. + * is returned. * * Strnvis will write no more than siz-1 bytes (and will NULL terminate). * The number of bytes needed to fully encode the string is returned. @@ -168,19 +172,18 @@ strnvis(char *dst, const char *src, size_t siz, int flag) 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) { + if (isvisible(c, flag)) { + if ((c == '"' && (flag & VIS_DQ) != 0) || + (c == '\\' && (flag & VIS_NOSLASH) == 0)) { /* need space for the extra '\\' */ - if (dst < end) - *dst++ = '\\'; - else { - dst--; + if (dst + 1 >= end) { i = 2; break; } + *dst++ = '\\'; } + i = 1; + *dst++ = c; src++; } else { i = vis(tbuf, c, flag, *++src) - tbuf; @@ -203,6 +206,25 @@ strnvis(char *dst, const char *src, size_t siz, int flag) return (dst - start); } +int +stravis(char **outp, const char *src, int flag) +{ + char *buf; + int len, serrno; + + buf = calloc(4, strlen(src) + 1); + if (buf == NULL) + return -1; + len = strvis(buf, src, flag); + serrno = errno; + *outp = realloc(buf, len + 1); + if (*outp == NULL) { + *outp = buf; + errno = serrno; + } + return (len); +} + int strvisx(char *dst, const char *src, size_t len, int flag) { diff --git a/compat/vis.h b/compat/vis.h index d6ff235d..6795139c 100644 --- a/compat/vis.h +++ b/compat/vis.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 millert Exp $ */ +/* $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 millert Exp $ */ /* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ /*- @@ -50,6 +50,8 @@ #define VIS_NL 0x10 /* also encode newline */ #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) #define VIS_SAFE 0x20 /* only encode "unsafe" characters */ +#define VIS_DQ 0x200 /* backslash-escape double quotes */ +#define VIS_ALL 0x400 /* encode all characters */ /* * other @@ -71,12 +73,18 @@ */ #define UNVIS_END 1 /* no more characters */ +#include + +__BEGIN_DECLS char *vis(char *, int, int, int); int strvis(char *, const char *, int); +int stravis(char **, const char *, int); int strnvis(char *, const char *, size_t, int); int strvisx(char *, const char *, size_t, int); int strunvis(char *, const char *); int unvis(char *, char, int *, int); ssize_t strnunvis(char *, const char *, size_t); +__END_DECLS + #endif /* !_VIS_H_ */ diff --git a/configure.ac b/configure.ac index de336fef..9d64a964 100644 --- a/configure.ac +++ b/configure.ac @@ -326,22 +326,22 @@ if test "x$found_strtonum" = xyes; then fi AM_CONDITIONAL(NO_STRTONUM, [test "x$found_strtonum" = xno]) -# Look for strnvis, compat/{vis,unvis}.c used if missing. -AC_CHECK_FUNC(strnvis, found_strnvis=yes, found_strnvis=no) -if test "x$found_strnvis" = xyes; then +# Look for stravis, compat/{vis,unvis}.c used if missing. +AC_CHECK_FUNC(stravis, found_stravis=yes, found_stravis=no) +if test "x$found_stravis" = xyes; then AC_MSG_CHECKING(if strnvis is broken) AC_EGREP_HEADER([strnvis\(char \*, const char \*, size_t, int\)], vis.h, AC_MSG_RESULT(no), - [found_strnvis=no]) - if test "x$found_strnvis" = xno; then + [found_stravis=no]) + if test "x$found_stravis" = xno; then AC_MSG_RESULT(yes) fi fi -if test "x$found_strnvis" = xyes; then +if test "x$found_stravis" = xyes; then AC_DEFINE(HAVE_VIS) fi -AM_CONDITIONAL(NO_VIS, [test "x$found_strnvis" = xno]) +AM_CONDITIONAL(NO_VIS, [test "x$found_stravis" = xno]) # Look for cfmakeraw, compat/cfmakeraw.c used if missing. AC_CHECK_FUNC(cfmakeraw, found_cfmakeraw=yes, found_cfmakeraw=no)