Commit 961fb96b authored by Бобби's avatar Бобби Committed by Cesanta Bot

Fix OOB access in mg_match_prefix_n()

CL: Fix OOB access in mg_match_prefix_n().
    Made mg_match_prefix_n() return non-negative result.

PUBLISHED_FROM=611454df6a6c55bfa7ddf05e7d268a86fa0457a8
parent d6475fcd
...@@ -612,8 +612,8 @@ int cs_log_print_prefix(enum cs_log_level level, const char *func, ...@@ -612,8 +612,8 @@ int cs_log_print_prefix(enum cs_log_level level, const char *func,
if (level > cs_log_threshold) return 0; if (level > cs_log_threshold) return 0;
if (s_filter_pattern != NULL && if (s_filter_pattern != NULL &&
mg_match_prefix(s_filter_pattern, s_filter_pattern_len, func) < 0 && mg_match_prefix(s_filter_pattern, s_filter_pattern_len, func) == 0 &&
mg_match_prefix(s_filter_pattern, s_filter_pattern_len, filename) < 0) { mg_match_prefix(s_filter_pattern, s_filter_pattern_len, filename) == 0) {
return 0; return 0;
} }
...@@ -1632,9 +1632,9 @@ const char *mg_strstr(const struct mg_str haystack, ...@@ -1632,9 +1632,9 @@ const char *mg_strstr(const struct mg_str haystack,
#ifndef EXCLUDE_COMMON #ifndef EXCLUDE_COMMON
/* Amalgamated: #include "common/str_util.h" */
/* Amalgamated: #include "common/mg_mem.h" */ /* Amalgamated: #include "common/mg_mem.h" */
/* Amalgamated: #include "common/platform.h" */ /* Amalgamated: #include "common/platform.h" */
/* Amalgamated: #include "common/str_util.h" */
#ifndef C_DISABLE_BUILTIN_SNPRINTF #ifndef C_DISABLE_BUILTIN_SNPRINTF
#define C_DISABLE_BUILTIN_SNPRINTF 0 #define C_DISABLE_BUILTIN_SNPRINTF 0
...@@ -2090,11 +2090,10 @@ struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val, ...@@ -2090,11 +2090,10 @@ struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val,
return list; return list;
} }
int mg_match_prefix_n(const struct mg_str, const struct mg_str) WEAK; size_t mg_match_prefix_n(const struct mg_str, const struct mg_str) WEAK;
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str) { size_t mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str) {
const char *or_str; const char *or_str;
size_t len, i = 0, j = 0; size_t res = 0, len = 0, i = 0, j = 0;
int res;
if ((or_str = (const char *) memchr(pattern.p, '|', pattern.len)) != NULL || if ((or_str = (const char *) memchr(pattern.p, '|', pattern.len)) != NULL ||
(or_str = (const char *) memchr(pattern.p, ',', pattern.len)) != NULL) { (or_str = (const char *) memchr(pattern.p, ',', pattern.len)) != NULL) {
...@@ -2106,11 +2105,9 @@ int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str) { ...@@ -2106,11 +2105,9 @@ int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str) {
return mg_match_prefix_n(pstr, str); return mg_match_prefix_n(pstr, str);
} }
for (; i < pattern.len; i++, j++) { for (; i < pattern.len && j < str.len; i++, j++) {
if (pattern.p[i] == '?' && j != str.len) { if (pattern.p[i] == '?') {
continue; continue;
} else if (pattern.p[i] == '$') {
return j == str.len ? (int) j : -1;
} else if (pattern.p[i] == '*') { } else if (pattern.p[i] == '*') {
i++; i++;
if (i < pattern.len && pattern.p[i] == '*') { if (i < pattern.len && pattern.p[i] == '*') {
...@@ -2118,29 +2115,29 @@ int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str) { ...@@ -2118,29 +2115,29 @@ int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str) {
len = str.len - j; len = str.len - j;
} else { } else {
len = 0; len = 0;
while (j + len != str.len && str.p[j + len] != '/') { while (j + len < str.len && str.p[j + len] != '/') len++;
len++;
}
} }
if (i == pattern.len) { if (i == pattern.len || (pattern.p[i] == '$' && i == pattern.len - 1))
return j + len; return j + len;
}
do { do {
const struct mg_str pstr = {pattern.p + i, pattern.len - i}; const struct mg_str pstr = {pattern.p + i, pattern.len - i};
const struct mg_str sstr = {str.p + j + len, str.len - j - len}; const struct mg_str sstr = {str.p + j + len, str.len - j - len};
res = mg_match_prefix_n(pstr, sstr); res = mg_match_prefix_n(pstr, sstr);
} while (res == -1 && len-- > 0); } while (res == 0 && len != 0 && len-- > 0);
return res == -1 ? -1 : (int) (j + res + len); return res == 0 ? 0 : j + res + len;
} else if (str_util_lowercase(&pattern.p[i]) != } else if (str_util_lowercase(&pattern.p[i]) !=
str_util_lowercase(&str.p[j])) { str_util_lowercase(&str.p[j])) {
return -1; break;
} }
} }
return j; if (i < pattern.len && pattern.p[i] == '$') {
return j == str.len ? str.len : 0;
}
return i == pattern.len ? j : 0;
} }
int mg_match_prefix(const char *, int, const char *) WEAK; size_t mg_match_prefix(const char *, int, const char *) WEAK;
int mg_match_prefix(const char *pattern, int pattern_len, const char *str) { size_t mg_match_prefix(const char *pattern, int pattern_len, const char *str) {
const struct mg_str pstr = {pattern, (size_t) pattern_len}; const struct mg_str pstr = {pattern, (size_t) pattern_len};
struct mg_str s = {str, 0}; struct mg_str s = {str, 0};
if (str != NULL) s.len = strlen(str); if (str != NULL) s.len = strlen(str);
...@@ -6234,7 +6231,7 @@ struct mg_http_endpoint *mg_http_get_endpoint_handler(struct mg_connection *nc, ...@@ -6234,7 +6231,7 @@ struct mg_http_endpoint *mg_http_get_endpoint_handler(struct mg_connection *nc,
ep = pd->endpoints; ep = pd->endpoints;
while (ep != NULL) { while (ep != NULL) {
if ((matched = mg_match_prefix_n(ep->uri_pattern, *uri_path)) != -1) { if ((matched = mg_match_prefix_n(ep->uri_pattern, *uri_path)) > 0) {
if (matched > matched_max) { if (matched > matched_max) {
/* Looking for the longest suitable handler */ /* Looking for the longest suitable handler */
ret = ep; ret = ep;
...@@ -7291,8 +7288,7 @@ static int mg_is_file_hidden(const char *path, ...@@ -7291,8 +7288,7 @@ static int mg_is_file_hidden(const char *path,
} }
return (exclude_specials && (!strcmp(path, ".") || !strcmp(path, ".."))) || return (exclude_specials && (!strcmp(path, ".") || !strcmp(path, ".."))) ||
(p1 != NULL && (p1 != NULL && mg_match_prefix(p1, strlen(p1), path) == strlen(p1)) ||
mg_match_prefix(p1, strlen(p1), path) == (int) strlen(p1)) ||
(p2 != NULL && mg_match_prefix(p2, strlen(p2), path) > 0); (p2 != NULL && mg_match_prefix(p2, strlen(p2), path) > 0);
} }
...@@ -7842,7 +7838,7 @@ MG_INTERNAL int mg_uri_to_local_path(struct http_message *hm, ...@@ -7842,7 +7838,7 @@ MG_INTERNAL int mg_uri_to_local_path(struct http_message *hm,
} }
} else { } else {
/* Regular rewrite, URI=directory */ /* Regular rewrite, URI=directory */
int match_len = mg_match_prefix_n(a, hm->uri); size_t match_len = mg_match_prefix_n(a, hm->uri);
if (match_len > 0) { if (match_len > 0) {
file_uri_start = hm->uri.p + match_len; file_uri_start = hm->uri.p + match_len;
if (*file_uri_start == '/' || file_uri_start == cp_end) { if (*file_uri_start == '/' || file_uri_start == cp_end) {
......
...@@ -2076,8 +2076,8 @@ int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len); ...@@ -2076,8 +2076,8 @@ int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
/* Amalgamated: #include "common/platform.h" */
/* Amalgamated: #include "common/mg_str.h" */ /* Amalgamated: #include "common/mg_str.h" */
/* Amalgamated: #include "common/platform.h" */
#ifndef CS_ENABLE_STRDUP #ifndef CS_ENABLE_STRDUP
#define CS_ENABLE_STRDUP 0 #define CS_ENABLE_STRDUP 0
...@@ -2221,23 +2221,22 @@ struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val, ...@@ -2221,23 +2221,22 @@ struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val,
* - | or , divides alternative patterns * - | or , divides alternative patterns
* - any other character matches itself * - any other character matches itself
* ``` * ```
* Match is case-insensitive. Returns number of bytes matched, or -1 if no * Match is case-insensitive. Return number of bytes matched.
* match.
* Examples: * Examples:
* ``` * ```
* mg_match_prefix("a*f", len, "abcdefgh") == 6 * mg_match_prefix("a*f", len, "abcdefgh") == 6
* mg_match_prefix("a*f", len, "abcdexgh") == -1 * mg_match_prefix("a*f", len, "abcdexgh") == 0
* mg_match_prefix("a*f|de*,xy", len, "defgh") == 5 * mg_match_prefix("a*f|de*,xy", len, "defgh") == 5
* mg_match_prefix("?*", len, "abc") == 3 * mg_match_prefix("?*", len, "abc") == 3
* mg_match_prefix("?*", len, "") == -1 * mg_match_prefix("?*", len, "") == 0
* ``` * ```
*/ */
int mg_match_prefix(const char *pattern, int pattern_len, const char *str); size_t mg_match_prefix(const char *pattern, int pattern_len, const char *str);
/* /*
* Like `mg_match_prefix()`, but takes `pattern` and `str` as `struct mg_str`. * Like `mg_match_prefix()`, but takes `pattern` and `str` as `struct mg_str`.
*/ */
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str); size_t mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment