]> granicus.if.org Git - apache/commitdiff
mod_lua: backport the two parsebody fixes.
authorDaniel Gruno <humbedooh@apache.org>
Sun, 20 Apr 2014 14:02:22 +0000 (14:02 +0000)
committerDaniel Gruno <humbedooh@apache.org>
Sun, 20 Apr 2014 14:02:22 +0000 (14:02 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1588762 13f79535-47bb-0310-9956-ffa450edef68

modules/lua/lua_request.c

index 4201609eab6cc702c913970920c483c537485449..bd7ce0c0c2731fa620abde787616a51e1092e954 100644 (file)
@@ -227,7 +227,8 @@ static int req_aprtable2luatable_cb_len(void *l, const char *key,
     requests. Used for multipart POST data.
  =======================================================================================================================
  */
-static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size)
+static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size,
+        apr_off_t maxsize)
 {
     int rc = OK;
 
@@ -242,6 +243,9 @@ static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size)
         apr_off_t length = r->remaining;
         /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
+        if (maxsize != 0 && length > maxsize) {
+            return APR_EINCOMPLETE; /* Only room for incomplete data chunk :( */
+        }
         *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length + 1));
         *size = length;
         while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) {
@@ -313,6 +317,20 @@ static int req_parseargs(lua_State *L)
     return 2;                   /* [table<string, string>, table<string, array<string>>] */
 }
 
+/* ap_lua_binstrstr: Binary strstr function for uploaded data with NULL bytes */
+char* ap_lua_binstrstr (const char * haystack, size_t hsize, const char* needle, size_t nsize)
+{
+    if (haystack == NULL) return NULL;
+    if (needle == NULL) return NULL;
+    if (hsize < nsize) return NULL;
+    for (size_t p = 0; p <= (hsize - nsize); ++p) {
+        if (memcmp(haystack + p, needle, nsize) == 0) {
+            return (char*) (haystack + p);
+        }
+    }
+    return NULL;
+} 
+
 /* r:parsebody(): Parses regular (url-enocded) or multipart POST data and returns two tables*/
 static int req_parsebody(lua_State *L)
 {
@@ -336,7 +354,7 @@ static int req_parsebody(lua_State *L)
         int         i;
         size_t      vlen = 0;
         size_t      len = 0;
-        if (lua_read_body(r, &data, (apr_off_t*) &size) != OK) {
+        if (lua_read_body(r, &data, (apr_off_t*) &size, max_post_size) != OK) {
             return 2;
         }
         len = strlen(multipart);
@@ -344,15 +362,15 @@ static int req_parsebody(lua_State *L)
         for
         (
             start = strstr((char *) data, multipart);
-            start != start + size;
+            start != NULL;
             start = end
         ) {
             i++;
             if (i == POST_MAX_VARS) break;
-            end = strstr((char *) (start + 1), multipart);
-            if (!end) end = start + size;
             crlf = strstr((char *) start, "\r\n\r\n");
             if (!crlf) break;
+            end = ap_lua_binstrstr(crlf, (size - (crlf - data)), multipart, len);
+            if (end == NULL) break;
             key = (char *) apr_pcalloc(r->pool, 256);
             filename = (char *) apr_pcalloc(r->pool, 256);
             vlen = end - crlf - 8;