From 9f682eb9e5bb46cee0200c851fded13e1d54b802 Mon Sep 17 00:00:00 2001 From: David Freese Date: Tue, 11 Aug 2015 15:53:41 -0500 Subject: [PATCH] mg var length * implement new mongoose function to read variable length --- src/custom/custom.cxx | 8 ++--- src/include/mongoose.h | 2 ++ src/utils/mongoose.c | 67 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/custom/custom.cxx b/src/custom/custom.cxx index e49942c..1e8e0c8 100644 --- a/src/custom/custom.cxx +++ b/src/custom/custom.cxx @@ -413,10 +413,6 @@ void refresh_txt_custom_msg(void *) // called by web server thread void get_html_vars(struct mg_connection *conn) { -static char buff[65536]; - - memset(buff, 0, sizeof(buff)); - size_t p; if (custom_select < 0) return; @@ -435,7 +431,11 @@ static char buff[65536]; if ((p = field.find(".")) != string::npos) field.erase(p); } + + int fld_len = mg_get_var_len(conn, field.c_str()); + char buff[fld_len + 1]; memset(buff, 0, sizeof(buff)); + mg_get_var(conn, field.c_str(), buff, sizeof(buff)); switch (name_values[n].id) { diff --git a/src/include/mongoose.h b/src/include/mongoose.h index 4d4c5e5..47bdcc3 100644 --- a/src/include/mongoose.h +++ b/src/include/mongoose.h @@ -92,6 +92,8 @@ const char *mg_get_header(const struct mg_connection *, const char *name); const char *mg_get_mime_type(const char *name, const char *default_mime_type); int mg_get_var(const struct mg_connection *conn, const char *var_name, char *buf, size_t buf_len); +int mg_get_var_len(const struct mg_connection *conn, const char *name); + int mg_parse_header(const char *hdr, const char *var_name, char *buf, size_t); int mg_parse_multipart(const char *buf, int buf_len, char *var_name, int var_name_len, diff --git a/src/utils/mongoose.c b/src/utils/mongoose.c index 114db75..7841537 100644 --- a/src/utils/mongoose.c +++ b/src/utils/mongoose.c @@ -4025,6 +4025,73 @@ int mg_get_var(const struct mg_connection *conn, const char *name, return len; } +int mg_url_decode_len(const char *src, int src_len) { + int i, j; + for (i = j = 0; i < src_len; i++, j++) { + if (src[i] == '%' && i < src_len - 2 && + isxdigit(* (const unsigned char *) (src + i + 1)) && + isxdigit(* (const unsigned char *) (src + i + 2))) { + i += 2; + } + } + return i >= src_len ? j : -1; +} + +int get_var_len(const char *data, size_t data_len, const char *name) +{ + const char *p, *e, *s; + size_t name_len; + int len; + + if (data == NULL || name == NULL || data_len == 0) + return -1; + + name_len = strlen(name); + e = data + data_len; + len = -1; + +// data is "var1=val1&var2=val2...". Find variable first + for (p = data; p + name_len < e; p++) { + if ((p == data || p[-1] == '&') && p[name_len] == '=' && + !mg_strncasecmp(name, p, name_len)) { + +// Point p to variable value + p += name_len + 1; + +// Point s to the end of the value + s = (const char *) memchr(p, '&', (size_t)(e - p)); + if (s == NULL) { + s = e; + } + assert(s >= p); + +// Decode variable into destination buffer + len = mg_url_decode_len(p, (size_t)(s - p)); + +// Redirect error code from -1 to -2 (destination buffer too small). + if (len == -1) { + len = -2; + } + break; + } + } + return len; +} + +int mg_get_var_len(const struct mg_connection *conn, const char *name) +{ + int len = get_var_len( + conn->query_string, + conn->query_string == NULL ? 0 : strlen(conn->query_string), + name); + if (len < 0) + len = get_var_len( + conn->content, + conn->content_len, + name); + return len; +} + static int get_line_len(const char *buf, int buf_len) { int len = 0; while (len < buf_len && buf[len] != '\n') len++;