Commit 2f2ce096 authored by Geoff Simmons's avatar Geoff Simmons

Use "object-PRIV_TASK" scope to preserve match data for regex objects,

no longer using pthread keys.
parent ec5b2376
......@@ -115,7 +115,7 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
# due to calling barbaz.backref() before .match()
expect * = VCL_Error "^vmod re2 error: backref 0, fallback .fallback.: backref called without prior match$"
expect * = VCL_Error "^vmod re2 error: barbaz.backref.ref=0, fallback=.fallback..: backref called without prior match$"
# get the "out of range" error message even when the backref
# would have also failed due to failing prior match
......@@ -199,7 +199,7 @@ varnish v1 -vcl+backend {
logexpect l2 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod re2 error: backref 1, fallback .fallback.: backref called without prior match$"
expect * = VCL_Error "^vmod re2 error: barbaz.namedref.name=.bar., fallback=.fallback..: namedref called without prior match$"
expect * = VCL_Error "^vmod re2 error: barbaz.namedref..: fallback is undefined$"
expect * = VCL_Error "^vmod re2 error: barbaz.namedref.name=.., fallback=.name empty..: name is empty$"
expect * = VCL_Error "^vmod re2 error: barbaz.namedref.name=.., fallback=.name undefined..: name is empty$"
......
......@@ -28,7 +28,6 @@
#include "config.h"
#include <pthread.h>
#include <stdlib.h>
#include "vcl.h"
......@@ -49,6 +48,9 @@
#define VERR(ctx, fmt, ...) \
errmsg((ctx), "vmod re2 error: " fmt, __VA_ARGS__)
#define VERRNOMEM(ctx, fmt, ...) \
VERR((ctx), fmt ", out of space", __VA_ARGS__)
#define INIT(ctx) (((ctx)->method & VCL_MET_INIT) != 0)
struct vmod_re2_regex {
......@@ -56,7 +58,6 @@ struct vmod_re2_regex {
#define VMOD_RE2_REGEX_MAGIC 0x5c3f6f24
vre2 *vre2;
char *vcl_name;
pthread_key_t matchk;
int ngroups;
unsigned never_capture;
};
......@@ -159,8 +160,11 @@ match(VRT_CTX, vre2 * restrict vre2, VCL_STRING restrict subject,
return 0;
}
if (!never_capture && !match)
WS_Reset(ctx->ws, text);
if (!match) {
*groups = (void *)match_failed;
if (!never_capture)
WS_Reset(ctx->ws, text);
}
return match;
}
......@@ -183,11 +187,7 @@ backref(VRT_CTX, VCL_INT refnum, VCL_STRING fallback, void * const groups,
char *backref;
int len;
if (groups == NULL) {
VERR(ctx, ERR_PREFIX "backref called without prior match",
refnum, fallback);
return fallback;
}
AN(groups);
if (groups == match_failed)
return fallback;
......@@ -314,7 +314,6 @@ vmod_regex__init(const struct vrt_ctx *ctx, struct vmod_re2_regex **rep,
AN(re);
*rep = re;
AZ(pthread_key_create(&re->matchk, NULL));
if ((err = vre2_init(&re->vre2, pattern, utf8, posix_syntax,
longest_match, max_mem, literal, never_nl, dot_nl,
never_capture, case_sensitive, perl_classes,
......@@ -344,7 +343,6 @@ vmod_regex__fini(struct vmod_re2_regex **rep)
*rep = NULL;
CHECK_OBJ_NOTNULL(re, VMOD_RE2_REGEX_MAGIC);
vre2_fini(&re->vre2);
AZ(pthread_key_delete(re->matchk));
if (re->vcl_name != NULL)
free(re->vcl_name);
FREE_OBJ(re);
......@@ -355,16 +353,34 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
VCL_STRING subject)
{
VCL_BOOL ret;
void *groups;
struct vmod_priv *task;
task_match_t *task_match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(re, VMOD_RE2_REGEX_MAGIC);
AZ(pthread_setspecific(re->matchk, match_failed));
ret = match(ctx, re->vre2, subject, &groups, re->never_capture,
re->ngroups);
if (ret && !re->never_capture)
AZ(pthread_setspecific(re->matchk, groups));
task = VRT_priv_task(ctx, re);
AN(task);
if (task->priv == NULL) {
if ((task->priv = WS_Alloc(ctx->ws, sizeof(*task_match)))
== NULL) {
VERRNOMEM(ctx, "Allocating match data in "
"%s.match(subject=\"%.40s\"",
re->vcl_name, subject);
return 0;
}
task->len = sizeof(*task_match);
task->free = NULL;
task_match = (task_match_t *)task->priv;
task_match->magic = TASK_MATCH_MAGIC;
}
else {
WS_Contains(ctx->ws, task->priv, sizeof(*task_match));
CAST_OBJ(task_match, task->priv, TASK_MATCH_MAGIC);
}
ret = match(ctx, re->vre2, subject, &task_match->groups,
re->never_capture, re->ngroups);
return ret;
}
......@@ -374,7 +390,8 @@ VCL_STRING
vmod_regex_backref(VRT_CTX, struct vmod_re2_regex *re, VCL_INT refnum,
VCL_STRING fallback)
{
void *groups;
struct vmod_priv *task;
task_match_t *task_match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(re, VMOD_RE2_REGEX_MAGIC);
......@@ -395,8 +412,17 @@ vmod_regex_backref(VRT_CTX, struct vmod_re2_regex *re, VCL_INT refnum,
re->vcl_name, refnum, fallback, re->ngroups);
return fallback;
}
groups = pthread_getspecific(re->matchk);
return backref(ctx, refnum, fallback, groups, re->ngroups);
task = VRT_priv_task(ctx, re);
AN(task);
if (task->priv == NULL) {
VERR(ctx, ERR_PREFIX "backref called without prior match",
re->vcl_name, refnum, fallback);
return fallback;
}
WS_Contains(ctx->ws, task->priv, sizeof(*task_match));
CAST_OBJ(task_match, task->priv, TASK_MATCH_MAGIC);
return backref(ctx, refnum, fallback, task_match->groups, re->ngroups);
}
#undef ERR_PREFIX
......@@ -407,7 +433,8 @@ VCL_STRING
vmod_regex_namedref(VRT_CTX, struct vmod_re2_regex *re, VCL_STRING name,
VCL_STRING fallback)
{
void *groups;
struct vmod_priv *task;
task_match_t *task_match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(re, VMOD_RE2_REGEX_MAGIC);
......@@ -426,8 +453,18 @@ vmod_regex_namedref(VRT_CTX, struct vmod_re2_regex *re, VCL_STRING name,
re->vcl_name, name, fallback, re->vcl_name);
return fallback;
}
groups = pthread_getspecific(re->matchk);
return namedref(ctx, re->vre2, name, fallback, groups, re->ngroups);
task = VRT_priv_task(ctx, re);
AN(task);
if (task->priv == NULL) {
VERR(ctx, ERR_PREFIX "namedref called without prior match",
re->vcl_name, name, fallback);
return fallback;
}
WS_Contains(ctx->ws, task->priv, sizeof(*task_match));
CAST_OBJ(task_match, task->priv, TASK_MATCH_MAGIC);
return namedref(ctx, re->vre2, name, fallback, task_match->groups,
re->ngroups);
}
#undef ERR_PREFIX
......
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