On Wednesday, December 1, 2010, Enlightenment SVN
<[email protected]> 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
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
>

-- 
Gustavo Sverzut Barbieri
http://profusion.mobi embedded systems
--------------------------------------
MSN: [email protected]
Skype: gsbarbieri
Mobile: +55 (19) 9225-2202

------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to