diff options
author | dan <dan@FreeBSD.org> | 2000-07-01 15:55:49 +0000 |
---|---|---|
committer | dan <dan@FreeBSD.org> | 2000-07-01 15:55:49 +0000 |
commit | 4b9cb06856c3e02a9d1f5b363f3240c2b55fb2a3 (patch) | |
tree | d4df74c657f56d379a1f991fbea89c018f213ed1 /lib/libc/gen/unvis.c | |
parent | 88ee2872aa59d6889ba9f704ed630fde0f581cbb (diff) | |
download | FreeBSD-src-4b9cb06856c3e02a9d1f5b363f3240c2b55fb2a3.zip FreeBSD-src-4b9cb06856c3e02a9d1f5b363f3240c2b55fb2a3.tar.gz |
Add URI encoding to the vis/unvis routines courtesy of VIS_HTTPSTYLE.
Since alex is a -doc committer, he can update his own manpage. :-)
Also add $FreeBSD$ while I'm here.
Submitted by: alex
Diffstat (limited to 'lib/libc/gen/unvis.c')
-rw-r--r-- | lib/libc/gen/unvis.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/lib/libc/gen/unvis.c b/lib/libc/gen/unvis.c index 32405df..a730692 100644 --- a/lib/libc/gen/unvis.c +++ b/lib/libc/gen/unvis.c @@ -29,6 +29,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ #if defined(LIBC_SCCS) && !defined(lint) @@ -48,8 +50,12 @@ static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; #define S_CTRL 4 /* control char started (^) */ #define S_OCTAL2 5 /* octal digit 2 */ #define S_OCTAL3 6 /* octal digit 3 */ +#define S_HEX2 7 /* hex digit 2 */ + +#define S_HTTP 0x080 /* %HEXHEX escape */ #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define ishex(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '9' || ((u_char)(c)) >= 'a' && ((u_char)(c)) <= 'f') /* * unvis - decode characters previously encoded by vis @@ -68,7 +74,7 @@ unvis(cp, c, astate, flag) return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); } - switch (*astate) { + switch (*astate & ~S_HTTP) { case S_GROUND: *cp = 0; @@ -76,10 +82,21 @@ unvis(cp, c, astate, flag) *astate = S_START; return (0); } + if (flag & VIS_HTTPSTYLE && c == '%') { + *astate = S_START | S_HTTP; + return (0); + } *cp = c; return (UNVIS_VALID); case S_START: + if (*astate & S_HTTP) { + if (ishex(tolower(c))) { + *cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a'); + *astate = S_HEX2; + return (0); + } + } switch(c) { case '\\': *cp = c; @@ -199,6 +216,13 @@ unvis(cp, c, astate, flag) */ return (UNVIS_VALIDPUSH); + case S_HEX2: /* second mandatory hex digit */ + if (ishex(tolower(c))) { + *cp = (isdigit(c) ? (*cp << 4) + (c - '0') : (*cp << 4) + (tolower(c) - 'a' + 10)); + } + *astate = S_GROUND; + return (UNVIS_VALID); + default: /* * decoder in unknown state - (probably uninitialized) @@ -245,3 +269,34 @@ strunvis(dst, src) *dst = '\0'; return (dst - start); } + +int +strunvisx(dst, src, flag) + register char *dst; + register const char *src; +{ + register char c; + char *start = dst; + int state = 0; + + while ( (c = *src++) ) { + again: + switch (unvis(dst, c, &state, flag)) { + case UNVIS_VALID: + dst++; + break; + case UNVIS_VALIDPUSH: + dst++; + goto again; + case 0: + case UNVIS_NOCHAR: + break; + default: + return (-1); + } + } + if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) + dst++; + *dst = '\0'; + return (dst - start); +} |