diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-11-21 00:47:35 -0500 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2021-11-21 21:27:52 -0500 |
commit | 7db817c59a89375ece9c3ec3b4ef7e4302e64549 (patch) | |
tree | 5a58d66c9704ed4cbec020dedb357d87c370a8c2 | |
parent | 6d47d4c69997c3f62e35d71203d770a4a98dcb56 (diff) | |
download | lighttpd-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.c | 44 | ||||
-rw-r--r-- | src/keyvalue.h | 4 | ||||
-rw-r--r-- | src/mod_dirlisting.c | 2 | ||||
-rw-r--r-- | src/mod_trigger_b4_dl.c | 2 |
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; |