1
/* $NetBSD: vis.c,v 1.38 2008/09/04 09:41:44 lukem Exp $ */
4
* Copyright (c) 1989, 1993
5
* The Regents of the University of California. All rights reserved.
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* 3. Neither the name of the University nor the names of its contributors
16
* may be used to endorse or promote products derived from this software
17
* without specific prior written permission.
19
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
* Copyright (c) 1999, 2005 The NetBSD Foundation, Inc.
34
* All rights reserved.
36
* Redistribution and use in source and binary forms, with or without
37
* modification, are permitted provided that the following conditions
39
* 1. Redistributions of source code must retain the above copyright
40
* notice, this list of conditions and the following disclaimer.
41
* 2. Redistributions in binary form must reproduce the above copyright
42
* notice, this list of conditions and the following disclaimer in the
43
* documentation and/or other materials provided with the distribution.
45
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
46
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
47
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
49
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55
* POSSIBILITY OF SUCH DAMAGE.
60
#if defined(LIBC_SCCS) && !defined(lint)
61
#endif /* LIBC_SCCS and not lint */
63
#include <sys/types.h>
74
__weak_alias(strsvis,_strsvis)
75
__weak_alias(strsvisx,_strsvisx)
76
__weak_alias(strvis,_strvis)
77
__weak_alias(strvisx,_strvisx)
78
__weak_alias(svis,_svis)
79
__weak_alias(vis,_vis)
82
#if !HAVE_VIS || !HAVE_SVIS
88
static char *do_svis(char *, int, int, int, const char *);
93
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
94
#define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
95
#define issafe(c) (c == '\b' || c == BELL || c == '\r')
96
#define xtoa(c) "0123456789abcdef"[c]
100
#define MAKEEXTRALIST(flag, extra, orig_str) \
102
const char *orig = orig_str; \
103
const char *o = orig; \
107
extra = malloc((size_t)((o - orig) + MAXEXTRAS)); \
109
for (o = orig, e = extra; (*e++ = *o++) != '\0';) \
112
if (flag & VIS_SP) *e++ = ' '; \
113
if (flag & VIS_TAB) *e++ = '\t'; \
114
if (flag & VIS_NL) *e++ = '\n'; \
115
if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \
117
} while (/*CONSTCOND*/0)
120
* This is do_hvis, for HTTP style (RFC 1808)
123
do_hvis(char *dst, int c, int flag, int nextc, const char *extra)
125
if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) {
127
*dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
128
*dst++ = xtoa((unsigned int)c & 0xf);
130
dst = do_svis(dst, c, flag, nextc, extra);
136
* This is do_vis, the central code of vis.
137
* dst: Pointer to the destination buffer
138
* c: Character to encode
140
* nextc: The character following 'c'
141
* extra: Pointer to the list of extra characters to be
142
* backslash-protected.
145
do_svis(char *dst, int c, int flag, int nextc, const char *extra)
148
isextra = strchr(extra, c) != NULL;
149
if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||
150
((flag & VIS_SAFE) && issafe(c)))) {
154
if (flag & VIS_CSTYLE) {
157
*dst++ = '\\'; *dst++ = 'n';
160
*dst++ = '\\'; *dst++ = 'r';
163
*dst++ = '\\'; *dst++ = 'b';
166
*dst++ = '\\'; *dst++ = 'a';
169
*dst++ = '\\'; *dst++ = 'v';
172
*dst++ = '\\'; *dst++ = 't';
175
*dst++ = '\\'; *dst++ = 'f';
178
*dst++ = '\\'; *dst++ = 's';
181
*dst++ = '\\'; *dst++ = '0';
182
if (isoctal(nextc)) {
189
*dst++ = '\\'; *dst++ = c;
194
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
196
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';
197
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';
198
*dst++ = (c & 07) + '0';
200
if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\';
202
c &= 0177; *dst++ = 'M';
211
*dst++ = '-'; *dst++ = c;
219
* svis - visually encode characters, also encoding the characters
220
* pointed to by `extra'
223
svis(char *dst, int c, int flag, int nextc, const char *extra)
227
_DIAGASSERT(dst != NULL);
228
_DIAGASSERT(extra != NULL);
229
MAKEEXTRALIST(flag, nextra, extra);
231
*dst = '\0'; /* can't create nextra, return "" */
234
if (flag & VIS_HTTPSTYLE)
235
dst = do_hvis(dst, c, flag, nextc, nextra);
237
dst = do_svis(dst, c, flag, nextc, nextra);
245
* strsvis, strsvisx - visually encode characters from src into dst
247
* Extra is a pointer to a \0-terminated list of characters to
248
* be encoded, too. These functions are useful e. g. to
249
* encode strings in such a way so that they are not interpreted
252
* Dst must be 4 times the size of src to account for possible
253
* expansion. The length of dst, not including the trailing NULL,
256
* Strsvisx encodes exactly len bytes from src into dst.
257
* This is useful for encoding a block of data.
260
strsvis(char *dst, const char *csrc, int flag, const char *extra)
265
const unsigned char *src = (const unsigned char *)csrc;
267
_DIAGASSERT(dst != NULL);
268
_DIAGASSERT(src != NULL);
269
_DIAGASSERT(extra != NULL);
270
MAKEEXTRALIST(flag, nextra, extra);
272
*dst = '\0'; /* can't create nextra, return "" */
275
if (flag & VIS_HTTPSTYLE) {
276
for (start = dst; (c = *src++) != '\0'; /* empty */)
277
dst = do_hvis(dst, c, flag, *src, nextra);
279
for (start = dst; (c = *src++) != '\0'; /* empty */)
280
dst = do_svis(dst, c, flag, *src, nextra);
284
return (dst - start);
289
strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
294
const unsigned char *src = (const unsigned char *)csrc;
296
_DIAGASSERT(dst != NULL);
297
_DIAGASSERT(src != NULL);
298
_DIAGASSERT(extra != NULL);
299
MAKEEXTRALIST(flag, nextra, extra);
301
*dst = '\0'; /* can't create nextra, return "" */
305
if (flag & VIS_HTTPSTYLE) {
306
for (start = dst; len > 0; len--) {
308
dst = do_hvis(dst, c, flag,
309
len > 1 ? *src : '\0', nextra);
312
for (start = dst; len > 0; len--) {
314
dst = do_svis(dst, c, flag,
315
len > 1 ? *src : '\0', nextra);
320
return (dst - start);
326
* vis - visually encode characters
329
vis(char *dst, int c, int flag, int nextc)
332
unsigned char uc = (unsigned char)c;
334
_DIAGASSERT(dst != NULL);
336
MAKEEXTRALIST(flag, extra, "");
338
*dst = '\0'; /* can't create extra, return "" */
341
if (flag & VIS_HTTPSTYLE)
342
dst = do_hvis(dst, uc, flag, nextc, extra);
344
dst = do_svis(dst, uc, flag, nextc, extra);
352
* strvis, strvisx - visually encode characters from src into dst
354
* Dst must be 4 times the size of src to account for possible
355
* expansion. The length of dst, not including the trailing NULL,
358
* Strvisx encodes exactly len bytes from src into dst.
359
* This is useful for encoding a block of data.
362
strvis(char *dst, const char *src, int flag)
367
MAKEEXTRALIST(flag, extra, "");
369
*dst = '\0'; /* can't create extra, return "" */
372
rv = strsvis(dst, src, flag, extra);
379
strvisx(char *dst, const char *src, size_t len, int flag)
384
MAKEEXTRALIST(flag, extra, "");
386
*dst = '\0'; /* can't create extra, return "" */
389
rv = strsvisx(dst, src, len, flag, extra);