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 | |
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
-rw-r--r-- | include/vis.h | 1 | ||||
-rw-r--r-- | lib/libc/gen/unvis.c | 57 | ||||
-rw-r--r-- | lib/libc/gen/vis.c | 17 |
3 files changed, 74 insertions, 1 deletions
diff --git a/include/vis.h b/include/vis.h index f3722d6..30bd58a 100644 --- a/include/vis.h +++ b/include/vis.h @@ -64,6 +64,7 @@ typedef _BSD_SIZE_T_ size_t; * other */ #define VIS_NOSLASH 0x40 /* inhibit printing '\' */ +#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ /* * unvis return codes 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); +} diff --git a/lib/libc/gen/vis.c b/lib/libc/gen/vis.c index 61aa836..cc3501d 100644 --- a/lib/libc/gen/vis.c +++ b/lib/libc/gen/vis.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) @@ -52,6 +54,21 @@ vis(dst, c, flag, nextc) register int flag; { c = (unsigned char)c; + + if (flag & VIS_HTTPSTYLE) { + if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z') || c == '$' || c == '-' + || c == '_' || c == '\'' || c == '+' || c == '!' || + c == '(' || c == ')' || c == ',' || c == '"' || + c == ';' || c == '/' || c == '?' || c == ':' || + c == '@' || c == '&' || c == '=' || c == '+')) { + *dst++ = '%'; + snprintf(dst, 4, (c < 16 ? "0%X" : "%X"), c); + dst += 2; + goto done; + } + } + if (isgraph(c) || ((flag & VIS_SP) == 0 && c == ' ') || ((flag & VIS_TAB) == 0 && c == '\t') || |