Date: Thu, 22 Mar 2001 20:28:02 +0100 (CET) From: Cyrille Lefevre <clefevre@poboxes.com> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/26005: MIME quoted-printable encoding added to vis/unvis + bug fix Message-ID: <200103221928.f2MJS2I22918@gits.dyndns.org>
next in thread | raw e-mail | index | archive | help
>Number: 26005 >Category: bin >Synopsis: MIME quoted-printable encoding added to vis/unvis + bug fix >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu Mar 22 11:30:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: Cyrille Lefevre >Release: FreeBSD 4.3-BETA i386 >Organization: ACME >Environment: System: FreeBSD gits 4.3-BETA FreeBSD 4.3-BETA #18: Sat Mar 17 02:17:40 CET 2001 root@:/disk2/4.x-stable/src/sys/compile/CUSTOM i386 >Description: MIME quoted-printable encoding added to vis/unvis. this allow you to read quoted-printable messages through the mail interface using !unvis -q which may be somewhat usefull. the bug fix is in the S_START case of unvis where *cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a'); must be *cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a' + 10); also, added references to strunvisx in the unvis(3) manual page. the unvis(3) API has been change since characters from stdio are in and not char. following this rule, I get rid of all uneeded casts. I've checked all the source tree, unvis(3) is only used by unvis(1). new -h and -q flags added to unvis(1). well, I know that my english is very poor. so, the manual pages need to be reviewed. at least, the added parts. >How-To-Repeat: validation tests are : vis -q /bin/ls | unvis -q | cmp - /bin/ls vis -q /bin/ls | mimencode -u -q | cmp - /bin/ls mimencode -q /bin/ls | unvis -q | cmp - /bin/ls mimencode come from the metamail port. >Fix: Index: include/vis.h =================================================================== RCS file: /home/ncvs/src/include/vis.h,v retrieving revision 1.6.2.1 diff -u -r1.6.2.1 vis.h --- include/vis.h 2000/08/17 08:25:53 1.6.2.1 +++ include/vis.h 2001/03/21 23:39:51 @@ -47,24 +47,25 @@ /* * to select alternate encoding format */ -#define VIS_OCTAL 0x01 /* use octal \ddd format */ -#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */ +#define VIS_OCTAL 0x001 /* use octal \ddd format */ +#define VIS_CSTYLE 0x002 /* use \[nrft0..] where appropriate */ /* * to alter set of characters encoded (default is to encode all * non-graphic except space, tab, and newline). */ -#define VIS_SP 0x04 /* also encode space */ -#define VIS_TAB 0x08 /* also encode tab */ -#define VIS_NL 0x10 /* also encode newline */ +#define VIS_SP 0x004 /* also encode space */ +#define VIS_TAB 0x008 /* also encode tab */ +#define VIS_NL 0x010 /* also encode newline */ #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) -#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ +#define VIS_SAFE 0x020 /* only encode "unsafe" characters */ /* * other */ -#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ -#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ +#define VIS_NOSLASH 0x040 /* inhibit printing '\' */ +#define VIS_HTTPSTYLE 0x080 /* http-style escape % HEX HEX */ +#define VIS_QPSTYLE 0x100 /* quoted-printable-style escape = HEX HEX */ /* * unvis return codes @@ -86,8 +87,9 @@ char *vis __P((char *, int, int, int)); int strvis __P((char *, const char *, int)); int strvisx __P((char *, const char *, size_t, int)); +int unvis __P((int *, int, int *, int)); int strunvis __P((char *, const char *)); -int unvis __P((char *, int, int *, int)); +int strunvisx __P((char *, const char *, int)); __END_DECLS #endif /* !_VIS_H_ */ Index: usr.bin/vis/foldit.c =================================================================== RCS file: /home/ncvs/src/usr.bin/vis/foldit.c,v retrieving revision 1.4 diff -u -r1.4 foldit.c --- usr.bin/vis/foldit.c 1999/08/28 01:07:25 1.4 +++ usr.bin/vis/foldit.c 2001/03/21 04:19:54 @@ -40,7 +40,10 @@ #endif /* not lint */ #include <stdio.h> +#include <vis.h> +extern int eflags; + int foldit(chunk, col, max) char *chunk; @@ -54,24 +57,34 @@ again: cp = chunk; while (*cp) { - switch(*cp) { - case '\n': - case '\r': - col = 0; - break; - case '\t': - col = col + 8 &~ 07; - break; - case '\b': - col = col ? col - 1 : 0; - break; - default: - col++; - } - if (col > (max - 2)) { - printf("\\\n"); - col = 0; - goto again; + if (eflags & VIS_QPSTYLE) { + if (*cp == '\n') + col = 0; + else if (++col > (max - 2)) { + printf ("=\n"); + col = 0; + goto again; + } + } else { + switch(*cp) { + case '\n': + case '\r': + col = 0; + break; + case '\t': + col = col + 8 &~ 07; + break; + case '\b': + col = col ? col - 1 : 0; + break; + default: + col++; + } + if (col > (max - 2)) { + printf ("\\\n"); + col = 0; + goto again; + } } cp++; } Index: usr.bin/vis/vis.1 =================================================================== RCS file: /home/ncvs/src/usr.bin/vis/vis.1,v retrieving revision 1.6 diff -u -r1.6 vis.1 --- usr.bin/vis/vis.1 1999/08/28 01:07:25 1.6 +++ usr.bin/vis/vis.1 2001/03/22 02:31:39 @@ -40,7 +40,7 @@ .Nd display non-printable characters in a visual format .Sh SYNOPSIS .Nm -.Op Fl cbflnostw +.Op Fl cbfhlnoqstw .Op Fl F Ar foldwidth .Op Ar .Sh DESCRIPTION @@ -83,6 +83,12 @@ .It Fl f Same as .Fl F . +.It Fl h +Request a format which displays non-printable characters using URI +encoding sequences (%dd where dd is an hexadecimal number) as +described in RFC 2396. The +.Fl b +option is implied. .It Fl l Mark newlines with the visible sequence .Ql \e$ , @@ -106,6 +112,14 @@ .It Fl o Request a format which displays non-printable characters as an octal number, \eddd. +.It Fl q +Request a format which displays non-printable characters in MIME +quoted-printable sequences (=dd where dd is an hexadecimal number) as +described in RFC 2045. The +.Fl b +and +.Fl F 77 +options are implied. .It Fl s Only characters considered unsafe to send to a terminal are encoded. This flag allows backspace, bell, and carriage return in addition @@ -117,7 +131,24 @@ .El .Sh SEE ALSO .Xr unvis 1 , -.Xr vis 3 +.Xr vis 3 , +.Xr unvis 3 . +.Rs +.%T Multipurpose Internet Mail Extensions (MIME) Part One +.%R Format of Internet Message Bodies. +.%A N. Freed +.%A N. Borenstein +.%D November 1996 +.%O RFC2045 +.Re +.Rs +.%T Relative Uniform Resource Locators (URI) +.%R Generic Syntax +.%A T. Berners-Lee +.%A R. Fielding +.%D August 1998 +.%O RFC2396 +.Re .Sh HISTORY The .Nm Index: usr.bin/vis/vis.c =================================================================== RCS file: /home/ncvs/src/usr.bin/vis/vis.c,v retrieving revision 1.6 diff -u -r1.6 vis.c --- usr.bin/vis/vis.c 1999/08/28 01:07:25 1.6 +++ usr.bin/vis/vis.c 2001/03/22 03:48:21 @@ -67,7 +67,7 @@ (void) setlocale(LC_CTYPE, ""); - while ((ch = getopt(argc, argv, "nwctsobfF:ld")) != -1) + while ((ch = getopt(argc, argv, "nwchqtsobfF:ld")) != -1) switch((char)ch) { case 'n': none++; @@ -78,6 +78,12 @@ case 'c': eflags |= VIS_CSTYLE; break; + case 'h': + eflags |= VIS_HTTPSTYLE; + break; + case 'q': + eflags |= VIS_QPSTYLE; + break; case 't': eflags |= VIS_TAB; break; @@ -112,6 +118,11 @@ argc -= optind; argv += optind; + if (eflags & VIS_QPSTYLE) { + foldwidth = 77; + fold++; + } + if (*argv) while (*argv) { if ((fp=fopen(*argv, "r")) != NULL) @@ -125,14 +136,13 @@ exit(0); } - static void usage() { #ifdef DEBUG - fprintf(stderr, "usage: vis [-cbflnostwd] [-F foldwidth] [file ...]\n"); + fprintf(stderr, "usage: vis [-cbfhlnoqstwd] [-F foldwidth] [file ...]\n"); #else - fprintf(stderr, "usage: vis [-cbflnostw] [-F foldwidth] [file ...]\n"); + fprintf(stderr, "usage: vis [-cbfhlnoqstw] [-F foldwidth] [file ...]\n"); #endif exit(1); } @@ -156,7 +166,8 @@ if (c == '\\') *cp++ = '\\'; *cp = '\0'; - } else if (markeol && c == '\n') { + } else if (markeol && c == '\n' && + !(eflags & (VIS_HTTPSTYLE|VIS_QPSTYLE))) { cp = buff; if ((eflags & VIS_NOSLASH) == 0) *cp++ = '\\'; @@ -164,7 +175,7 @@ *cp++ = '\n'; *cp = '\0'; } else - (void) vis(buff, (char)c, eflags, (char)rachar); + (void) vis(buff, c, eflags, rachar); cp = buff; if (fold) { @@ -186,6 +197,11 @@ /* * terminate partial line with a hidden newline */ - if (fold && *(cp-1) != '\n') - printf("\\\n"); + if (fold && *(cp-1) != '\n') { + if (eflags & VIS_QPSTYLE) + putchar ('='); + else + putchar ('\\'); + putchar ('\n'); + } } Index: usr.bin/unvis/unvis.1 =================================================================== RCS file: /home/ncvs/src/usr.bin/unvis/unvis.1,v retrieving revision 1.5 diff -u -r1.5 unvis.1 --- usr.bin/unvis/unvis.1 1999/08/28 01:07:12 1.5 +++ usr.bin/unvis/unvis.1 2001/03/22 02:30:49 @@ -40,6 +40,7 @@ .Nd "revert a visual representation of data back to original form" .Sh SYNOPSIS .Nm +.Op Fl hq .Op Ar .Sh DESCRIPTION .Nm Unvis @@ -47,10 +48,36 @@ .Xr vis 1 . It reverts a visual representation of data back to its original form on standard output. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl h +Inputs are in URI encoded form (%dd where dd is an hexadecimal number) +as described in RFC 2396. +.It Fl q +Inputs are in MIME quoted-printable from (=dd where dd is an +hexadecimal number) as described in RFC 2045. +.El .Sh SEE ALSO .Xr vis 1 , .Xr unvis 3 , -.Xr vis 3 +.Xr vis 3 . +.Rs +.%T Multipurpose Internet Mail Extensions (MIME) Part One +.%R Format of Internet Message Bodies. +.%A N. Freed +.%A N. Borenstein +.%D November 1996 +.%O RFC2045 +.Re +.Rs +.%T Relative Uniform Resource Locators (URI) +.%R Generic Syntax +.%A T. Berners-Lee +.%A R. Fielding +.%D August 1998 +.%O RFC2396 +.Re .Sh HISTORY The .Nm Index: usr.bin/unvis/unvis.c =================================================================== RCS file: /home/ncvs/src/usr.bin/unvis/unvis.c,v retrieving revision 1.5 diff -u -r1.5 unvis.c --- usr.bin/unvis/unvis.c 1999/08/28 01:07:13 1.5 +++ usr.bin/unvis/unvis.c 2001/03/21 05:53:52 @@ -50,6 +50,8 @@ #include <unistd.h> #include <vis.h> +int eflags; + void process __P((FILE *, char *)); static void usage __P((void)); @@ -60,8 +62,14 @@ FILE *fp; int ch; - while ((ch = getopt(argc, argv, "")) != -1) + while ((ch = getopt(argc, argv, "hq")) != -1) switch((char)ch) { + case 'h': + eflags |= VIS_HTTPSTYLE; + break; + case 'q': + eflags |= VIS_QPSTYLE; + break; case '?': default: usage(); @@ -85,7 +93,7 @@ static void usage() { - fprintf(stderr, "usage: unvis [file ...]\n"); + fprintf(stderr, "usage: unvis [-hq] [file ...]\n"); exit(1); } @@ -96,12 +104,12 @@ { register int offset = 0, c, ret; int state = 0; - char outc; + int outc; while ((c = getc(fp)) != EOF) { offset++; again: - switch(ret = unvis(&outc, (char)c, &state, 0)) { + switch(ret = unvis(&outc, c, &state, eflags)) { case UNVIS_VALID: putchar(outc); break; @@ -119,6 +127,6 @@ errx(1, "bad return value (%d), can't happen", ret); } } - if (unvis(&outc, (char)0, &state, UNVIS_END) == UNVIS_VALID) + if (unvis(&outc, 0, &state, UNVIS_END) == UNVIS_VALID) putchar(outc); } Index: lib/libc/gen/unvis.3 =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/unvis.3,v retrieving revision 1.6.2.3 diff -u -r1.6.2.3 unvis.3 --- lib/libc/gen/unvis.3 2000/12/29 14:44:45 1.6.2.3 +++ lib/libc/gen/unvis.3 2001/03/22 02:29:27 @@ -47,32 +47,45 @@ .Fn unvis "char *cp" "int c" "int *astate" "int flag" .Ft int .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 .Xr vis 3 function, back into -the original form. Unvis is called with successive characters in +the original form. The +.Fn unvis +function is called with successive characters in .Ar c until a valid sequence is recognized, at which time the decoded character is available at the character pointed to by .Ar cp . -Strunvis decodes the +The +.Fn strunvis +function decodes the characters pointed to by .Ar src into the buffer pointed to by .Ar dst . +The +.Fa flag +parameter is used for altering the default range of +characters considered for decoding. .Pp The .Fn strunvis -function -simply copies +and +.Fn strunvisx +functions +simply copy .Ar src to .Ar dst , @@ -124,9 +137,30 @@ unknown state. The decoder is placed into the starting state. .El .Pp +Two forms of encoding style need to be specified to be recognized. +Those forms are : +.Bl -tag -width VIS_HTTPSTYLE +.It Dv VIS_HTTPSTYLE +Interpret URI encoded sequences as described in RFC 2396. +Encoded values have the form +.Ql %dd +where +.Em d +represents an hexadecimal digit. +.It Dv VIS_QPSTYLE +Interpret MIME quoted-printable sequences as described in RFC 2045. +Encoded values have the form +.Ql =dd +where +.Em d +represents an hexadecimal digit. +.El +.Pp When all bytes in the stream have been processed, call .Fn unvis -one more time with flag set to +one more time with +.Fa flag +set to .Dv UNVIS_END to extract any remaining character (the character passed in is ignored). .Pp @@ -157,7 +191,26 @@ (void) putchar(out); .Ed .Sh SEE ALSO -.Xr vis 1 +.Xr unvis 1 , +.Xr vis 1 , +.Xr strvis 3 , +.Xr vis 3 . +.Rs +.%T Multipurpose Internet Mail Extensions (MIME) Part One +.%R Format of Internet Message Bodies. +.%A N. Freed +.%A N. Borenstein +.%D November 1996 +.%O RFC2045 +.Re +.Rs +.%T Relative Uniform Resource Locators (URI) +.%R Generic Syntax +.%A T. Berners-Lee +.%A R. Fielding +.%D August 1998 +.%O RFC2396 +.Re .Sh HISTORY The .Fn unvis Index: lib/libc/gen/unvis.c =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/unvis.c,v retrieving revision 1.4.8.1 diff -u -r1.4.8.1 unvis.c --- lib/libc/gen/unvis.c 2000/08/17 08:25:54 1.4.8.1 +++ lib/libc/gen/unvis.c 2001/03/22 18:41:49 @@ -38,6 +38,7 @@ #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> +#include <stdio.h> #include <vis.h> /* @@ -53,19 +54,18 @@ #define S_HEX2 7 /* hex digit 2 */ #define S_HTTP 0x080 /* %HEXHEX escape */ +#define S_QP 0x100 /* =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') +#define isoctal(c) ((c) >= '0' && (c) <= '7') +#define ishex(c) ((c) >= '0' && (c) <= '9' || (c) >= 'a' && (c) <= 'f') /* * unvis - decode characters previously encoded by vis */ int unvis(cp, c, astate, flag) - char *cp; - int c, *astate, flag; + int *cp, c, *astate, flag; { - if (flag & UNVIS_END) { if (*astate == S_OCTAL2 || *astate == S_OCTAL3) { *astate = S_GROUND; @@ -74,15 +74,19 @@ return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); } - switch (*astate & ~S_HTTP) { + switch (*astate & ~(S_HTTP|S_QP)) { case S_GROUND: *cp = 0; - if (c == '\\') { + if (c == '\\' && !(flag & VIS_QPSTYLE)) { *astate = S_START; return (0); + } + if (c == '=' && (flag & VIS_QPSTYLE)) { + *astate = S_START | S_QP; + return (0); } - if (flag & VIS_HTTPSTYLE && c == '%') { + if (c == '%' && (flag & VIS_HTTPSTYLE)) { *astate = S_START | S_HTTP; return (0); } @@ -90,9 +94,9 @@ return (UNVIS_VALID); case S_START: - if (*astate & S_HTTP) { + if (*astate & (S_HTTP|S_QP)) { if (ishex(tolower(c))) { - *cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a'); + *cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a' + 10); *astate = S_HEX2; return (0); } @@ -218,7 +222,8 @@ case S_HEX2: /* second mandatory hex digit */ if (ishex(tolower(c))) { - *cp = (isdigit(c) ? (*cp << 4) + (c - '0') : (*cp << 4) + (tolower(c) - 'a' + 10)); + *cp = (*cp << 4) + (isdigit(c) ? + (c - '0') : (tolower(c) - 'a' + 10)); } *astate = S_GROUND; return (UNVIS_VALID); @@ -244,18 +249,19 @@ register char *dst; register const char *src; { - register char c; + register int c; + int tc; char *start = dst; int state = 0; while ( (c = *src++) ) { again: - switch (unvis(dst, c, &state, 0)) { + switch (unvis(&tc, c, &state, 0)) { case UNVIS_VALID: - dst++; + *dst++ = tc; break; case UNVIS_VALIDPUSH: - dst++; + *dst++ = tc; goto again; case 0: case UNVIS_NOCHAR: @@ -264,8 +270,8 @@ return (-1); } } - if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) - dst++; + if (unvis(&tc, c, &state, UNVIS_END) == UNVIS_VALID) + *dst++ = tc; *dst = '\0'; return (dst - start); } @@ -274,19 +280,21 @@ strunvisx(dst, src, flag) register char *dst; register const char *src; + int flag; { - register char c; + register int c; + int tc; char *start = dst; int state = 0; while ( (c = *src++) ) { again: - switch (unvis(dst, c, &state, flag)) { + switch (unvis(&tc, c, &state, flag)) { case UNVIS_VALID: - dst++; + *dst++ = tc; break; case UNVIS_VALIDPUSH: - dst++; + *dst++ = tc; goto again; case 0: case UNVIS_NOCHAR: @@ -295,8 +303,8 @@ return (-1); } } - if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) - dst++; + if (unvis(&tc, c, &state, UNVIS_END) == UNVIS_VALID) + *dst++ = tc; *dst = '\0'; return (dst - start); } Index: lib/libc/gen/vis.3 =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/vis.3,v retrieving revision 1.8.2.4 diff -u -r1.8.2.4 vis.3 --- lib/libc/gen/vis.3 2001/03/06 16:45:55 1.8.2.4 +++ lib/libc/gen/vis.3 2001/03/22 02:24:03 @@ -67,7 +67,9 @@ encoding a set of characters into a buffer, the size of the buffer should be four times the number of characters encoded, plus one for the trailing .Dv NUL . -The flag parameter is used for altering the default range of +The +.Fa flag +parameter is used for altering the default range of characters considered for encoding and for altering the visual representation. The additional character, @@ -132,8 +134,7 @@ except space, tab, and newline are encoded. (See .Xr isgraph 3 . ) -The following flags -alter this: +The following flags alter this: .Bl -tag -width VIS_WHITEX .It Dv VIS_SP Also encode space. @@ -239,12 +240,19 @@ is an octal digit, the latter representation is used to avoid ambiguity. .It Dv VIS_HTTPSTYLE -Use URI encoding as described in RFC 1808. +Use URI encoding as described in RFC 2396. The form is .Ql %dd where +.Em d +represents an hexadecimal digit. +.It Dv VIS_QPSTYLE +Use MIME quoted-printable encoding as described in RFC 2045. +The form is +.Ql =dd +where .Em d -represents a hexadecimal digit. +represents an hexadecimal digit. .It Dv VIS_OCTAL Use a three digit octal sequence. The form is .Ql \eddd @@ -253,6 +261,13 @@ represents an octal digit. .El .Pp +If more than one style is specified, precedences are as follow : +.Dv VIS_QPSTYLE , +.Dv VIS_HTTPSTYLE , +.Dv VIS_CSTYLE , +.Dv VIS_OCTAL , +.Dv (default) . +.Pp There is one additional flag, .Dv VIS_NOSLASH , which inhibits the @@ -263,15 +278,33 @@ meta characters as .Ql M-C ) . With this flag set, the encoding is -ambiguous and non-invertible. +ambiguous and non-invertible. The +.Dv VIS_NOSLASH +flag is implied by +.Dv VIS_HTTPSTYLE +or +.Dv VIS_QPSTYLE +styles. .Sh SEE ALSO +.Xr vis 1 , .Xr unvis 1 , .Xr strunvis 3 , -.Xr unvis 3 +.Xr unvis 3 . +.Rs +.%T Multipurpose Internet Mail Extensions (MIME) Part One +.%R Format of Internet Message Bodies. +.%A N. Freed +.%A N. Borenstein +.%D November 1996 +.%O RFC2045 +.Re .Rs +.%T Relative Uniform Resource Locators (URI) +.%R Generic Syntax +.%A T. Berners-Lee .%A R. Fielding -.%T Relative Uniform Resource Locators -.%O RFC1808 +.%D August 1998 +.%O RFC2396 .Re .Sh HISTORY These functions first appeared in Index: lib/libc/gen/vis.c =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/vis.c,v retrieving revision 1.5.8.2 diff -u -r1.5.8.2 vis.c --- lib/libc/gen/vis.c 2001/03/05 09:44:34 1.5.8.2 +++ lib/libc/gen/vis.c 2001/03/22 18:42:22 @@ -54,33 +54,84 @@ int c, nextc; register int flag; { - c = (unsigned char)c; + static int lastc = EOF; + if (flag & VIS_QPSTYLE) { + /* Described in RFC 2045 */ + if (c == '\n') { + if (isascii(lastc) && isblank(lastc)) { + *dst++ = '='; + *dst++ = c; + } + *dst++ = c; + goto done; + } + if (c == '=' || !(isascii(c) && (isgraph(c) || isblank(c)))) { + *dst++ = '='; + snprintf(dst, 4, "%02X", c); + dst += 2; + goto done; + } + } + if (flag & VIS_HTTPSTYLE) { - /* Described in RFC 1808 */ - if (!(isalnum(c) /* alpha-numeric */ + if (!( +#define RFC 0 +#if RFC == 2396 + isalnum(c) /* alpha-numeric */ + /* reserved */ + || c == ';' || c == '/' || c == '?' || c == ':' + || c == '@' || c == '&' || c == '=' || c == '+' + || c == '$' || c == ',' + /* mark */ + || c == '-' || c == '_' || c == '.' || c == '!' + || c == '~' || c == '*' || c == '\'' || c == '(' + || c == ')' + /* delims / + || c == '<' || c == '>' || c == '#' || c == '%' + || c == '"' + /* unwise */ + || c == '{' || c == '}' || c == '|' || c == '\\' + || c == '^' || c == '[' || c == ']' || c == '`' +#elif RFC == 1808 /* obsoleted by RFC2396 */ + !(isalnum(c) /* alpha-numeric */ /* safe */ - || c == '$' || c == '-' || c == '_' || c == '.' || c == '+' + || c == '$' || c == '-' || c == '_' || c == '.' + || c == '+' /* extra */ || c == '!' || c == '*' || c == '\'' || c == '(' - || c == ')' || c == ',')) { + || c == ')' || c == ',' + /* national */ + || c == '{' || c == '}' || c == '|' || c == '\\' + || c == '^' || c == '~' || c == '[' || c == ']' + || c == '`' + /* reserved */ + || c == ';' || c == '/' || c == '?' || c == ':' + || c == '@' || c == '&' || c == '=' + /* punctuation */ + || c == '<' || c == '>' || c == '#' || c == '%' + || c == '"' +#else /* same as above, but faster. */ + isgraph(c) && isascii(c) +#endif + )) { *dst++ = '%'; - snprintf(dst, 4, (c < 16 ? "0%X" : "%X"), c); + snprintf(dst, 4, "%02X", c); dst += 2; goto done; } } if (isgraph(c) || - ((flag & VIS_SP) == 0 && c == ' ') || - ((flag & VIS_TAB) == 0 && c == '\t') || - ((flag & VIS_NL) == 0 && c == '\n') || - ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) { + (c == ' ' && !(flag & VIS_SP)) || + (c == '\t' && !(flag & VIS_TAB)) || + (c == '\n' && !(flag & VIS_NL)) || + ((c == '\b' || c == '\007' || c == '\r')) && (flag & VIS_SAFE)) { *dst++ = c; - if (c == '\\' && (flag & VIS_NOSLASH) == 0) + if (c == '\\' && + !(flag & (VIS_NOSLASH|VIS_QPSTYLE|VIS_HTTPSTYLE))) *dst++ = '\\'; - *dst = '\0'; - return (dst); + goto done; } if (flag & VIS_CSTYLE) { @@ -133,9 +184,9 @@ } if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) { *dst++ = '\\'; - *dst++ = ((u_char)c >> 6 & 07) + '0'; - *dst++ = ((u_char)c >> 3 & 07) + '0'; - *dst++ = ((u_char)c & 07) + '0'; + *dst++ = (c >> 6 & 07) + '0'; + *dst++ = (c >> 3 & 07) + '0'; + *dst++ = (c & 07) + '0'; goto done; } if ((flag & VIS_NOSLASH) == 0) @@ -155,6 +206,7 @@ *dst++ = c; } done: + lastc = c; *dst = '\0'; return (dst); } @@ -175,10 +227,10 @@ register const char *src; int flag; { - register char c; - char *start; + register int c; + char *start = dst; - for (start = dst; (c = *src); ) + while ( (c = *src) ) dst = vis(dst, c, flag, *++src); *dst = '\0'; return (dst - start); @@ -191,15 +243,15 @@ register size_t len; int flag; { - int c; - char *start; + register int c; + char *start = dst; - for (start = dst; len > 1; len--) { + while (len-- > 1) { c = *src; dst = vis(dst, c, flag, *++src); } - if (len) - dst = vis(dst, *src, flag, '\0'); + if (len > 0) + dst = vis(dst, *src, flag, 0); *dst = '\0'; return (dst - start); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103221928.f2MJS2I22918>