[master] a635df720 vre: New VRE_export() function
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Mon Jul 5 15:49:06 UTC 2021
commit a635df720a042aa8cfbbd53e4138e94da15ea0db
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Fri Jun 18 14:20:41 2021 +0200
vre: New VRE_export() function
It packs a vre_t and a pcre in a single allocation that can be used by
both VRE_match() and VRE_sub().
diff --git a/include/vre.h b/include/vre.h
index 08c768cd7..31dd339ab 100644
--- a/include/vre.h
+++ b/include/vre.h
@@ -57,6 +57,7 @@ extern const unsigned VRE_has_jit;
extern const unsigned VRE_CASELESS;
vre_t *VRE_compile(const char *, unsigned, int *, int *, unsigned);
+vre_t *VRE_export(const vre_t *, size_t *);
int VRE_error(struct vsb *, int err);
int VRE_match(const vre_t *code, const char *subject, size_t length,
int options, const volatile struct vre_limits *lim);
diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c
index a4e3f4a72..f4e54f864 100644
--- a/lib/libvarnish/vre.c
+++ b/lib/libvarnish/vre.c
@@ -32,6 +32,7 @@
#include <pcre.h>
#include <ctype.h>
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -56,6 +57,8 @@ const unsigned VRE_has_jit = VRE_STUDY_JIT_COMPILE;
# define pcre_free_study pcre_free
#endif
+#define VRE_PACKED_RE (pcre *)(-1)
+
struct vre {
unsigned magic;
#define VRE_MAGIC 0xe83097dc
@@ -138,27 +141,64 @@ VRE_error(struct vsb *vsb, int err)
return (0);
}
+static pcre *
+vre_unpack(const vre_t *code)
+{
+
+ CHECK_OBJ_NOTNULL(code, VRE_MAGIC);
+ if (code->re == VRE_PACKED_RE) {
+ AZ(code->re_extra);
+ AZ(code->my_extra);
+ return (TRUST_ME(code + 1));
+ }
+ return (code->re);
+}
+
+vre_t *
+VRE_export(const vre_t *code, size_t *sz)
+{
+ pcre *re;
+ vre_t *exp;
+
+ CHECK_OBJ_NOTNULL(code, VRE_MAGIC);
+ re = vre_unpack(code);
+ AZ(pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, sz));
+
+ exp = malloc(sizeof(*exp) + *sz);
+ if (exp == NULL)
+ return (NULL);
+
+ INIT_OBJ(exp, VRE_MAGIC);
+ exp->re = VRE_PACKED_RE;
+ memcpy(exp + 1, re, *sz);
+ *sz += sizeof(*exp);
+ return (exp);
+}
+
static int
vre_exec(const vre_t *code, const char *subject, int length,
int startoffset, int options, int *ovector, int ovecsize,
const volatile struct vre_limits *lim)
{
+ pcre *re;
CHECK_OBJ_NOTNULL(code, VRE_MAGIC);
AN(ovector);
if (lim != NULL) {
/* XXX: not reentrant */
+ AN(code->re_extra);
code->re_extra->match_limit = lim->match;
code->re_extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
code->re_extra->match_limit_recursion = lim->match_recursion;
code->re_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
- } else {
+ } else if (code->re_extra != NULL) {
code->re_extra->flags &= ~PCRE_EXTRA_MATCH_LIMIT;
code->re_extra->flags &= ~PCRE_EXTRA_MATCH_LIMIT_RECURSION;
}
- return (pcre_exec(code->re, code->re_extra, subject, length,
+ re = vre_unpack(code);
+ return (pcre_exec(re, code->re_extra, subject, length,
startoffset, options, ovector, ovecsize));
}
@@ -241,6 +281,13 @@ VRE_free(vre_t **vv)
*vv = NULL;
CHECK_OBJ(v, VRE_MAGIC);
+
+ if (v->re == VRE_PACKED_RE) {
+ v->re = NULL;
+ AZ(v->re_extra);
+ AZ(v->my_extra);
+ }
+
if (v->re_extra != NULL) {
if (v->my_extra)
free(v->re_extra);
More information about the varnish-commit
mailing list