dgaudet 98/03/13 18:43:48
Modified: src CHANGES src/main http_main.c util.c Log: Another 1.5% -- this is the basics of the istable patch I posted a few times, but without the compile-time generated table. I still plan to do the compile-time generated table. I decided not to do it in ap_ since the table was really tied into functions in util.c. find_token() completely rewritten so that it doesn't chew up memory. Take out some dead code as well. Revision Changes Path 1.708 +2 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.707 retrieving revision 1.708 diff -u -r1.707 -r1.708 --- CHANGES 1998/03/14 00:33:44 1.707 +++ CHANGES 1998/03/14 02:43:42 1.708 @@ -1,5 +1,7 @@ Changes with Apache 1.3b6 + *) util.c cleanup and speedup. [Dean Gaudet] + *) API: Clarification, pstrndup() will always copy n bytes of the source and NUL terminate at the (n+1)st byte. [Dean Gaudet] 1.303 +4 -0 apache-1.3/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/http_main.c,v retrieving revision 1.302 retrieving revision 1.303 diff -u -r1.302 -r1.303 --- http_main.c 1998/03/13 23:44:44 1.302 +++ http_main.c 1998/03/14 02:43:45 1.303 @@ -2957,6 +2957,9 @@ } +/* DEAN WILL CLEAN THIS UP! */ +extern void util_init(void); + /* Some init code that's common between win32 and unix... well actually * some of it is #ifdef'd but was duplicated before anyhow. This stuff * is still a mess. @@ -2986,6 +2989,7 @@ pconf = permanent_pool; ptrans = make_sub_pool(pconf); + util_init(); util_uri_init(); pcommands = make_sub_pool(NULL); 1.100 +77 -57 apache-1.3/src/main/util.c Index: util.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/util.c,v retrieving revision 1.99 retrieving revision 1.100 diff -u -r1.99 -r1.100 --- util.c 1998/03/14 00:50:38 1.99 +++ util.c 1998/03/14 02:43:46 1.100 @@ -74,6 +74,54 @@ extern int fclose(FILE *); #endif +/* A bunch of functions in util.c scan strings looking for certain characters. + * To make that more efficient we encode a lookup table. + */ +#define T_ESCAPE_SHELL_CMD (0x01) +#define T_ESCAPE_PATH_SEGMENT (0x02) +#define T_OS_ESCAPE_PATH (0x04) +#define T_HTTP_TOKEN_STOP (0x08) + +static unsigned char test_char_table[256]; + +#define TEST_CHAR(c, f) (test_char_table[((unsigned char)(c)) & 0xff] & (f)) + +/* XXX: this should be compile-time initialized so that test_char_table can + * live in read-only memory and not require backing store across fork(). + */ +void util_init(void) +{ + unsigned c; + unsigned char flags; + + /* explicitly deal with NUL in case some strchr() do bogosity with it */ + test_char_table[0] = 0; + + for (c = 1; c < 256; ++c) { + flags = 0; + + /* escape_shell_cmd */ + if (strchr("&;`'\"|*?~<>^()[]{}$\\\n", c)) { + flags |= T_ESCAPE_SHELL_CMD; + } + + if (!isalnum(c) && !strchr("$-_.+!*'(),:@&=~", c)) { + flags |= T_ESCAPE_PATH_SEGMENT; + } + + if (!isalnum(c) && !strchr("$-_.+!*'(),:@&=/~", c)) { + flags |= T_OS_ESCAPE_PATH; + } + + /* these are the "tspecials" from RFC2068 */ + if (iscntrl(c) || strchr(" \t()<>@,;:\\/[]?={}", c)) { + flags |= T_HTTP_TOKEN_STOP; + } + + test_char_table[c] = flags; + } +} + API_VAR_EXPORT const char month_snames[12][4] = { @@ -944,60 +992,42 @@ return token; } -static char *tspecials = " \t()<>@,;:\\/[]?={}"; - -/* Next HTTP token from a header line. Warning --- destructive! - * Use only with a copy! - */ - -static char *next_token(char **toks) -{ - char *cp = *toks; - char *ret; - - while (*cp && (iscntrl(*cp) || strchr(tspecials, *cp))) { - if (*cp == '"') - while (*cp && (*cp != '"')) - ++cp; - else - ++cp; - } - - if (!*cp) - ret = NULL; - else { - ret = cp; - - while (*cp && !iscntrl(*cp) && !strchr(tspecials, *cp)) - ++cp; - - if (*cp) { - *toks = cp + 1; - *cp = '\0'; - } - else - *toks = cp; - } - - return ret; -} +/* find http tokens, see the definition of token from RFC2068 */ API_EXPORT(int) find_token(pool *p, const char *line, const char *tok) { - char *ltok; - char *lcopy; + const char *start_token; + const char *s; if (!line) return 0; - lcopy = pstrdup(p, line); - while ((ltok = next_token(&lcopy))) - if (!strcasecmp(ltok, tok)) + s = line; + for (;;) { + /* find start of token, skip all stop characters, note NUL + * isn't a token stop, so we don't need to test for it + */ + while (TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) { + ++s; + } + if (!*s) { + return 0; + } + start_token = s; + /* find end of the token */ + while (*s && !TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) { + ++s; + } + if (!strncasecmp(start_token, tok, s - start_token)) { return 1; - - return 0; + } + if (!*s) { + return 0; + } + } } + API_EXPORT(int) find_last_token(pool *p, const char *line, const char *tok) { int llen, tlen, lidx; @@ -1035,7 +1065,7 @@ } #endif - if (strchr("&;`'\"|*?~<>^()[]{}$\\\n", cmd[x])) { + if (TEST_CHAR(cmd[x], T_ESCAPE_SHELL_CMD)) { for (y = l + 1; y > x; y--) cmd[y] = cmd[y - 1]; l++; /* length has been increased */ @@ -1164,12 +1194,7 @@ for (x = 0, y = 0; segment[x]; x++, y++) { char c = segment[x]; -#ifndef CHARSET_EBCDIC - if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c > '9') -#else /* CHARSET_EBCDIC*/ - if (!isalnum(c) -#endif /*CHARSET_EBCDIC*/ - && !strchr("$-_.+!*'(),:@&=~", c)) { + if (TEST_CHAR(c, T_ESCAPE_PATH_SEGMENT)) { c2x(c, ©[y]); y += 2; } @@ -1196,12 +1221,7 @@ } for (; *path; ++path) { char c = *path; -#ifndef CHARSET_EBCDIC - if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c > '9') -#else /* CHARSET_EBCDIC*/ - if (!isalnum(c) -#endif /*CHARSET_EBCDIC*/ - && !strchr("$-_.+!*'(),:@&=/~", c)) { + if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) { c2x(c, s); s += 3; }