summaryrefslogtreecommitdiff
path: root/src/configparser.y
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2022-04-05 15:25:51 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2022-04-08 06:33:02 -0400
commitdcb5f2318b163028f4bb7a18b2211facbd997713 (patch)
tree440d153611e96e5285b31de659c229e40863b05f /src/configparser.y
parentb3e80a13632bf2803f3dcd286d054e3a0f1fc4cf (diff)
downloadlighttpd-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.y46
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);