Commit 13022358 authored by Geoff Simmons's avatar Geoff Simmons

Fix: now using priv_call scope for an object with the compiled regex

and pattern.
parent 1eb241bd
...@@ -43,10 +43,16 @@ ...@@ -43,10 +43,16 @@
#define MAX_OV 33 #define MAX_OV 33
typedef struct re_t {
unsigned magic;
#define RE_MAGIC 0xd361bdcb
vre_t *re;
char *pattern;
} re_t;
typedef struct sess_ov { typedef struct sess_ov {
unsigned magic; unsigned magic;
#define SESS_OV_MAGIC 0x844bfa39 #define SESS_OV_MAGIC 0x844bfa39
char *pattern;
const char *subject; const char *subject;
int ovector[MAX_OV]; int ovector[MAX_OV];
int count; int count;
...@@ -65,6 +71,19 @@ struct sess_tbl { ...@@ -65,6 +71,19 @@ struct sess_tbl {
*/ */
pthread_mutex_t re_mutex; pthread_mutex_t re_mutex;
static void
free_re(void *priv)
{
struct re_t *re;
CAST_OBJ_NOTNULL(re, priv, RE_MAGIC);
if (re->re != NULL)
VRE_free(&re->re);
if (re->pattern != NULL)
free(re->pattern);
FREE_OBJ(re);
}
static void static void
free_sess_tbl(void *priv) free_sess_tbl(void *priv)
{ {
...@@ -72,11 +91,8 @@ free_sess_tbl(void *priv) ...@@ -72,11 +91,8 @@ free_sess_tbl(void *priv)
CAST_OBJ_NOTNULL(tbl, priv, SESS_TBL_MAGIC); CAST_OBJ_NOTNULL(tbl, priv, SESS_TBL_MAGIC);
for (int i = 0; i < tbl->nsess; i++) for (int i = 0; i < tbl->nsess; i++)
if (tbl->sess[i] != NULL) { if (tbl->sess[i] != NULL)
if (tbl->sess[i]->pattern != NULL)
free(tbl->sess[i]->pattern);
FREE_OBJ(tbl->sess[i]); FREE_OBJ(tbl->sess[i]);
}
free(tbl->sess); free(tbl->sess);
FREE_OBJ(tbl); FREE_OBJ(tbl);
} }
...@@ -122,7 +138,7 @@ static inline unsigned ...@@ -122,7 +138,7 @@ static inline unsigned
match(struct sess *sp, struct vmod_priv *priv_vcl, struct vmod_priv *priv_call, match(struct sess *sp, struct vmod_priv *priv_vcl, struct vmod_priv *priv_call,
const char *str, const char *pattern, int dynamic) const char *str, const char *pattern, int dynamic)
{ {
vre_t *re; re_t *re;
struct sess_tbl *tbl; struct sess_tbl *tbl;
sess_ov *ov; sess_ov *ov;
int s; int s;
...@@ -141,43 +157,40 @@ match(struct sess *sp, struct vmod_priv *priv_vcl, struct vmod_priv *priv_call, ...@@ -141,43 +157,40 @@ match(struct sess *sp, struct vmod_priv *priv_vcl, struct vmod_priv *priv_call,
CHECK_OBJ(tbl->sess[sp->id], SESS_OV_MAGIC); CHECK_OBJ(tbl->sess[sp->id], SESS_OV_MAGIC);
ov = tbl->sess[sp->id]; ov = tbl->sess[sp->id];
if (priv_call->priv == NULL CAST_OBJ(re, priv_call->priv, RE_MAGIC);
|| (dynamic && strcmp(pattern, ov->pattern) != 0)) { if (re == NULL || (dynamic && pattern != re->pattern)) {
char *pat = ov->pattern;
AZ(pthread_mutex_lock(&re_mutex)); AZ(pthread_mutex_lock(&re_mutex));
/*
* Double-check the lock. For dynamic, the pointer would /* Double-check the lock. */
* have changed by now if another thread was already here, if (re == NULL || (dynamic && pattern != re->pattern)) {
* so strcmp doesn't have to be repeated.
*/
if (priv_call->priv == NULL
|| (dynamic && (pat == ov->pattern))) {
int erroffset = 0; int erroffset = 0;
const char *error = NULL; const char *error = NULL;
priv_call->priv = VRE_compile(pattern, 0, &error, if (re == NULL) {
&erroffset); ALLOC_OBJ(re, RE_MAGIC);
if (priv_call->priv == NULL) XXXAN(re);
}
re->re = VRE_compile(pattern, 0, &error, &erroffset);
if (re->re == NULL)
WSP(sp, SLT_VCL_error, WSP(sp, SLT_VCL_error,
"vmod re: error compiling regex \"%s\": " "vmod re: error compiling regex \"%s\": "
"%s (position %d)", pattern, error, "%s (position %d)", pattern, error,
erroffset); erroffset);
else { else {
priv_call->free = VRT_re_fini; priv_call->priv = re;
priv_call->free = free_re;
if (dynamic) if (dynamic)
REPLACE(ov->pattern, pattern); REPLACE(re->pattern, pattern);
} }
} }
AZ(pthread_mutex_unlock(&re_mutex)); AZ(pthread_mutex_unlock(&re_mutex));
} }
re = (vre_t *) priv_call->priv; if (re->re == NULL)
if (re == NULL)
return 0; return 0;
if (str == NULL) if (str == NULL)
str = ""; str = "";
s = VRE_exec(re, str, strlen(str), 0, 0, &ov->ovector[0], s = VRE_exec(re->re, str, strlen(str), 0, 0, &ov->ovector[0],
MAX_OV, &params->vre_limits); MAX_OV, &params->vre_limits);
ov->count = s; ov->count = s;
if (s < VRE_ERROR_NOMATCH) { if (s < VRE_ERROR_NOMATCH) {
......
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