[master] 8a385bf Make it possible to set limits for VRE matching.
Poul-Henning Kamp
phk at varnish-cache.org
Thu Sep 22 16:57:35 CEST 2011
commit 8a385bfc803409428e37e23c4d7f844d03bb74c4
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Thu Sep 22 12:15:52 2011 +0000
Make it possible to set limits for VRE matching.
diff --git a/bin/varnishd/cache_vrt_re.c b/bin/varnishd/cache_vrt_re.c
index f41b809..b2afaa5 100644
--- a/bin/varnishd/cache_vrt_re.c
+++ b/bin/varnishd/cache_vrt_re.c
@@ -76,7 +76,7 @@ VRT_re_match(const struct sess *sp, const char *s, void *re)
s = "";
AN(re);
t = re;
- i = VRE_exec(t, s, strlen(s), 0, 0, NULL, 0);
+ i = VRE_exec(t, s, strlen(s), 0, 0, NULL, 0, ¶ms->vre_limits);
if (i >= 0)
return (1);
if (i < VRE_ERROR_NOMATCH )
@@ -101,7 +101,8 @@ VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
str = "";
t = re;
memset(ovector, 0, sizeof(ovector));
- i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30);
+ i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30,
+ ¶ms->vre_limits);
/* If it didn't match, we can return the original string */
if (i == VRE_ERROR_NOMATCH)
@@ -139,7 +140,8 @@ VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
if (!all)
break;
memset(&ovector, 0, sizeof(ovector));
- i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30);
+ i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30,
+ ¶ms->vre_limits);
if (i < VRE_ERROR_NOMATCH ) {
WSP(sp, SLT_VCL_Error,
"Regexp matching returned %d", i);
diff --git a/bin/varnishd/heritage.h b/bin/varnishd/heritage.h
index 13fce78..7aebf11 100644
--- a/bin/varnishd/heritage.h
+++ b/bin/varnishd/heritage.h
@@ -30,6 +30,7 @@
*/
#include <pthread.h>
+#include "vre.h"
struct listen_sock {
unsigned magic;
@@ -213,6 +214,8 @@ struct params {
double critbit_cooloff;
double shortlived;
+
+ struct vre_limits vre_limits;
};
/*
diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c
index decd130..f247b71 100644
--- a/bin/varnishd/mgt_param.c
+++ b/bin/varnishd/mgt_param.c
@@ -951,6 +951,24 @@ static const struct parspec input_parspec[] = {
"Unreferenced VCL objects result in error.\n",
0,
"on", "bool" },
+
+
+ { "pcre_match_limit", tweak_uint,
+ &master.vre_limits.match,
+ 1, UINT_MAX,
+ "The limit for the number of internal matching function"
+ " calls in a pcre_exec() execution.",
+ 0,
+ "10000", ""},
+
+ { "pcre_match_limit_recursion", tweak_uint,
+ &master.vre_limits.match_recursion,
+ 1, UINT_MAX,
+ "The limit for the number of internal matching function"
+ " recursions in a pcre_exec() execution.",
+ 0,
+ "10000", ""},
+
{ NULL, NULL, NULL }
};
diff --git a/include/vre.h b/include/vre.h
index 47dea3f..29c1b08 100644
--- a/include/vre.h
+++ b/include/vre.h
@@ -27,9 +27,21 @@
*
* Regular expression support
*
+ * We wrap PCRE in VRE to make to make it feasible to use something else
+ * without hunting down stuff through out the Varnish source code.
+ *
*/
+#ifndef VRE_H_INCLUDED
+#define VRE_H_INCLUDED
+
struct vre;
+
+struct vre_limits {
+ unsigned match;
+ unsigned match_recursion;
+};
+
typedef struct vre vre_t;
/* This maps to PCRE error codes */
@@ -39,5 +51,9 @@ typedef struct vre vre_t;
#define VRE_CASELESS 0x00000001
vre_t *VRE_compile(const char *, int, const char **, int *);
-int VRE_exec(const vre_t *, const char *, int, int, int, int *, int);
+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);
void VRE_free(vre_t **);
+
+#endif /* VRE_H_INCLUDED */
diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c
index 667d177..68beaf8 100644
--- a/lib/libvarnish/vre.c
+++ b/lib/libvarnish/vre.c
@@ -27,6 +27,7 @@
*/
#include <pcre.h>
+#include <string.h>
#include "libvarnish.h"
#include "miniobj.h"
@@ -58,17 +59,27 @@ VRE_compile(const char *pattern, int options,
int
VRE_exec(const vre_t *code, const char *subject, int length,
- int startoffset, int options, int *ovector, int ovecsize)
+ int startoffset, int options, int *ovector, int ovecsize,
+ const volatile struct vre_limits *lim)
{
CHECK_OBJ_NOTNULL(code, VRE_MAGIC);
int ov[30];
+ pcre_extra extra;
if (ovector == NULL) {
ovector = ov;
ovecsize = sizeof(ov)/sizeof(ov[0]);
}
- return (pcre_exec(code->re, NULL, subject, length,
+ memset(&extra, 0, sizeof extra);
+ if (lim != NULL) {
+ extra.match_limit = lim->match;
+ extra.flags |= PCRE_EXTRA_MATCH_LIMIT;
+ extra.match_limit_recursion = lim->match_recursion;
+ extra.flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
+ }
+
+ return (pcre_exec(code->re, &extra, subject, length,
startoffset, options, ovector, ovecsize));
}
diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c
index 58a454d..8473d31 100644
--- a/lib/libvarnishapi/vsl.c
+++ b/lib/libvarnishapi/vsl.c
@@ -266,13 +266,13 @@ VSL_NextLog(const struct VSM_data *vd, uint32_t **pp, uint64_t *bits)
continue;
if (vsl->regincl != NULL) {
i = VRE_exec(vsl->regincl, VSL_DATA(p), VSL_LEN(p),
- 0, 0, NULL, 0);
+ 0, 0, NULL, 0, NULL);
if (i == VRE_ERROR_NOMATCH)
continue;
}
if (vsl->regexcl != NULL) {
i = VRE_exec(vsl->regexcl, VSL_DATA(p), VSL_LEN(p),
- 0, 0, NULL, 0);
+ 0, 0, NULL, 0, NULL);
if (i != VRE_ERROR_NOMATCH)
continue;
}
@@ -282,7 +282,7 @@ VSL_NextLog(const struct VSM_data *vd, uint32_t **pp, uint64_t *bits)
VTAILQ_FOREACH(vrm, &vsl->matchers, next) {
if (vrm->tag == t) {
i = VRE_exec(vrm->re, VSL_DATA(p),
- VSL_LEN(p), 0, 0, NULL, 0);
+ VSL_LEN(p), 0, 0, NULL, 0, NULL);
if (i >= 0)
*bits |= (uintmax_t)1 << j;
}
More information about the varnish-commit
mailing list