From 8d84deecc580741d85097afaadd0c0ae2d762ebc Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 28 Oct 2015 00:04:45 +0200 Subject: [PATCH] Updated schemarouter to use PCRE2 and moved includes to the header file. --- server/modules/include/schemarouter.h | 25 ++++++++- .../routing/schemarouter/schemarouter.c | 56 +++++++++---------- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/server/modules/include/schemarouter.h b/server/modules/include/schemarouter.h index 4f5698972..1607669d1 100644 --- a/server/modules/include/schemarouter.h +++ b/server/modules/include/schemarouter.h @@ -28,11 +28,31 @@ * * @endverbatim */ +#ifndef PCRE2_CODE_UNIT_WIDTH +#define PCRE2_CODE_UNIT_WIDTH 8 +#endif +#include +#include +#include +#include +#include +#include #include #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + /** * Bitmask values for the router session's initialization. These values are used * to prevent responses from internal commands being forwarded to the client. @@ -330,9 +350,10 @@ typedef struct router_instance { HASHTABLE* ignored_dbs; /*< List of databases to ignore when the * database mapping finds multiple servers * with the same database */ - pcre* ignore_regex; /*< Databases matching this regex will + pcre2_code* ignore_regex; /*< Databases matching this regex will * not cause the session to be terminated * if they are found on more than one server. */ + pcre2_match_data* ignore_match_data; } ROUTER_INSTANCE; diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 8f155892d..710c766bf 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -15,35 +15,14 @@ * * Copyright MariaDB Corporation Ab 2013-2014 */ -#include -#include -#include -#include -#include -#include -#include + #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #define DEFAULT_REFRESH_INTERVAL 30.0 /** Size of the hashtable used to store ignored databases */ #define SCHEMAROUTER_HASHSIZE 100 -/** Size of the offset vector used for regex matching */ -#define SCHEMA_OVEC_SIZE 24 - MODULE_INFO info = { MODULE_API_ROUTER, MODULE_BETA_RELEASE, @@ -380,13 +359,11 @@ showdb_response_t parse_showdb_response(ROUTER_CLIENT_SES* rses, backend_ref_t* } else { - const int ovec_count = SCHEMA_OVEC_SIZE; - int ovector[ovec_count]; - if (!(hashtable_fetch(rses->router->ignored_dbs, data) || (rses->router->ignore_regex && - pcre_exec(rses->router->ignore_regex, NULL, data, - strlen(data), 0, 0, ovector, ovec_count) >= 0))) + pcre2_match(rses->router->ignore_regex, (PCRE2_SPTR)data, + PCRE2_ZERO_TERMINATED, 0, 0, + rses->router->ignore_match_data, NULL) >= 0))) { duplicate_found = true; skygw_log_write(LE, "Error: Database '%s' found on servers '%s' and '%s' for user %s@%s.", @@ -801,19 +778,36 @@ createInstance(SERVICE *service, char **options) if((param = config_get_param(conf,"ignore_databases_regex"))) { - const char* errptr; - int erroffset; - pcre* re = pcre_compile(param->value, 0, &errptr, &erroffset, NULL); + int errcode; + PCRE2_SIZE erroffset; + pcre2_code* re = pcre2_compile((PCRE2_SPTR)param->value, PCRE2_ZERO_TERMINATED, 0, + &errcode, &erroffset, NULL); if(re == NULL) { + PCRE2_UCHAR errbuf[512]; + pcre2_get_error_message(errcode, errbuf, sizeof(errbuf)); skygw_log_write(LE, "Error: Regex compilation failed at %d for regex '%s': %s", - erroffset, param->value, errptr); + erroffset, param->value, errbuf); hashtable_free(router->ignored_dbs); free(router); return NULL; } + + pcre2_match_data* match_data = pcre2_match_data_create_from_pattern(re, NULL); + + if (match_data == NULL) + { + skygw_log_write(LE, "Error: PCRE2 match data creation failed. This" + " is most likely caused by a lack of available memory."); + pcre2_code_free(re); + hashtable_free(router->ignored_dbs); + free(router); + return NULL; + } + router->ignore_regex = re; + router->ignore_match_data = match_data; } if((param = config_get_param(conf,"ignore_databases")))