From a89f0f332db70d9a7c925807f02b06c9cb0b481d Mon Sep 17 00:00:00 2001 From: Evan Ramos Date: Fri, 26 Feb 2021 15:08:34 -0600 Subject: [PATCH] Make regex code in utils thread-safe regex_context_t is only 520 bytes on platforms with 8-byte pointers, which is reasonable to allocate on the stack instead of as a global in a userland program. --- src/utils.cpp | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/utils.cpp b/src/utils.cpp index b7f679a28a..bf88238d4a 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1280,24 +1280,14 @@ extern "C" { /* Typedef'd pointer to get abstract datatype. */ typedef struct regex_t *re_t; + typedef struct regex_context_t *re_ctx_t; /* Compile regex string pattern to a regex_t-array. */ - static re_t re_compile(const char *pattern); + static re_t re_compile(re_ctx_t context, const char *pattern); /* Find matches of the compiled pattern inside text. */ static int re_matchp(const char *text, re_t pattern, int *matchlen); - int re_match(const char *text, const char *pattern) - { - int dummy; - return re_matchp(text, re_compile(pattern), &dummy); - } - - int re_find(const char *text, const char *pattern, int *matchlen) - { - return re_matchp(text, re_compile(pattern), matchlen); - } - /* Definitions: */ #define MAX_REGEXP_OBJECTS 30 /* Max number of regex symbols in expression. */ @@ -1317,6 +1307,26 @@ extern "C" { } u; } regex_t; + typedef struct regex_context_t { + /* MAX_REGEXP_OBJECTS is the max number of symbols in the expression. + MAX_CHAR_CLASS_LEN determines the size of buffer for chars in all char-classes in the expression. */ + regex_t re_compiled[MAX_REGEXP_OBJECTS]; + unsigned char ccl_buf[MAX_CHAR_CLASS_LEN]; + } regex_context_t; + + int re_match(const char *text, const char *pattern) + { + regex_context_t context; + int dummy; + return re_matchp(text, re_compile(&context, pattern), &dummy); + } + + int re_find(const char *text, const char *pattern, int *matchlen) + { + regex_context_t context; + return re_matchp(text, re_compile(&context, pattern), matchlen); + } + /* Private function declarations: */ static int matchpattern(regex_t *pattern, const char *text, int *matchlen); static int matchcharclass(char c, const char *str); @@ -1359,13 +1369,10 @@ extern "C" { return -1; } - re_t re_compile(const char *pattern) + re_t re_compile(re_ctx_t context, const char *pattern) { - /* The sizes of the two static arrays below substantiates the static RAM usage of this module. - MAX_REGEXP_OBJECTS is the max number of symbols in the expression. - MAX_CHAR_CLASS_LEN determines the size of buffer for chars in all char-classes in the expression. */ - static regex_t re_compiled[MAX_REGEXP_OBJECTS]; - static unsigned char ccl_buf[MAX_CHAR_CLASS_LEN]; + regex_t * const re_compiled = context->re_compiled; + unsigned char * const ccl_buf = context->ccl_buf; int ccl_bufidx = 1; char c; /* current char in pattern */