On Wed, 1 Dec 2010 05:22:20 -0200
Gustavo Sverzut Barbieri <barbi...@profusion.mobi> wrote:

> On Wednesday, December 1, 2010, Enlightenment SVN
> <no-re...@enlightenment.org> wrote:
> > Log:
> > add custom parser for headers, avoiding regexec and reducing stack size by
> > not using alloca to convert unsigned char* to char* for regexec
> 
> This approach is not the best, instead of calling couple of "dumb"
> checker functions change them to return offsets so you avoid
> repetitive lookups in the buffer and know for sure where things are
> and where to jump or how much to skip.
> 
> That includes no memchr() as well, just do it with stripping of spaces
> all together, keep pointers and call eina_stringshare_add_length()
> with base pointer and end-base difference.
> 
> For http header validation (getting numbers) you can also use strtol()
> which does similar handling and gives you the pointer to first
> non-number char
> 
> 
> >
> >
> > Author:       discomfitor
> > Date:         2010-11-30 21:28:13 -0800 (Tue, 30 Nov 2010)
> > New Revision: 55111
> > Trac:         http://trac.enlightenment.org/e/changeset/55111
> >
> > Modified:
> >   trunk/PROTO/azy/src/lib/azy_events.c
> >
> > Modified: trunk/PROTO/azy/src/lib/azy_events.c
> > ===================================================================
> > --- trunk/PROTO/azy/src/lib/azy_events.c        2010-12-01 04:43:58 UTC
> > (rev 55110) +++ trunk/PROTO/azy/src/lib/azy_events.c        2010-12-01
> > 05:28:13 UTC (rev 55111) @@ -24,17 +24,43 @@
> >  static char _init = 0;
> >  static regex_t __response;
> >  static regex_t request;
> > -static regex_t a_header;
> >
> >  static void
> >  _azy_events_init(void)
> >  {
> >     regcomp(&request, "^(GET|HEAD|POST|PUT) ([^ @\\]+) HTTP/1\\.([0-1])$",
> > REG_EXTENDED);
> > -   regcomp(&a_header, "^([a-zA-Z-]+): ([[:alnum:][:punct:] ]+)",
> > REG_EXTENDED); regcomp(&__response, "^HTTP/1\\.([0-1]) ([0-9]{3}) (.+)$",
> > REG_EXTENDED); _init = 1;
> >  }
> >
> > +static Eina_Bool
> > +_azy_events_valid_header_name(const char *name, unsigned int len)
> > +{
> > +   while (len--)
> > +     {
> > +        if ((!isalnum(*name)) && (*name != '-'))
> > +          return EINA_FALSE;
> > +
> > +        name++;
> > +     }
> > +
> > +   return EINA_TRUE;
> > +}
> > +
> > +static Eina_Bool
> > +_azy_events_valid_header_value(const char *name, unsigned int len)
> > +{
> > +   while (len--)
> > +     {
> > +        if (!isprint(*name))
> > +          return EINA_FALSE;
> > +
> > +        name++;
> > +     }
> > +
> > +   return EINA_TRUE;
> > +}
> > +
> >  int
> >  azy_events_type_parse(Azy_Net            *net,
> >                         int                  type,
> > @@ -151,7 +177,6 @@
> >                           size_t         event_len,
> >                           int            offset)
> >  {
> > -   regmatch_t match[3];
> >     unsigned char *c = NULL, *r = NULL, *p = NULL, *start = NULL,
> > *buf_start = NULL; unsigned char *data = (event_data) ? event_data +
> > offset : NULL; size_t len = (event_len) ? event_len - offset : 0;
> > @@ -267,27 +292,36 @@
> >     line_len = r - p;
> >     while (len && c && r)
> >       {
> > -        char *ptr;
> > +        const unsigned char *ptr, *semi;
> >
> >          if (line_len > 4096)
> >            {
> >               WARN("Ignoring unreasonably large header starting with:\n
> > %.32s\n", p); goto skip_header;
> >            }
> > -        ptr = alloca(line_len + 1);
> > -        memcpy(ptr, p, line_len);
> > -        ptr[line_len] = '\0';
> > -        if (!regexec(&a_header, ptr, 3, match, 0))
> > -          {
> > -             char *key, *value;
> > +        semi = memchr(p, ':', line_len);
> > +        if ((!semi) || (semi - p + 1 >= line_len))
> > +          goto skip_header;
> > +        if (!_azy_events_valid_header_name((const char*)p, semi - p))
> > +          goto skip_header;
> >
> > -             key = strndupa(ptr + match[1].rm_so, match[1].rm_eo -
> > match[1].rm_so);
> > -             value = strndupa(ptr + match[2].rm_so, match[2].rm_eo -
> > match[2].rm_so);
> > -             INFO("Found header: key='%s'", key);
> > -             INFO("Found header: value='%s'", value);
> > -             azy_net_header_set(net, key, value);
> > -          }
> > +        ptr = semi + 1;
> > +        while ((isspace(*ptr)) && (ptr - p < line_len))
> > +          ptr++;
> >
> > +        if (!_azy_events_valid_header_value((const char*)ptr, line_len -
> > (ptr - p)))
> > +          goto skip_header;
> > +        {
> > +           char *key, *value;
> > +
> > +           key = strndupa((const char*)p, semi - p);
> > +           value = strndupa((const char*)ptr, line_len - (ptr - p));
> > +           INFO("Found header: key='%s'", key);
> > +           INFO("Found header: value='%s'", value);
> > +           azy_net_header_set(net, key, value);
> > +        }
> > +
> > +
> >  skip_header:
> >          len -= line_len + slen;
> >          if (len < slen)
> >
> >
> > ------------------------------------------------------------------------------
> > Increase Visibility of Your 3D Game App & Earn a Chance To Win $500!
> > Tap into the largest installed PC base & get more eyes on your game by
> > optimizing for Intel(R) Graphics Technology. Get started today with the
> > Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs.
> > http://p.sf.net/sfu/intelisp-dev2dev
> > _______________________________________________
> > enlightenment-svn mailing list
> > enlightenment-...@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
> >
> 
I'm currently in the process of reworking most/all of the parsing code here.
Thanks for the tip!

-- 
Mike Blumenkrantz
Zentific: Our boolean values are huge.

------------------------------------------------------------------------------
Increase Visibility of Your 3D Game App & Earn a Chance To Win $500!
Tap into the largest installed PC base & get more eyes on your game by
optimizing for Intel(R) Graphics Technology. Get started today with the
Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs.
http://p.sf.net/sfu/intelisp-dev2dev
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to