Sfoglia il codice sorgente

Added URLEncode methods

Thomas Davis 12 anni fa
parent
commit
acbe6db15f
5 ha cambiato i file con 95 aggiunte e 16 eliminazioni
  1. 1 0
      RELEASE_NOTES.md
  2. 44 2
      include/CivetServer.h
  3. 5 0
      include/civetweb.h
  4. 29 0
      src/CivetServer.cpp
  5. 16 14
      src/civetweb.c

+ 1 - 0
RELEASE_NOTES.md

@@ -4,6 +4,7 @@ Release Notes v1.4 (UNDER DEVELOPMENT)
 
 - Added CivetServer::getParam methods
 - Added CivetServer::urlDecode methods
+- Added CivetServer::urlEncode methods
 - Dealt with compiler warnings and some static analysis hits.
 - Added mg_get_var2() to parse repeated query variables
 - Externalized logging function cry() as mg_cry()

+ 44 - 2
include/CivetServer.h

@@ -223,7 +223,7 @@ public:
 
 
     /**
-     * urlDecode(const char *, int, std::string &, bool)
+     * urlDecode(const std::string &, std::string &, bool)
      *
      * @param src string to be decoded
      * @param dst destination string
@@ -237,7 +237,7 @@ public:
     }
 
     /**
-     * urlDecode(const char *, int, std::string &, bool)
+     * urlDecode(const char *, size_t, std::string &, bool)
      *
      * @param src buffer to be decoded
      * @param src_len length of buffer to be decoded
@@ -249,6 +249,48 @@ public:
      */
     static void urlDecode(const char *src, size_t src_len, std::string &dst, bool is_form_url_encoded=true);
 
+    /**
+     * urlDecode(const char *, std::string &, bool)
+     *
+     * @param src buffer to be decoded (0 terminated)
+     * @param dst destination string
+     * @is_form_url_encoded true if form url encoded
+     *       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 void urlDecode(const char *src, std::string &dst, bool is_form_url_encoded=true);
+
+    /**
+     * urlEncode(const std::string &, std::string &, bool)
+     *
+     * @param src buffer to be encoded
+     * @param dst destination string
+     * @append true if string should not be cleared before encoding.
+     */
+    static void urlEncode(const std::string &src, std::string &dst, bool append=false) {
+        urlEncode(src.c_str(), src.length(), dst, append);
+    }
+
+    /**
+     * urlEncode(const char *, size_t, std::string &, bool)
+     *
+     * @param src buffer to be encoded (0 terminated)
+     * @param dst destination string
+     * @append true if string should not be cleared before encoding.
+     */
+    static void urlEncode(const char *src, std::string &dst, bool append=false);
+
+    /**
+     * urlEncode(const char *, size_t, std::string &, bool)
+     *
+     * @param src buffer to be encoded
+     * @param src_len length of buffer to be decoded
+     * @param dst destination string
+     * @append true if string should not be cleared before encoding.
+     */
+    static void urlEncode(const char *src, size_t src_len, std::string &dst, bool append=false);
+
 protected:
 
     /**

+ 5 - 0
include/civetweb.h

@@ -409,6 +409,11 @@ const char *mg_version(void);
 int mg_url_decode(const char *src, int src_len, char *dst,
                   int dst_len, int is_form_url_encoded);
 
+// URL-encode input buffer into destination buffer.
+// returns the length of the resulting buffer or -1
+// is the buffer is too small.
+int mg_url_encode(const char *src, char *dst, size_t dst_len);
+
 // MD5 hash given strings.
 // Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
 // ASCIIz strings. When function returns, buf will contain human-readable

+ 29 - 0
src/CivetServer.cpp

@@ -172,6 +172,11 @@ const char* CivetServer::getHeader(struct mg_connection *conn, const std::string
 }
 
 void
+CivetServer::urlDecode(const char *src, std::string &dst, bool is_form_url_encoded) {
+    urlDecode(src, strlen(src), dst, is_form_url_encoded);
+}
+
+void
 CivetServer::urlDecode(const char *src, size_t src_len, std::string &dst, bool is_form_url_encoded) {
   int i, j, a, b;
 #define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
@@ -236,3 +241,27 @@ CivetServer::getParam(const char *data, size_t data_len, const char *name,
   return false;
 }
 
+void
+CivetServer::urlEncode(const char *src, std::string &dst, bool append) {
+    urlEncode(src, strlen(src), dst, append);
+}
+
+void
+CivetServer::urlEncode(const char *src, size_t src_len, std::string &dst, bool append) {
+  static const char *dont_escape = "._-$,;~()";
+  static const char *hex = "0123456789abcdef";
+
+  if (!append)
+      dst.clear();
+
+  for (; src_len > 0; src_len--) {
+    if (isalnum(*(const unsigned char *) src) ||
+        strchr(dont_escape, * (const unsigned char *) src) != NULL) {
+      dst.push_back(*src);
+    } else {
+      dst.push_back('%');
+      dst.push_back(hex[(* (const unsigned char *) src) >> 4]);
+      dst.push_back(hex[(* (const unsigned char *) src) & 0xf]);
+    }
+  }
+}

+ 16 - 14
src/civetweb.c

@@ -2435,26 +2435,28 @@ static SOCKET conn2(const char *host, int port, int use_ssl,
   return sock;
 }
 
-
-
-void mg_url_encode(const char *src, char *dst, size_t dst_len) {
+int mg_url_encode(const char *src, char *dst, size_t dst_len) {
   static const char *dont_escape = "._-$,;~()";
   static const char *hex = "0123456789abcdef";
+  char *pos = dst;
   const char *end = dst + dst_len - 1;
 
-  for (; *src != '\0' && dst < end; src++, dst++) {
+  for (; *src != '\0' && pos < end; src++, pos++) {
     if (isalnum(*(const unsigned char *) src) ||
         strchr(dont_escape, * (const unsigned char *) src) != NULL) {
-      *dst = *src;
-    } else if (dst + 2 < end) {
-      dst[0] = '%';
-      dst[1] = hex[(* (const unsigned char *) src) >> 4];
-      dst[2] = hex[(* (const unsigned char *) src) & 0xf];
-      dst += 2;
-    }
-  }
-
-  *dst = '\0';
+      *pos = *src;
+    } else if (pos + 2 < end) {
+      pos[0] = '%';
+      pos[1] = hex[(* (const unsigned char *) src) >> 4];
+      pos[2] = hex[(* (const unsigned char *) src) & 0xf];
+      pos += 2;
+	} else {
+		return -1;
+	}
+  }
+
+  *pos = '\0';
+  return (*src == '\0') ? (int)(pos - dst) : -1;
 }
 
 static void print_dir_entry(struct de *de) {