فهرست منبع

Changed signature of url_decode(): signalling on destination buffer overflow. mg_get_var() now does not require extra space for variable buffer

Sergey Lyubka 12 سال پیش
والد
کامیت
080cb2dd4b
2فایلهای تغییر یافته به همراه13 افزوده شده و 11 حذف شده
  1. 6 10
      mongoose.c
  2. 7 1
      test/unit_test.c

+ 6 - 10
mongoose.c

@@ -1614,10 +1614,9 @@ int mg_printf(struct mg_connection *conn, const char *fmt, ...) {
 // form-url-encoded data differs from URI encoding in a way that it
 // uses '+' as character for space, see RFC 1866 section 8.2.1
 // http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
-static size_t url_decode(const char *src, size_t src_len, char *dst,
-                         size_t dst_len, int is_form_url_encoded) {
-  size_t i, j;
-  int a, b;
+static int url_decode(const char *src, int src_len, char *dst,
+                      int dst_len, int is_form_url_encoded) {
+  int i, j, a, b;
 #define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
 
   for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
@@ -1637,7 +1636,7 @@ static size_t url_decode(const char *src, size_t src_len, char *dst,
 
   dst[j] = '\0'; // Null-terminate the destination
 
-  return j;
+  return i >= src_len ? j : -1;
 }
 
 // Scan given buffer and fetch the value of the given variable.
@@ -1679,9 +1678,7 @@ int mg_get_var(const char *buf, size_t buf_len, const char *name,
         assert(s >= p);
 
         // Decode variable into destination buffer
-        if ((size_t) (s - p) < dst_len) {
-          len = (int) url_decode(p, (size_t)(s - p), dst, dst_len, 1);
-        }
+        len = url_decode(p, (size_t)(s - p), dst, dst_len, 1);
         break;
       }
     }
@@ -4052,8 +4049,7 @@ static void handle_request(struct mg_connection *conn) {
     * ((char *) conn->request_info.query_string++) = '\0';
   }
   uri_len = (int) strlen(ri->uri);
-  url_decode(ri->uri, (size_t)uri_len, (char *) ri->uri,
-             (size_t) (uri_len + 1), 0);
+  url_decode(ri->uri, uri_len, (char *) ri->uri, uri_len + 1, 0);
   remove_double_dots_and_double_slashes((char *) ri->uri);
   convert_uri_to_file_name(conn, path, sizeof(path), &file);
   conn->throttle = set_throttle(conn->ctx->config[THROTTLE],

+ 7 - 1
test/unit_test.c

@@ -238,7 +238,11 @@ static void test_base64_encode(void) {
 }
 
 static void test_mg_get_var(void) {
-  static const char *post[] = {"a=1&&b=2&d&=&c=3%20&e=", NULL};
+  static const char *post[] = {
+    "a=1&&b=2&d&=&c=3%20&e=",
+    "q=&st=2012%2F11%2F13+17%3A05&et=&team_id=",
+    NULL
+  };
   char buf[20];
 
   ASSERT(mg_get_var(post[0], strlen(post[0]), "a", buf, sizeof(buf)) == 1);
@@ -255,6 +259,8 @@ static void test_mg_get_var(void) {
 
   ASSERT(mg_get_var(post[0], strlen(post[0]), "x", NULL, 10) == -2);
   ASSERT(mg_get_var(post[0], strlen(post[0]), "x", buf, 0) == -2);
+  ASSERT(mg_get_var(post[1], strlen(post[1]), "st", buf, 16) == -1);
+  ASSERT(mg_get_var(post[1], strlen(post[1]), "st", buf, 17) == 16);
 }
 
 static void test_set_throttle(void) {