Commit 7ea83d5c authored by Geoff Simmons's avatar Geoff Simmons

Consolidate common code for the sub() method and function.

parent cd2b0621
Pipeline #259 skipped
...@@ -703,6 +703,68 @@ refer(VRT_CTX, VCL_INT ref, VCL_STRING restrict const name, ...@@ -703,6 +703,68 @@ refer(VRT_CTX, VCL_INT ref, VCL_STRING restrict const name,
return fallback; return fallback;
} }
static inline VCL_STRING
sub(VRT_CTX, VCL_STRING restrict subject, VCL_STRING const restrict replacement,
VCL_INT len, struct vmod_priv * const restrict priv_task,
pcre2_code * restrict code,
const struct match_call * const restrict match_opts,
const char * const restrict context)
{
pcre2_match_data *mdata;
struct task *match_task = NULL;
int ret;
PCRE2_SIZE bytes;
PCRE2_UCHAR *buf;
char *msg;
uintptr_t snap;
if ((match_task = get_task(ctx, priv_task, context, ".sub()"))
== NULL)
return NULL;
mdata = pcre2_match_data_create_from_pattern(code, match_task->gctx);
if (mdata == NULL) {
VERRNOMEM(ctx, "initializing match data in %s.sub()", context);
return NULL;
}
/*
* Don't need to ensure that the subject is in workspace, as we do
* with matches, because we won't be retrieving backrefs, and we
* give pcre2 the rest of the workspace to write the substitution.
*/
if (subject == NULL)
subject = "";
if (len == 0)
len = PCRE2_ZERO_TERMINATED;
buf = (PCRE2_UCHAR *) WS_Front(ctx->ws);
bytes = (PCRE2_SIZE) WS_Reserve(ctx->ws, 0);
/* XXX param for start_offset */
ret = pcre2_substitute(code, (PCRE2_SPTR)subject, len, 0,
match_opts->match_options, mdata,
match_opts->mctx, (PCRE2_SPTR)replacement,
PCRE2_ZERO_TERMINATED, buf, &bytes);
if (ret > 0) {
WS_Release(ctx->ws, bytes + 1);
return (VCL_STRING)buf;
}
WS_Release(ctx->ws, 0);
if (ret == 0)
return subject;
if (ret == PCRE2_ERROR_NOMEMORY) {
VERRNOMEM(ctx, "allocating substitution result in %s.sub()",
context);
return NULL;
}
snap = WS_Snapshot(ctx->ws);
if ((msg = WS_Printf(ctx->ws, "in %s.sub()", context)) == NULL)
msg = "";
report_pcre2_err(ctx, ret, msg, "");
WS_Reset(ctx->ws, snap);
return NULL;
}
VCL_VOID VCL_VOID
vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp, vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp,
const char *vcl_name, VCL_STRING pattern, COMPILE_OPTS) const char *vcl_name, VCL_STRING pattern, COMPILE_OPTS)
...@@ -844,14 +906,7 @@ vmod_regex_sub(VRT_CTX, struct vmod_pcre2_regex *regex, ...@@ -844,14 +906,7 @@ vmod_regex_sub(VRT_CTX, struct vmod_pcre2_regex *regex,
VCL_STRING subject, VCL_STRING replacement, MATCH_OPTS, VCL_STRING subject, VCL_STRING replacement, MATCH_OPTS,
SUB_OPTS) SUB_OPTS)
{ {
pcre2_match_data *mdata;
struct task *match_task = NULL;
struct match_call *match_opts; struct match_call *match_opts;
int ret;
PCRE2_SIZE bytes;
PCRE2_UCHAR *buf;
char *msg;
uintptr_t snap;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(regex, VMOD_PCRE2_REGEX_MAGIC); CHECK_OBJ_NOTNULL(regex, VMOD_PCRE2_REGEX_MAGIC);
...@@ -869,54 +924,8 @@ vmod_regex_sub(VRT_CTX, struct vmod_pcre2_regex *regex, ...@@ -869,54 +924,8 @@ vmod_regex_sub(VRT_CTX, struct vmod_pcre2_regex *regex,
if (match_opts == NULL) if (match_opts == NULL)
return 0; return 0;
/* XXX mdata in PRIV_CALL? */ return sub(ctx, subject, replacement, len, priv_task, regex->code,
if ((match_task = get_task(ctx, priv_task, regex->vcl_name, ".sub()")) match_opts, regex->vcl_name);
== NULL)
return NULL;
mdata = pcre2_match_data_create_from_pattern(regex->code,
match_task->gctx);
if (mdata == NULL) {
VERRNOMEM(ctx, "initializing match data in %s.sub()",
regex->vcl_name);
return NULL;
}
/*
* Don't need to ensure that the subject is in workspace, as we do
* with matches, because we won't be retrieving backrefs, and we
* give pcre2 the rest of the workspace to write the substitution.
*/
if (subject == NULL)
subject = "";
if (len == 0)
len = PCRE2_ZERO_TERMINATED;
buf = (PCRE2_UCHAR *) WS_Front(ctx->ws);
bytes = (PCRE2_SIZE) WS_Reserve(ctx->ws, 0);
/* XXX param for start_offset */
ret = pcre2_substitute(regex->code, (PCRE2_SPTR)subject, len, 0,
match_opts->match_options, mdata,
match_opts->mctx, (PCRE2_SPTR)replacement,
PCRE2_ZERO_TERMINATED, buf, &bytes);
if (ret > 0) {
WS_Release(ctx->ws, bytes + 1);
return (VCL_STRING)buf;
}
WS_Release(ctx->ws, 0);
if (ret == 0)
return subject;
if (ret == PCRE2_ERROR_NOMEMORY) {
VERRNOMEM(ctx, "allocating substitution result in %s.sub()",
regex->vcl_name);
return NULL;
}
snap = WS_Snapshot(ctx->ws);
if ((msg = WS_Printf(ctx->ws, "in %s.sub()", regex->vcl_name)) == NULL)
msg = "";
report_pcre2_err(ctx, ret, msg, "");
WS_Reset(ctx->ws, snap);
return NULL;
} }
/* Functional interface */ /* Functional interface */
...@@ -1028,15 +1037,9 @@ vmod_sub(VRT_CTX, struct vmod_priv *priv_call, struct vmod_priv *priv_task, ...@@ -1028,15 +1037,9 @@ vmod_sub(VRT_CTX, struct vmod_priv *priv_call, struct vmod_priv *priv_task,
VCL_STRING pattern, VCL_STRING subject, VCL_STRING replacement, VCL_STRING pattern, VCL_STRING subject, VCL_STRING replacement,
COMPILE_OPTS, MATCHF_OPTS, SUB_OPTS) COMPILE_OPTS, MATCHF_OPTS, SUB_OPTS)
{ {
pcre2_match_data *mdata;
struct task *match_task = NULL;
struct match_call *match_opts; struct match_call *match_opts;
pcre2_code *code; pcre2_code *code;
int ret; VCL_STRING ret;
PCRE2_SIZE bytes;
PCRE2_UCHAR *buf;
char *msg;
uintptr_t snap;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(priv_task); AN(priv_task);
...@@ -1068,52 +1071,10 @@ vmod_sub(VRT_CTX, struct vmod_priv *priv_call, struct vmod_priv *priv_task, ...@@ -1068,52 +1071,10 @@ vmod_sub(VRT_CTX, struct vmod_priv *priv_call, struct vmod_priv *priv_task,
"pcre2", ".match()")) == NULL) "pcre2", ".match()")) == NULL)
return NULL; return NULL;
/* XXX mdata in PRIV_CALL? */ ret = sub(ctx, subject, replacement, len, priv_task, code, match_opts,
if ((match_task = get_task(ctx, priv_task, "pcre2", ".sub()")) "pcre2");
== NULL)
return NULL;
mdata = pcre2_match_data_create_from_pattern(code, match_task->gctx);
if (mdata == NULL) {
ERRNOMEM(ctx, "initializing match data in pcre2.sub()");
return NULL;
}
/*
* Don't need to ensure that the subject is in workspace, as we do
* with matches, because we won't be retrieving backrefs, and we
* give pcre2 the rest of the workspace to write the substitution.
*/
if (subject == NULL)
subject = "";
if (len == 0)
len = PCRE2_ZERO_TERMINATED;
buf = (PCRE2_UCHAR *) WS_Front(ctx->ws);
bytes = (PCRE2_SIZE) WS_Reserve(ctx->ws, 0);
/* XXX param for start_offset */
ret = pcre2_substitute(code, (PCRE2_SPTR)subject, len, 0,
match_opts->match_options, mdata,
match_opts->mctx, (PCRE2_SPTR)replacement,
PCRE2_ZERO_TERMINATED, buf, &bytes);
pcre2_code_free(code); pcre2_code_free(code);
if (ret > 0) { return ret;
WS_Release(ctx->ws, bytes + 1);
return (VCL_STRING)buf;
}
WS_Release(ctx->ws, 0);
if (ret == 0)
return subject;
if (ret == PCRE2_ERROR_NOMEMORY) {
ERRNOMEM(ctx, "allocating substitution result in pcre2.sub()");
return NULL;
}
snap = WS_Snapshot(ctx->ws);
if ((msg = WS_Printf(ctx->ws, "in pcre2.sub()")) == NULL)
msg = "";
report_pcre2_err(ctx, ret, msg, "");
WS_Reset(ctx->ws, snap);
return NULL;
} }
/* Functions */ /* Functions */
......
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