root/source4/heimdal/lib/roken/vis.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_hvis
  2. do_svis
  3. rk_svis
  4. rk_strsvis
  5. rk_strsvisx
  6. rk_vis
  7. rk_strvis
  8. rk_strvisx

   1 /*      $NetBSD: vis.c,v 1.37 2008/07/25 22:29:23 dsl Exp $     */
   2 
   3 /*-
   4  * Copyright (c) 1989, 1993
   5  *      The Regents of the University of California.  All rights reserved.
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  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.
  18  *
  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
  29  * SUCH DAMAGE.
  30  */
  31 
  32 /*-
  33  * Copyright (c) 1999, 2005 The NetBSD Foundation, Inc.
  34  * All rights reserved.
  35  *
  36  * Redistribution and use in source and binary forms, with or without
  37  * modification, are permitted provided that the following conditions
  38  * are met:
  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.
  44  *
  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.
  56  */
  57 
  58 #if 1
  59 #ifdef HAVE_CONFIG_H
  60 #include <config.h>
  61 RCSID("$Id$");
  62 #endif
  63 #include "roken.h"
  64 #ifndef _DIAGASSERT
  65 #define _DIAGASSERT(X)
  66 #endif
  67 #else /* heimdal */
  68 #include <sys/cdefs.h>
  69 #if defined(LIBC_SCCS) && !defined(lint)
  70 __RCSID("$NetBSD: vis.c,v 1.37 2008/07/25 22:29:23 dsl Exp $");
  71 #endif /* LIBC_SCCS and not lint */
  72 
  73 #include "namespace.h"
  74 #endif /* heimdal */
  75 
  76 #include <sys/types.h>
  77 
  78 #include <assert.h>
  79 #include <ctype.h>
  80 #include <limits.h>
  81 #include <stdio.h>
  82 #include <string.h>
  83 #include <vis.h>
  84 #include <stdlib.h>
  85 
  86 #if 0
  87 #ifdef __weak_alias
  88 __weak_alias(strsvis,_strsvis)
  89 __weak_alias(strsvisx,_strsvisx)
  90 __weak_alias(strvis,_strvis)
  91 __weak_alias(strvisx,_strvisx)
  92 __weak_alias(svis,_svis)
  93 __weak_alias(vis,_vis)
  94 #endif
  95 #endif
  96 
  97 #if !HAVE_VIS || !HAVE_SVIS
  98 #include <ctype.h>
  99 #include <limits.h>
 100 #include <stdio.h>
 101 #include <string.h>
 102 
 103 static char *do_svis(char *, int, int, int, const char *);
 104 
 105 #undef BELL
 106 #if defined(__STDC__)
 107 #define BELL '\a'
 108 #else
 109 #define BELL '\007'
 110 #endif
 111 
 112 char * ROKEN_LIB_FUNCTION
 113         rk_vis (char *, int, int, int);
 114 char * ROKEN_LIB_FUNCTION
 115         rk_svis (char *, int, int, int, const char *);
 116 int ROKEN_LIB_FUNCTION
 117         rk_strvis (char *, const char *, int);
 118 int ROKEN_LIB_FUNCTION
 119         rk_strsvis (char *, const char *, int, const char *);
 120 int ROKEN_LIB_FUNCTION
 121         rk_strvisx (char *, const char *, size_t, int);
 122 int ROKEN_LIB_FUNCTION
 123         rk_strsvisx (char *, const char *, size_t, int, const char *);
 124 
 125 
 126 #define isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
 127 #define iswhite(c)      (c == ' ' || c == '\t' || c == '\n')
 128 #define issafe(c)       (c == '\b' || c == BELL || c == '\r')
 129 #define xtoa(c)         "0123456789abcdef"[c]
 130 
 131 #define MAXEXTRAS       5
 132 
 133 #define MAKEEXTRALIST(flag, extra, orig_str)                                  \
 134 do {                                                                          \
 135         const char *orig = orig_str;                                          \
 136         const char *o = orig;                                                 \
 137         char *e;                                                              \
 138         while (*o++)                                                          \
 139                 continue;                                                     \
 140         extra = malloc((size_t)((o - orig) + MAXEXTRAS));                     \
 141         if (!extra) break;                                                    \
 142         for (o = orig, e = extra; (*e++ = *o++) != '\0';)                     \
 143                 continue;                                                     \
 144         e--;                                                                  \
 145         if (flag & VIS_SP) *e++ = ' ';                                        \
 146         if (flag & VIS_TAB) *e++ = '\t';                                      \
 147         if (flag & VIS_NL) *e++ = '\n';                                       \
 148         if ((flag & VIS_NOSLASH) == 0) *e++ = '\\';                           \
 149         *e = '\0';                                                            \
 150 } while (/*CONSTCOND*/0)
 151 
 152 /*
 153  * This is do_hvis, for HTTP style (RFC 1808)
 154  */
 155 static char *
 156 do_hvis(char *dst, int c, int flag, int nextc, const char *extra)
     /* [<][>][^][v][top][bottom][index][help] */
 157 {
 158         if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) {
 159                 *dst++ = '%';
 160                 *dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
 161                 *dst++ = xtoa((unsigned int)c & 0xf);
 162         } else {
 163                 dst = do_svis(dst, c, flag, nextc, extra);
 164         }
 165         return dst;
 166 }
 167 
 168 /*
 169  * This is do_vis, the central code of vis.
 170  * dst:       Pointer to the destination buffer
 171  * c:         Character to encode
 172  * flag:      Flag word
 173  * nextc:     The character following 'c'
 174  * extra:     Pointer to the list of extra characters to be
 175  *            backslash-protected.
 176  */
 177 static char *
 178 do_svis(char *dst, int c, int flag, int nextc, const char *extra)
     /* [<][>][^][v][top][bottom][index][help] */
 179 {
 180         int isextra;
 181         isextra = strchr(extra, c) != NULL;
 182         if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||
 183             ((flag & VIS_SAFE) && issafe(c)))) {
 184                 *dst++ = c;
 185                 return dst;
 186         }
 187         if (flag & VIS_CSTYLE) {
 188                 switch (c) {
 189                 case '\n':
 190                         *dst++ = '\\'; *dst++ = 'n';
 191                         return dst;
 192                 case '\r':
 193                         *dst++ = '\\'; *dst++ = 'r';
 194                         return dst;
 195                 case '\b':
 196                         *dst++ = '\\'; *dst++ = 'b';
 197                         return dst;
 198                 case BELL:
 199                         *dst++ = '\\'; *dst++ = 'a';
 200                         return dst;
 201                 case '\v':
 202                         *dst++ = '\\'; *dst++ = 'v';
 203                         return dst;
 204                 case '\t':
 205                         *dst++ = '\\'; *dst++ = 't';
 206                         return dst;
 207                 case '\f':
 208                         *dst++ = '\\'; *dst++ = 'f';
 209                         return dst;
 210                 case ' ':
 211                         *dst++ = '\\'; *dst++ = 's';
 212                         return dst;
 213                 case '\0':
 214                         *dst++ = '\\'; *dst++ = '0';
 215                         if (isoctal(nextc)) {
 216                                 *dst++ = '0';
 217                                 *dst++ = '0';
 218                         }
 219                         return dst;
 220                 default:
 221                         if (isgraph(c)) {
 222                                 *dst++ = '\\'; *dst++ = c;
 223                                 return dst;
 224                         }
 225                 }
 226         }
 227         if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
 228                 *dst++ = '\\';
 229                 *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';
 230                 *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';
 231                 *dst++ =                             (c       & 07) + '0';
 232         } else {
 233                 if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\';
 234                 if (c & 0200) {
 235                         c &= 0177; *dst++ = 'M';
 236                 }
 237                 if (iscntrl(c)) {
 238                         *dst++ = '^';
 239                         if (c == 0177)
 240                                 *dst++ = '?';
 241                         else
 242                                 *dst++ = c + '@';
 243                 } else {
 244                         *dst++ = '-'; *dst++ = c;
 245                 }
 246         }
 247         return dst;
 248 }
 249 
 250 
 251 /*
 252  * svis - visually encode characters, also encoding the characters
 253  *        pointed to by `extra'
 254  */
 255 char * ROKEN_LIB_FUNCTION
 256 rk_svis(char *dst, int c, int flag, int nextc, const char *extra)
     /* [<][>][^][v][top][bottom][index][help] */
 257 {
 258         char *nextra = NULL;
 259 
 260         _DIAGASSERT(dst != NULL);
 261         _DIAGASSERT(extra != NULL);
 262         MAKEEXTRALIST(flag, nextra, extra);
 263         if (!nextra) {
 264                 *dst = '\0';            /* can't create nextra, return "" */
 265                 return dst;
 266         }
 267         if (flag & VIS_HTTPSTYLE)
 268                 dst = do_hvis(dst, c, flag, nextc, nextra);
 269         else
 270                 dst = do_svis(dst, c, flag, nextc, nextra);
 271         free(nextra);
 272         *dst = '\0';
 273         return dst;
 274 }
 275 
 276 
 277 /*
 278  * strsvis, strsvisx - visually encode characters from src into dst
 279  *
 280  *      Extra is a pointer to a \0-terminated list of characters to
 281  *      be encoded, too. These functions are useful e. g. to
 282  *      encode strings in such a way so that they are not interpreted
 283  *      by a shell.
 284  *
 285  *      Dst must be 4 times the size of src to account for possible
 286  *      expansion.  The length of dst, not including the trailing NULL,
 287  *      is returned.
 288  *
 289  *      Strsvisx encodes exactly len bytes from src into dst.
 290  *      This is useful for encoding a block of data.
 291  */
 292 int ROKEN_LIB_FUNCTION
 293 rk_strsvis(char *dst, const char *csrc, int flag, const char *extra)
     /* [<][>][^][v][top][bottom][index][help] */
 294 {
 295         int c;
 296         char *start;
 297         char *nextra = NULL;
 298         const unsigned char *src = (const unsigned char *)csrc;
 299 
 300         _DIAGASSERT(dst != NULL);
 301         _DIAGASSERT(src != NULL);
 302         _DIAGASSERT(extra != NULL);
 303         MAKEEXTRALIST(flag, nextra, extra);
 304         if (!nextra) {
 305                 *dst = '\0';            /* can't create nextra, return "" */
 306                 return 0;
 307         }
 308         if (flag & VIS_HTTPSTYLE) {
 309                 for (start = dst; (c = *src++) != '\0'; /* empty */)
 310                         dst = do_hvis(dst, c, flag, *src, nextra);
 311         } else {
 312                 for (start = dst; (c = *src++) != '\0'; /* empty */)
 313                         dst = do_svis(dst, c, flag, *src, nextra);
 314         }
 315         free(nextra);
 316         *dst = '\0';
 317         return (dst - start);
 318 }
 319 
 320 
 321 int ROKEN_LIB_FUNCTION
 322 rk_strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
     /* [<][>][^][v][top][bottom][index][help] */
 323 {
 324         unsigned char c;
 325         char *start;
 326         char *nextra = NULL;
 327         const unsigned char *src = (const unsigned char *)csrc;
 328 
 329         _DIAGASSERT(dst != NULL);
 330         _DIAGASSERT(src != NULL);
 331         _DIAGASSERT(extra != NULL);
 332         MAKEEXTRALIST(flag, nextra, extra);
 333         if (! nextra) {
 334                 *dst = '\0';            /* can't create nextra, return "" */
 335                 return 0;
 336         }
 337 
 338         if (flag & VIS_HTTPSTYLE) {
 339                 for (start = dst; len > 0; len--) {
 340                         c = *src++;
 341                         dst = do_hvis(dst, c, flag, len ? *src : '\0', nextra);
 342                 }
 343         } else {
 344                 for (start = dst; len > 0; len--) {
 345                         c = *src++;
 346                         dst = do_svis(dst, c, flag, len ? *src : '\0', nextra);
 347                 }
 348         }
 349         free(nextra);
 350         *dst = '\0';
 351         return (dst - start);
 352 }
 353 #endif
 354 
 355 #if !HAVE_VIS
 356 /*
 357  * vis - visually encode characters
 358  */
 359 char * ROKEN_LIB_FUNCTION
 360 rk_vis(char *dst, int c, int flag, int nextc)
     /* [<][>][^][v][top][bottom][index][help] */
 361 {
 362         char *extra = NULL;
 363         unsigned char uc = (unsigned char)c;
 364 
 365         _DIAGASSERT(dst != NULL);
 366 
 367         MAKEEXTRALIST(flag, extra, "");
 368         if (! extra) {
 369                 *dst = '\0';            /* can't create extra, return "" */
 370                 return dst;
 371         }
 372         if (flag & VIS_HTTPSTYLE)
 373                 dst = do_hvis(dst, uc, flag, nextc, extra);
 374         else
 375                 dst = do_svis(dst, uc, flag, nextc, extra);
 376         free(extra);
 377         *dst = '\0';
 378         return dst;
 379 }
 380 
 381 
 382 /*
 383  * strvis, strvisx - visually encode characters from src into dst
 384  *
 385  *      Dst must be 4 times the size of src to account for possible
 386  *      expansion.  The length of dst, not including the trailing NULL,
 387  *      is returned.
 388  *
 389  *      Strvisx encodes exactly len bytes from src into dst.
 390  *      This is useful for encoding a block of data.
 391  */
 392 int ROKEN_LIB_FUNCTION
 393 rk_strvis(char *dst, const char *src, int flag)
     /* [<][>][^][v][top][bottom][index][help] */
 394 {
 395         char *extra = NULL;
 396         int rv;
 397 
 398         MAKEEXTRALIST(flag, extra, "");
 399         if (!extra) {
 400                 *dst = '\0';            /* can't create extra, return "" */
 401                 return 0;
 402         }
 403         rv = strsvis(dst, src, flag, extra);
 404         free(extra);
 405         return rv;
 406 }
 407 
 408 
 409 int ROKEN_LIB_FUNCTION
 410 rk_strvisx(char *dst, const char *src, size_t len, int flag)
     /* [<][>][^][v][top][bottom][index][help] */
 411 {
 412         char *extra = NULL;
 413         int rv;
 414 
 415         MAKEEXTRALIST(flag, extra, "");
 416         if (!extra) {
 417                 *dst = '\0';            /* can't create extra, return "" */
 418                 return 0;
 419         }
 420         rv = strsvisx(dst, src, len, flag, extra);
 421         free(extra);
 422         return rv;
 423 }
 424 #endif

/* [<][>][^][v][top][bottom][index][help] */