diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2022-04-05 15:25:51 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2022-04-08 06:33:02 -0400 |
commit | dcb5f2318b163028f4bb7a18b2211facbd997713 (patch) | |
tree | 440d153611e96e5285b31de659c229e40863b05f /src/configparser.y | |
parent | b3e80a13632bf2803f3dcd286d054e3a0f1fc4cf (diff) | |
download | lighttpd-git-dcb5f2318b163028f4bb7a18b2211facbd997713.tar.gz |
[core] convert simple config cond regex to pre/sfx
convert simple config condition regex to prefix/suffix match
Diffstat (limited to 'src/configparser.y')
-rw-r--r-- | src/configparser.y | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/src/configparser.y b/src/configparser.y index 2f98516d..396084b1 100644 --- a/src/configparser.y +++ b/src/configparser.y @@ -177,9 +177,51 @@ configparser_comp_key_id(const buffer * const obj_tag, const buffer * const comp return COMP_UNSET; } +static config_cond_t +configparser_simplify_regex(buffer * const b) +{ + /* translate simple regex anchored with ^ and/or $ to simpler match types + * (note: skips if regex contains any '\\', even if some could be removed, + * though we special-case "\.ext"; skips if other '.' found in str) + * (currently assumes CONFIG_COND_NOMATCH input, not CONFIG_COND_NOMATCH) */ + uint32_t len = buffer_clen(b); + config_cond_t cond = CONFIG_COND_MATCH; + int off = 0; + if (len && b->ptr[len-1] == '$') { + cond = CONFIG_COND_SUFFIX; + if (b->ptr[0] == '\\' && b->ptr[1] == '.') + off = 2; + else if (b->ptr[0] == '^') { + off = 1; + cond = CONFIG_COND_EQ; + } + --len; + } + else if (b->ptr[0] == '^') { + off = 1; + cond = CONFIG_COND_PREFIX; + } + else + return CONFIG_COND_MATCH; + + static const char regex_chars[] = "\\^$.|?*+()[]{}"; + if (strcspn(b->ptr+off, regex_chars) != len - off) + return CONFIG_COND_MATCH; + if (off) { /*(remove only first char if (off == 2) to keep '.' in "\.")*/ + memmove(b->ptr, b->ptr+1, len-1); + --len; + } + buffer_truncate(b, len); + return cond; +} + static void -configparser_parse_condition(config_t * const ctx, const buffer * const obj_tag, const buffer * const comp_tag, const config_cond_t cond, buffer * const rvalue) +configparser_parse_condition(config_t * const ctx, const buffer * const obj_tag, const buffer * const comp_tag, config_cond_t cond, buffer * const rvalue) { + const comp_key_t comp = configparser_comp_key_id(obj_tag, comp_tag); + if (cond == CONFIG_COND_MATCH && comp != COMP_SERVER_SOCKET) + cond = configparser_simplify_regex(rvalue); + const char *op = NULL; switch(cond) { case CONFIG_COND_NE: op = "!="; break; @@ -219,7 +261,7 @@ configparser_parse_condition(config_t * const ctx, const buffer * const obj_tag, else { dc = data_config_init(); dc->cond = cond; - dc->comp = configparser_comp_key_id(obj_tag, comp_tag); + dc->comp = comp; buffer_copy_buffer(&dc->key, tb); buffer_copy_buffer(&dc->comp_tag, comp_tag); |