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, &copy[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;
        }
  
  
  

Reply via email to