about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-02-18 18:53:03 -0800
committerEric Wong <normalperson@yhbt.net>2010-02-18 19:30:51 -0800
commitace625cfb1aa1b3c2f06890fb1f97900059bf226 (patch)
tree7102ee0510ef6a931e0122c4cbf35c6f2077a64a
parent4ee6275918cf15c1c380e0adc46e2516433d76fa (diff)
downloadunicorn-ace625cfb1aa1b3c2f06890fb1f97900059bf226.tar.gz
Not fun, but maybe this can help us spot _real_ problems
more easily in the future.
-rw-r--r--TODO2
-rw-r--r--ext/unicorn_http/c_util.h13
-rw-r--r--ext/unicorn_http/unicorn_http.rl10
3 files changed, 18 insertions, 7 deletions
diff --git a/TODO b/TODO
index eed9422..f7a14f9 100644
--- a/TODO
+++ b/TODO
@@ -3,8 +3,6 @@
 * ensure test suite passes on non-GNU/Linux, non-FreeBSD systems
   (likely that it already does)
 
-* fix const-correctness in HTTP parser
-
 * performance validation (esp. TeeInput)
 
 * improve test suite (steal from Rainbows!, probably...)
diff --git a/ext/unicorn_http/c_util.h b/ext/unicorn_http/c_util.h
index 9e674fa..8542b3d 100644
--- a/ext/unicorn_http/c_util.h
+++ b/ext/unicorn_http/c_util.h
@@ -30,6 +30,19 @@
 #endif /* SIZEOF_OFF_T check */
 
 /*
+ * ragel enforces fpc as a const, and merely casting can make picky
+ * compilers unhappy, so we have this little helper do our dirty work
+ */
+static inline void *deconst(const void *in)
+{
+  union { const void *in; void *out; } tmp;
+
+  tmp.in = in;
+
+  return tmp.out;
+}
+
+/*
  * capitalizes all lower-case ASCII characters and converts dashes
  * to underscores for HTTP headers.  Locale-agnostic.
  */
diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
index 0c58473..f0b602b 100644
--- a/ext/unicorn_http/unicorn_http.rl
+++ b/ext/unicorn_http/unicorn_http.rl
@@ -136,7 +136,7 @@ static inline void hp_invalid_if_trailer(struct http_parser *hp)
 }
 
 static void write_cont_value(struct http_parser *hp,
-                             const char *buffer, const char *p)
+                             char *buffer, const char *p)
 {
   char *vptr;
 
@@ -154,7 +154,7 @@ static void write_cont_value(struct http_parser *hp,
   if (RSTRING_LEN(hp->cont) > 0)
     --hp->mark;
 
-  vptr = (char *)PTR_TO(mark);
+  vptr = PTR_TO(mark);
 
   if (RSTRING_LEN(hp->cont) > 0) {
     assert((' ' == *vptr || '\t' == *vptr) && "invalid leading white space");
@@ -220,8 +220,8 @@ static void write_value(VALUE req, struct http_parser *hp,
   action mark {MARK(mark, fpc); }
 
   action start_field { MARK(start.field, fpc); }
-  action snake_upcase_field { snake_upcase_char((char *)fpc); }
-  action downcase_char { downcase_char((char *)fpc); }
+  action snake_upcase_field { snake_upcase_char(deconst(fpc)); }
+  action downcase_char { downcase_char(deconst(fpc)); }
   action write_field { hp->s.field_len = LEN(start.field, fpc); }
   action start_value { MARK(mark, fpc); }
   action write_value { write_value(req, hp, buffer, fpc); }
@@ -344,7 +344,7 @@ static void http_parser_init(struct http_parser *hp)
 
 /** exec **/
 static void http_parser_execute(struct http_parser *hp,
-  VALUE req, const char *buffer, size_t len)
+  VALUE req, char *buffer, size_t len)
 {
   const char *p, *pe;
   int cs = hp->cs;