summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2021-11-21 00:47:35 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2021-11-21 21:27:52 -0500
commit7db817c59a89375ece9c3ec3b4ef7e4302e64549 (patch)
tree5a58d66c9704ed4cbec020dedb357d87c370a8c2
parent6d47d4c69997c3f62e35d71203d770a4a98dcb56 (diff)
downloadlighttpd-git-7db817c59a89375ece9c3ec3b4ef7e4302e64549.tar.gz
[core] extend pcre_keyvalue_ctx to pass more state
extend pcre_keyvalue_ctx to pass internal state
-rw-r--r--src/keyvalue.c44
-rw-r--r--src/keyvalue.h4
-rw-r--r--src/mod_dirlisting.c2
-rw-r--r--src/mod_trigger_b4_dl.c2
4 files changed, 30 insertions, 22 deletions
diff --git a/src/keyvalue.c b/src/keyvalue.c
index d9f14605..4c9cf9fa 100644
--- a/src/keyvalue.c
+++ b/src/keyvalue.c
@@ -91,8 +91,8 @@ int pcre_keyvalue_buffer_append(log_error_st *errh, pcre_keyvalue_buffer *kvb, c
void pcre_keyvalue_buffer_free(pcre_keyvalue_buffer *kvb) {
#ifdef HAVE_PCRE_H
- for (uint32_t i = 0; i < kvb->used; ++i) {
- pcre_keyvalue * const kv = kvb->kv+i;
+ pcre_keyvalue *kv = kvb->kv;
+ for (int i = 0, used = (int)kvb->used; i < used; ++i, ++kv) {
if (kv->key) pcre_free(kv->key);
if (kv->key_extra) pcre_free_study(kv->key_extra);
/*free (kv->value.ptr);*//*(see pcre_keyvalue_buffer_append)*/
@@ -104,23 +104,27 @@ void pcre_keyvalue_buffer_free(pcre_keyvalue_buffer *kvb) {
}
#ifdef HAVE_PCRE_H
-static void pcre_keyvalue_buffer_append_match(buffer *b, const char **list, int n, unsigned int num, int flags) {
- if (num < (unsigned int)n) { /* n is always > 0 */
- burl_append(b, list[num], strlen(list[num]), flags);
+static void pcre_keyvalue_buffer_append_match(buffer *b, const pcre_keyvalue_ctx *ctx, unsigned int num, int flags) {
+ if (num < (unsigned int)ctx->n) { /* n is always > 0 */
+ const int *ovec = (int *)ctx->ovec;
+ const size_t off = (size_t)ovec[(num <<= 1)]; /*(num *= 2)*/
+ const size_t len = (size_t)ovec[num+1] - off;
+ burl_append(b, ctx->subject + off, len, flags);
}
}
static void pcre_keyvalue_buffer_append_ctxmatch(buffer *b, const pcre_keyvalue_ctx *ctx, unsigned int num, int flags) {
const struct cond_match_t * const cache = ctx->cache;
if (!cache) return; /* no enclosing match context */
- if ((int)num < cache->captures) {
- const int off = cache->matches[(num <<= 1)]; /*(num *= 2)*/
- const int len = cache->matches[num+1] - off;
- burl_append(b, cache->comp_value->ptr + off, (size_t)len, flags);
+ if (num < (unsigned int)cache->captures) {
+ const int *ovec = (int *)cache->matches;
+ const size_t off = (size_t)ovec[(num <<= 1)]; /*(num *= 2)*/
+ const size_t len = (size_t)ovec[num+1] - off;
+ burl_append(b, cache->comp_value->ptr + off, len, flags);
}
}
-static int pcre_keyvalue_buffer_subst_ext(buffer *b, const char *pattern, const char **list, int n, const pcre_keyvalue_ctx *ctx) {
+static int pcre_keyvalue_buffer_subst_ext(buffer *b, const char *pattern, const pcre_keyvalue_ctx *ctx) {
const unsigned char *p = (unsigned char *)pattern+2;/* +2 past ${} or %{} */
int flags = 0;
while (!light_isdigit(*p) && *p != '}' && *p != '\0') {
@@ -256,13 +260,13 @@ static int pcre_keyvalue_buffer_subst_ext(buffer *b, const char *pattern, const
}
if (0 == flags) flags = BURL_ENCODE_PSNDE; /* default */
pattern[0] == '$' /*(else '%')*/
- ? pcre_keyvalue_buffer_append_match(b, list, n, num, flags)
+ ? pcre_keyvalue_buffer_append_match(b, ctx, num, flags)
: pcre_keyvalue_buffer_append_ctxmatch(b, ctx, num, flags);
}
return (int)(p + 1 - (unsigned char *)pattern - 2);
}
-static void pcre_keyvalue_buffer_subst(buffer *b, const buffer *patternb, const char **list, int n, const pcre_keyvalue_ctx *ctx) {
+static void pcre_keyvalue_buffer_subst(buffer *b, const buffer *patternb, const pcre_keyvalue_ctx *ctx) {
const char *pattern = patternb->ptr;
const size_t pattern_len = buffer_clen(patternb);
size_t start = 0;
@@ -277,13 +281,13 @@ static void pcre_keyvalue_buffer_subst(buffer *b, const buffer *patternb, const
buffer_append_string_len(b, pattern + start, k - start);
if (pattern[k + 1] == '{') {
- int num = pcre_keyvalue_buffer_subst_ext(b, pattern+k, list, n, ctx);
+ int num = pcre_keyvalue_buffer_subst_ext(b, pattern+k, ctx);
if (num < 0) return; /* error; truncate result */
k += (size_t)num;
} else if (light_isdigit(((unsigned char *)pattern)[k + 1])) {
unsigned int num = (unsigned int)pattern[k + 1] - '0';
pattern[k] == '$' /*(else '%')*/
- ? pcre_keyvalue_buffer_append_match(b, list, n, num, 0)
+ ? pcre_keyvalue_buffer_append_match(b, ctx, num, 0)
: pcre_keyvalue_buffer_append_ctxmatch(b, ctx, num, 0);
} else {
/* enable escape: "%%" => "%", "%a" => "%a", "$$" => "$" */
@@ -299,8 +303,8 @@ static void pcre_keyvalue_buffer_subst(buffer *b, const buffer *patternb, const
}
handler_t pcre_keyvalue_buffer_process(const pcre_keyvalue_buffer *kvb, pcre_keyvalue_ctx *ctx, const buffer *input, buffer *result) {
- for (int i = 0, used = (int)kvb->used; i < used; ++i) {
- const pcre_keyvalue * const kv = kvb->kv+i;
+ const pcre_keyvalue *kv = kvb->kv;
+ for (int i = 0, used = (int)kvb->used; i < used; ++i, ++kv) {
#define N 20
int ovec[N * 3];
#undef N
@@ -318,11 +322,11 @@ handler_t pcre_keyvalue_buffer_process(const pcre_keyvalue_buffer *kvb, pcre_key
return HANDLER_GO_ON;
}
else { /* it matched */
- const char **list;
ctx->m = i;
- pcre_get_substring_list(input->ptr, ovec, n, &list);
- pcre_keyvalue_buffer_subst(result, &kv->value, list, n, ctx);
- pcre_free(list);
+ ctx->n = n;
+ ctx->subject = input->ptr;
+ ctx->ovec = ovec;
+ pcre_keyvalue_buffer_subst(result, &kv->value, ctx);
return HANDLER_FINISHED;
}
}
diff --git a/src/keyvalue.h b/src/keyvalue.h
index c8671935..97d500a1 100644
--- a/src/keyvalue.h
+++ b/src/keyvalue.h
@@ -13,6 +13,10 @@ typedef struct pcre_keyvalue_ctx {
struct cond_match_t *cache;
struct burl_parts_t *burl;
int m;
+ /*(internal use)*/
+ int n;
+ void *ovec;
+ const char *subject;
} pcre_keyvalue_ctx;
typedef struct {
diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
index d541c0e1..6e020b7c 100644
--- a/src/mod_dirlisting.c
+++ b/src/mod_dirlisting.c
@@ -243,7 +243,7 @@ static int mod_dirlisting_exclude(pcre_keyvalue_buffer * const kvb, const char *
* must have been configured with empty kvb 'value' during init)*/
buffer input = { NULL, len+1, 0 };
*(const char **)&input.ptr = name;
- pcre_keyvalue_ctx ctx = { NULL, NULL, -1 };
+ pcre_keyvalue_ctx ctx = { NULL, NULL, -1, 0, NULL, NULL };
#ifdef __COVERITY__
/*(again, must have been configured w/ empty kvb 'value' during init)*/
struct cond_match_t cache;
diff --git a/src/mod_trigger_b4_dl.c b/src/mod_trigger_b4_dl.c
index 79234b0e..4295d810 100644
--- a/src/mod_trigger_b4_dl.c
+++ b/src/mod_trigger_b4_dl.c
@@ -185,7 +185,7 @@ static int mod_trigger_b4_dl_init_regex(server * const srv, config_plugin_value_
static int mod_trigger_b4_dl_match(pcre_keyvalue_buffer * const kvb, const buffer * const input) {
/*(re-use keyvalue.[ch] for match-only;
* must have been configured with empty kvb 'value' during init)*/
- pcre_keyvalue_ctx ctx = { NULL, NULL, -1 };
+ pcre_keyvalue_ctx ctx = { NULL, NULL, -1, 0, NULL, NULL };
#ifdef __COVERITY__
/*(again, must have been configured w/ empty kvb 'value' during init)*/
struct cond_match_t cache;