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