diff options
| author | christos <christos@NetBSD.org> | 2002-03-23 17:38:27 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2002-03-23 17:38:27 +0000 |
| commit | e20c30d79415b1fdd55b176fcda19dcfc4e899d4 (patch) | |
| tree | 39dea70bd3fa4aa27f22f321186d0927a3c4b82e | |
| parent | 4498b37c8b676e3e369f23111c13ab341a3d3a90 (diff) | |
- Add VIS_HTTPSTYLE from FreeBSD.
- svis, strsvis, strsvisx were not reversible, because they did not encode
\\ unless it was passed in the extras array.
- Fix documentation to match the proper signature of the functions.
| -rw-r--r-- | lib/libc/gen/unvis.3 | 37 | ||||
| -rw-r--r-- | lib/libc/gen/unvis.c | 46 | ||||
| -rw-r--r-- | lib/libc/gen/vis.3 | 22 | ||||
| -rw-r--r-- | lib/libc/gen/vis.c | 96 |
4 files changed, 162 insertions, 39 deletions
diff --git a/lib/libc/gen/unvis.3 b/lib/libc/gen/unvis.3 index 68b348749bb..7aa1b67c853 100644 --- a/lib/libc/gen/unvis.3 +++ b/lib/libc/gen/unvis.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: unvis.3,v 1.13 2002/02/07 09:24:05 ross Exp $ +.\" $NetBSD: unvis.3,v 1.14 2002/03/23 17:38:27 christos Exp $ .\" .\" Copyright (c) 1989, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -45,14 +45,17 @@ .Sh SYNOPSIS .Fd #include \*[Lt]vis.h\*[Gt] .Ft int -.Fn unvis "char *cp" "char c" "int *astate" "int flag" +.Fn unvis "char *cp" "int c" "int *astate" "int flag" .Ft int -.Fn strunvis "char *dst" "char *src" +.Fn strunvis "char *dst" "const char *src" +.Ft int +.Fn strunvisx "char *dst" "const char *src" "int flag" .Sh DESCRIPTION The -.Fn unvis -and +.Fn unvis , .Fn strunvis +and +.Fn strunvisx functions are used to decode a visual representation of characters, as produced by the @@ -92,6 +95,17 @@ should be equal to the size of (that is, no expansion takes place during decoding). .Pp The +.Fn strunvisx +function does the same as the +.Fn strunvis +function, +but it allows you to add a flag that specifies the style the string +.Ar src +is encoded with. +Currently, the only supported flag is +.Dv VIS_HTTPSTYLE . +.Pp +The .Fn unvis function implements a state machine that can be used to decode an arbitrary stream of bytes. @@ -132,6 +146,14 @@ one more time with flag set to .Dv UNVIS_END to extract any remaining character (the character passed in is ignored). .Pp +The +.Ar flag +argument is also used to specify the encoding style of the source. +If set to +.Dv VIS_HTTPSTYLE , +.Fn unvis +will decode URI strings as specified in RFC 1808. +.Pp The following code fragment illustrates a proper use of .Fn unvis . .Bd -literal -offset indent @@ -162,6 +184,11 @@ if (unvis(\*[Am]out, (char)0, \*[Am]state, UNVIS_END) == UNVIS_VALID) .Xr unvis 1 , .Xr vis 1 , .Xr vis 3 +.Rs +.%A R. Fielding +.%T Relative Uniform Resource Locators +.%O RFC1808 +.Re .Sh HISTORY The .Fn unvis diff --git a/lib/libc/gen/unvis.c b/lib/libc/gen/unvis.c index 4f2f526382e..747863b98f0 100644 --- a/lib/libc/gen/unvis.c +++ b/lib/libc/gen/unvis.c @@ -1,4 +1,4 @@ -/* $NetBSD: unvis.c,v 1.21 2002/01/31 22:43:38 tv Exp $ */ +/* $NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ /*- * Copyright (c) 1989, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: unvis.c,v 1.21 2002/01/31 22:43:38 tv Exp $"); +__RCSID("$NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -73,8 +73,11 @@ __warn_references(unvis, #define S_CTRL 4 /* control char started (^) */ #define S_OCTAL2 5 /* octal digit 2 */ #define S_OCTAL3 6 /* octal digit 3 */ +#define S_HEX1 7 /* hex digit */ +#define S_HEX2 8 /* hex digit 2 */ #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) int unvis(cp, c, astate, flag) @@ -99,7 +102,8 @@ __unvis13(cp, c, astate, flag) _DIAGASSERT(astate != NULL); if (flag & UNVIS_END) { - if (*astate == S_OCTAL2 || *astate == S_OCTAL3) { + if (*astate == S_OCTAL2 || *astate == S_OCTAL3 + || *astate == S_HEX2) { *astate = S_GROUND; return (UNVIS_VALID); } @@ -114,6 +118,10 @@ __unvis13(cp, c, astate, flag) *astate = S_START; return (0); } + if ((flag & VIS_HTTPSTYLE) && c == '%') { + *astate = S_HEX1; + return (0); + } *cp = c; return (UNVIS_VALID); @@ -236,7 +244,24 @@ __unvis13(cp, c, astate, flag) * we were done, push back passed char */ return (UNVIS_VALIDPUSH); - + case S_HEX1: + if (isxdigit(c)) { + *cp = xtod(c); + *astate = S_HEX2; + return (0); + } + /* + * no - done with current sequence, push back passed char + */ + *astate = S_GROUND; + return (UNVIS_VALIDPUSH); + case S_HEX2: + *astate = S_GROUND; + if (isxdigit(c)) { + *cp = xtod(c) | (*cp << 4); + return (UNVIS_VALID); + } + return (UNVIS_VALIDPUSH); default: /* * decoder in unknown state - (probably uninitialized) @@ -254,9 +279,10 @@ __unvis13(cp, c, astate, flag) */ int -strunvis(dst, src) +strunvisx(dst, src, flag) char *dst; const char *src; + int flag; { char c; char *start = dst; @@ -267,7 +293,7 @@ strunvis(dst, src) while ((c = *src++) != '\0') { again: - switch (__unvis13(dst, c, &state, 0)) { + switch (__unvis13(dst, c, &state, flag)) { case UNVIS_VALID: dst++; break; @@ -286,4 +312,12 @@ strunvis(dst, src) *dst = '\0'; return (dst - start); } + +int +strunvis(dst, src) + char *dst; + const char *src; +{ + return strunvisx(dst, src, 0); +} #endif diff --git a/lib/libc/gen/vis.3 b/lib/libc/gen/vis.3 index 5b845ab24e0..af88b6ce19f 100644 --- a/lib/libc/gen/vis.3 +++ b/lib/libc/gen/vis.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: vis.3,v 1.15 2002/02/07 07:00:18 ross Exp $ +.\" $NetBSD: vis.3,v 1.16 2002/03/23 17:38:27 christos Exp $ .\" .\" Copyright (c) 1989, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -205,11 +205,15 @@ warning on the use of the .Dv VIS_NOSLASH flag below). .Pp -There are three forms of encoding. +There are four forms of encoding. All forms use the backslash character .Ql \e to introduce a special -sequence; two backslashes are used to represent a real backslash. +sequence; two backslashes are used to represent a real backslash, +except +.Dv VIS_HTTPSTYLE +that uses +.Ql $ . These are the visual formats: .Bl -tag -width VIS_CSTYLE .It (default) @@ -293,6 +297,13 @@ Use a three digit octal sequence. The form is where .Em d represents an octal digit. +.It Dv VIS_HTTPSTYLE +Use URI encoding as described in RFC 1808. +The form is +.Ql %xx +where +.Em x +represents a hexadecimal digit. .El .Pp There is one additional flag, @@ -310,6 +321,11 @@ ambiguous and non-invertible. .Xr unvis 1 , .Xr vis 1 , .Xr unvis 3 +.Rs +.%A R. Fielding +.%T Relative Uniform Resource Locators +.%O RFC1808 +.Re .Sh HISTORY The .Fa vis , diff --git a/lib/libc/gen/vis.c b/lib/libc/gen/vis.c index 17a6625f5f3..9021147c8a7 100644 --- a/lib/libc/gen/vis.c +++ b/lib/libc/gen/vis.c @@ -1,4 +1,4 @@ -/* $NetBSD: vis.c,v 1.21 2002/01/31 22:43:39 tv Exp $ */ +/* $NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: vis.c,v 1.21 2002/01/31 22:43:39 tv Exp $"); +__RCSID("$NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -44,6 +44,7 @@ __RCSID("$NetBSD: vis.c,v 1.21 2002/01/31 22:43:39 tv Exp $"); #include <assert.h> #include <vis.h> +#include <stdlib.h> #ifdef __weak_alias __weak_alias(strsvis,_strsvis) @@ -70,20 +71,43 @@ __weak_alias(vis,_vis) #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define iswhite(c) (c == ' ' || c == '\t' || c == '\n') #define issafe(c) (c == '\b' || c == BELL || c == '\r') +#define xtoa(c) "0123456789abcdef"[c] #define MAXEXTRAS 5 -#define MAKEEXTRALIST(flag, extra) \ +#define MAKEEXTRALIST(flag, extra, orig) \ do { \ - char *pextra = extra; \ - if (flag & VIS_SP) *pextra++ = ' '; \ - if (flag & VIS_TAB) *pextra++ = '\t'; \ - if (flag & VIS_NL) *pextra++ = '\n'; \ - if ((flag & VIS_NOSLASH) == 0) *pextra++ = '\\'; \ - *pextra = '\0'; \ + const char *o = orig; \ + char *e; \ + while (*o++) \ + continue; \ + extra = alloca((size_t)((o - orig) + MAXEXTRAS)); \ + for (o = orig, e = extra; (*e++ = *o++) != '\0';) \ + continue; \ + e--; \ + if (flag & VIS_SP) *e++ = ' '; \ + if (flag & VIS_TAB) *e++ = '\t'; \ + if (flag & VIS_NL) *e++ = '\n'; \ + if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \ + *e = '\0'; \ } while (/*CONSTCOND*/0) + +/* + * This is HVIS, the macro of vis used to HTTP style (RFC 1808) + */ +#define HVIS(dst, c, flag, nextc, extra) \ +do \ + if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \ + *dst++ = '%'; \ + *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \ + *dst++ = xtoa((unsigned int)c & 0xf); \ + } else { \ + SVIS(dst, c, flag, nextc, extra); \ + } \ +while (/*CONSTCOND*/0) + /* * This is SVIS, the central macro of vis. * dst: Pointer to the destination buffer @@ -171,10 +195,14 @@ svis(dst, c, flag, nextc, extra) int c, flag, nextc; const char *extra; { + char *nextra; _DIAGASSERT(dst != NULL); _DIAGASSERT(extra != NULL); - - SVIS(dst, c, flag, nextc, extra); + MAKEEXTRALIST(flag, nextra, extra); + if (flag & VIS_HTTPSTYLE) + HVIS(dst, c, flag, nextc, nextra); + else + SVIS(dst, c, flag, nextc, nextra); *dst = '\0'; return(dst); } @@ -204,13 +232,19 @@ strsvis(dst, src, flag, extra) { char c; char *start; + char *nextra; _DIAGASSERT(dst != NULL); _DIAGASSERT(src != NULL); _DIAGASSERT(extra != NULL); - - for (start = dst; (c = *src++) != '\0'; /* empty */) - SVIS(dst, c, flag, *src, extra); + MAKEEXTRALIST(flag, nextra, extra); + if (flag & VIS_HTTPSTYLE) { + for (start = dst; (c = *src++) != '\0'; /* empty */) + HVIS(dst, c, flag, *src, nextra); + } else { + for (start = dst; (c = *src++) != '\0'; /* empty */) + SVIS(dst, c, flag, *src, nextra); + } *dst = '\0'; return (dst - start); } @@ -226,14 +260,23 @@ strsvisx(dst, src, len, flag, extra) { char c; char *start; + char *nextra; _DIAGASSERT(dst != NULL); _DIAGASSERT(src != NULL); _DIAGASSERT(extra != NULL); - - for (start = dst; len > 0; len--) { - c = *src++; - SVIS(dst, c, flag, len ? *src : '\0', extra); + MAKEEXTRALIST(flag, nextra, extra); + + if (flag & VIS_HTTPSTYLE) { + for (start = dst; len > 0; len--) { + c = *src++; + HVIS(dst, c, flag, len ? *src : '\0', nextra); + } + } else { + for (start = dst; len > 0; len--) { + c = *src++; + SVIS(dst, c, flag, len ? *src : '\0', nextra); + } } *dst = '\0'; return (dst - start); @@ -249,12 +292,15 @@ vis(dst, c, flag, nextc) int c, flag, nextc; { - char extra[MAXEXTRAS]; + char *extra; _DIAGASSERT(dst != NULL); - MAKEEXTRALIST(flag, extra); - SVIS(dst, c, flag, nextc, extra); + MAKEEXTRALIST(flag, extra, ""); + if (flag & VIS_HTTPSTYLE) + HVIS(dst, c, flag, nextc, extra); + else + SVIS(dst, c, flag, nextc, extra); *dst = '\0'; return (dst); } @@ -276,9 +322,9 @@ strvis(dst, src, flag) const char *src; int flag; { - char extra[MAXEXTRAS]; + char *extra; - MAKEEXTRALIST(flag, extra); + MAKEEXTRALIST(flag, extra, ""); return (strsvis(dst, src, flag, extra)); } @@ -290,9 +336,9 @@ strvisx(dst, src, len, flag) size_t len; int flag; { - char extra[MAXEXTRAS]; + char *extra; - MAKEEXTRALIST(flag, extra); + MAKEEXTRALIST(flag, extra, ""); return (strsvisx(dst, src, len, flag, extra)); } #endif |
