From: Stefan Fritsch Date: Sun, 21 Nov 2010 17:22:26 +0000 (+0000) Subject: ap_expr related fixes/enhancements: X-Git-Tag: 2.3.9~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ef1911acc7e848d88e3ff505cc2a018f41cd903;p=apache ap_expr related fixes/enhancements: - implement regex backreferences and make them available for setting envvars in SetEnvIfExpr - implement nested function calls in %-syntax: %{func1:%{func2:arg}} - actually implement evaluation of concatenation operator (oops...) - Fix treating an internal error as success git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1037504 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/ap_expr.h b/include/ap_expr.h index b71c40aee2..2a27559232 100644 --- a/include/ap_expr.h +++ b/include/ap_expr.h @@ -55,12 +55,31 @@ typedef struct { * Evaluate a parse tree * @param r The current request * @param expr The expression to be evaluated - * @param err A more detailed error string + * @param err Where an error message should be stored * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error + * @note err will be set to NULL on success, or to an error message on error */ AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *expr, const char **err); +/** + * Evaluate a parse tree, with regexp backreferences + * @param r The current request + * @param expr The expression to be evaluated + * @param nmatch size of the regex match vector pmatch + * @param pmatch information about regex matches + * @param source the string that pmatch applies to + * @param err Where an error message should be stored + * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error + * @note err will be set to NULL on success, or to an error message on error + * @note nmatch/pmatch/source can be used both to make previous matches + * available to ap_expr_exec_re and to use ap_expr_exec_re's matches + * later on. + */ +AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *expr, + apr_size_t nmatch, ap_regmatch_t *pmatch, + const char **source, const char **err); + /** Context used during evaluation of a parse tree, created by ap_expr_exec */ typedef struct { /** the current request */ @@ -75,6 +94,12 @@ typedef struct { const char **err; /** ap_expr_info_t for the expression */ const ap_expr_info_t *info; + /** regex match information for back references */ + ap_regmatch_t *re_pmatch; + /** size of the vector pointed to by re_pmatch */ + apr_size_t re_nmatch; + /** the string corresponding to the re_pmatch*/ + const char **re_source; } ap_expr_eval_ctx; diff --git a/modules/aaa/mod_authz_core.c b/modules/aaa/mod_authz_core.c index 2fb89c6b49..217f0b026a 100644 --- a/modules/aaa/mod_authz_core.c +++ b/modules/aaa/mod_authz_core.c @@ -992,7 +992,7 @@ static authz_status expr_check_authorization(request_rec *r, const ap_expr_info_t *expr = parsed_require_line; int rc = ap_expr_exec(r, expr, &err); - if (err || !rc) + if (rc <= 0) /* XXX: real error handling? */ return AUTHZ_DENIED; else diff --git a/server/request.c b/server/request.c index f516617b8a..83cc8517a0 100644 --- a/server/request.c +++ b/server/request.c @@ -1535,7 +1535,7 @@ AP_DECLARE(int) ap_file_walk(request_rec *r) if (entry_core->condition) { /* XXX: error handling */ - if (!ap_expr_exec(r, entry_core->condition, &err)) { + if (ap_expr_exec(r, entry_core->condition, &err) <= 0) { continue; } } diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c index 30416bb89c..8e293e0498 100644 --- a/server/util_expr_eval.c +++ b/server/util_expr_eval.c @@ -38,12 +38,12 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(int, expr_lookup, (ap_expr_lookup_parms *parms), static const char *ap_expr_eval_string_func(ap_expr_eval_ctx *ctx, const ap_expr *info, const ap_expr *args); +static const char *ap_expr_eval_re_backref(ap_expr_eval_ctx *ctx, int n); static const char *ap_expr_eval_var(ap_expr_eval_ctx *ctx, const ap_expr_var_func_t *func, const void *data); /* define AP_EXPR_DEBUG to log the parse tree when parsing an expression */ -/*#define AP_EXPR_DEBUG */ #ifdef AP_EXPR_DEBUG static void expr_dump_tree(const ap_expr *e, const server_rec *s, int loglevel, int indent); #endif @@ -61,14 +61,30 @@ static const char *ap_expr_eval_word(ap_expr_eval_ctx *ctx, const ap_expr *node) case op_Var: result = ap_expr_eval_var(ctx, node->node_arg1, node->node_arg2); break; + case op_Concat: { + const char *s1 = ap_expr_eval_word(ctx, node->node_arg1); + const char *s2 = ap_expr_eval_word(ctx, node->node_arg2); + if (!*s1) + result = s2; + else if (!*s2) + result = s1; + else + result = apr_pstrcat(ctx->p, s1, s2, NULL); + break; + } case op_StringFuncCall: { const ap_expr *info = node->node_arg1; const ap_expr *args = node->node_arg2; result = ap_expr_eval_string_func(ctx, info, args); break; } + case op_RegexBackref: { + const int *np = node->node_arg1; + result = ap_expr_eval_re_backref(ctx, *np); + break; + } default: - *ctx->err = "Internal evaluation error: Unknown expression node"; + *ctx->err = "Internal evaluation error: Unknown word expression node"; break; } if (!result) @@ -85,6 +101,21 @@ static const char *ap_expr_eval_var(ap_expr_eval_ctx *ctx, return (*func)(ctx, data); } +static const char *ap_expr_eval_re_backref(ap_expr_eval_ctx *ctx, int n) +{ + int len; + + if (!ctx->re_pmatch || !ctx->re_source || *ctx->re_source == '\0' || + ctx->re_nmatch < n + 1) + return ""; + + len = ctx->re_pmatch[n].rm_eo - ctx->re_pmatch[n].rm_so; + if (len == 0) + return ""; + + return apr_pstrndup(ctx->p, *ctx->re_source + ctx->re_pmatch[n].rm_so, len); +} + static const char *ap_expr_eval_string_func(ap_expr_eval_ctx *ctx, const ap_expr *info, const ap_expr *arg) { @@ -206,32 +237,39 @@ static int ap_expr_eval_comp(ap_expr_eval_ctx *ctx, const ap_expr *node) } return 0; } - case op_REG: { - const ap_expr *e1; - const ap_expr *e2; - const char *word; - const ap_regex_t *regex; - - e1 = node->node_arg1; - e2 = node->node_arg2; - word = ap_expr_eval_word(ctx, e1); - regex = e2->node_arg1; - return (ap_regexec(regex, word, 0, NULL, 0) == 0); - } + case op_REG: case op_NRE: { const ap_expr *e1; const ap_expr *e2; const char *word; const ap_regex_t *regex; + int result; e1 = node->node_arg1; e2 = node->node_arg2; word = ap_expr_eval_word(ctx, e1); regex = e2->node_arg1; - return !(ap_regexec(regex, word, 0, NULL, 0) == 0); + + /* + * $0 ... $9 may contain stuff the user wants to keep. Therefore + * we only set them if there are capturing parens in the regex. + */ + if (regex->re_nsub > 0) { + result = (0 == ap_regexec(regex, word, ctx->re_nmatch, + ctx->re_pmatch, 0)); + *ctx->re_source = result ? word : NULL; + } + else { + result = (0 == ap_regexec(regex, word, 0, NULL, 0)); + } + + if (node->node_op == op_REG) + return result; + else + return !result; } default: { - *ctx->err = "Internal evaluation error: Unknown expression node"; + *ctx->err = "Internal evaluation error: Unknown comp expression node"; return -1; } } @@ -468,6 +506,8 @@ ap_expr *ap_expr_var_make(const char *name, ap_expr_parse_ctx *ctx) ap_log_error(MARK,"%*s%s: '%s' '%s'", indent, " ", op, (char *)s1, (char *)s2) #define DUMP_P(op, p1) \ ap_log_error(MARK,"%*s%s: %pp", indent, " ", op, p1); +#define DUMP_IP(op, p1) \ + ap_log_error(MARK,"%*s%s: %d", indent, " ", op, *(int *)p1); #define DUMP_S(op, s1) \ ap_log_error(MARK,"%*s%s: '%s'", indent, " ", op, (char *)s1) @@ -604,6 +644,10 @@ static void expr_dump_tree(const ap_expr *e, const server_rec *s, int loglevel, case op_Regex: DUMP_P("op_Regex", e->node_arg1); break; + /* arg1: pointer to int */ + case op_RegexBackref: + DUMP_IP("op_RegexBackref", e->node_arg1); + break; default: ap_log_error(MARK, "%*sERROR: INVALID OP %d", indent, " ", e->node_op); break; @@ -687,8 +731,14 @@ static int ap_expr_eval(ap_expr_eval_ctx *ctx, const ap_expr *node) } } - AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *info, const char **err) +{ + return ap_expr_exec_re(r, info, 0, NULL, NULL, err); +} + +AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *info, + apr_size_t nmatch, ap_regmatch_t *pmatch, + const char **source, const char **err) { ap_expr_eval_ctx ctx; int rc; @@ -698,6 +748,22 @@ AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *info, const c ctx.p = r->pool; ctx.err = err; ctx.info = info; + ctx.re_nmatch = nmatch; + ctx.re_pmatch = pmatch; + ctx.re_source = source; + ap_regmatch_t tmp_pmatch[10]; + const char *tmp_source; + + if (!pmatch) { + ctx.re_nmatch = 10; + ctx.re_pmatch = tmp_pmatch; + ctx.re_source = &tmp_source; + tmp_source = NULL; + } + else { + AP_DEBUG_ASSERT(source != NULL); + AP_DEBUG_ASSERT(nmatch > 0); + } *err = NULL; rc = ap_expr_eval(&ctx, info->root_node); diff --git a/server/util_expr_parse.c b/server/util_expr_parse.c index 5562e9e8f9..e1b656ca35 100644 --- a/server/util_expr_parse.c +++ b/server/util_expr_parse.c @@ -117,31 +117,32 @@ T_STRING = 263, T_REGEX = 264, T_REGEX_I = 265, - T_OP_UNARY = 266, - T_OP_BINARY = 267, - T_STR_BEGIN = 268, - T_STR_END = 269, - T_VAR_BEGIN = 270, - T_VAR_END = 271, - T_OP_EQ = 272, - T_OP_NE = 273, - T_OP_LT = 274, - T_OP_LE = 275, - T_OP_GT = 276, - T_OP_GE = 277, - T_OP_REG = 278, - T_OP_NRE = 279, - T_OP_IN = 280, - T_OP_STR_EQ = 281, - T_OP_STR_NE = 282, - T_OP_STR_LT = 283, - T_OP_STR_LE = 284, - T_OP_STR_GT = 285, - T_OP_STR_GE = 286, - T_OP_CONCAT = 287, - T_OP_OR = 288, - T_OP_AND = 289, - T_OP_NOT = 290 + T_REGEX_BACKREF = 266, + T_OP_UNARY = 267, + T_OP_BINARY = 268, + T_STR_BEGIN = 269, + T_STR_END = 270, + T_VAR_BEGIN = 271, + T_VAR_END = 272, + T_OP_EQ = 273, + T_OP_NE = 274, + T_OP_LT = 275, + T_OP_LE = 276, + T_OP_GT = 277, + T_OP_GE = 278, + T_OP_REG = 279, + T_OP_NRE = 280, + T_OP_IN = 281, + T_OP_STR_EQ = 282, + T_OP_STR_NE = 283, + T_OP_STR_LT = 284, + T_OP_STR_LE = 285, + T_OP_STR_GT = 286, + T_OP_STR_GE = 287, + T_OP_CONCAT = 288, + T_OP_OR = 289, + T_OP_AND = 290, + T_OP_NOT = 291 }; #endif @@ -156,11 +157,12 @@ typedef union YYSTYPE char *cpVal; ap_expr *exVal; + int num; /* Line 214 of yacc.c */ -#line 164 "util_expr_parse.c" +#line 166 "util_expr_parse.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -171,7 +173,7 @@ typedef union YYSTYPE /* Copy the second part of user declarations. */ /* Line 264 of yacc.c */ -#line 96 "util_expr_parse.y" +#line 99 "util_expr_parse.y" #include "util_expr_private.h" #define yyscanner ctx->scanner @@ -180,7 +182,7 @@ int ap_expr_yylex(YYSTYPE *lvalp, void *scanner); /* Line 264 of yacc.c */ -#line 184 "util_expr_parse.c" +#line 186 "util_expr_parse.c" #ifdef short # undef short @@ -393,22 +395,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 27 +#define YYFINAL 30 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 117 +#define YYLAST 122 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 42 +#define YYNTOKENS 43 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 13 +#define YYNNTS 14 /* YYNRULES -- Number of rules. */ -#define YYNRULES 47 +#define YYNRULES 50 /* YYNRULES -- Number of states. */ -#define YYNSTATES 88 +#define YYNSTATES 91 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 290 +#define YYMAXUTOK 291 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -420,15 +422,15 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 36, 37, 2, 2, 40, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 41, 2, + 37, 38, 2, 2, 41, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 38, 2, 39, 2, 2, 2, 2, + 2, 2, 2, 39, 2, 40, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -445,7 +447,7 @@ static const yytype_uint8 yytranslate[] = 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35 + 35, 36 }; #if YYDEBUG @@ -456,39 +458,42 @@ static const yytype_uint8 yyprhs[] = 0, 0, 3, 5, 7, 9, 11, 14, 18, 22, 24, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71, 75, 79, 83, 87, 91, 95, 97, - 101, 103, 107, 110, 112, 114, 116, 120, 126, 128, - 132, 134, 136, 140, 143, 145, 147, 152 + 101, 103, 107, 110, 112, 114, 116, 118, 122, 128, + 130, 134, 136, 138, 140, 144, 147, 149, 151, 153, + 158 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 43, 0, -1, 44, -1, 5, -1, 3, -1, 4, - -1, 35, 44, -1, 44, 33, 44, -1, 44, 34, - 44, -1, 45, -1, 11, 51, -1, 36, 44, 37, - -1, 51, 17, 51, -1, 51, 18, 51, -1, 51, - 19, 51, -1, 51, 20, 51, -1, 51, 21, 51, - -1, 51, 22, 51, -1, 51, 26, 51, -1, 51, - 27, 51, -1, 51, 28, 51, -1, 51, 29, 51, - -1, 51, 30, 51, -1, 51, 31, 51, -1, 51, - 25, 46, -1, 51, 23, 52, -1, 51, 24, 52, - -1, 51, 12, 51, -1, 53, -1, 38, 47, 39, - -1, 51, -1, 47, 40, 51, -1, 48, 49, -1, - 49, -1, 8, -1, 50, -1, 15, 7, 16, -1, - 15, 7, 41, 48, 16, -1, 6, -1, 51, 32, - 51, -1, 50, -1, 54, -1, 13, 48, 14, -1, - 13, 14, -1, 9, -1, 10, -1, 7, 36, 51, - 37, -1, 7, 36, 51, 37, -1 + 44, 0, -1, 45, -1, 5, -1, 3, -1, 4, + -1, 36, 45, -1, 45, 34, 45, -1, 45, 35, + 45, -1, 46, -1, 12, 52, -1, 37, 45, 38, + -1, 52, 18, 52, -1, 52, 19, 52, -1, 52, + 20, 52, -1, 52, 21, 52, -1, 52, 22, 52, + -1, 52, 23, 52, -1, 52, 27, 52, -1, 52, + 28, 52, -1, 52, 29, 52, -1, 52, 30, 52, + -1, 52, 31, 52, -1, 52, 32, 52, -1, 52, + 26, 47, -1, 52, 24, 53, -1, 52, 25, 53, + -1, 52, 13, 52, -1, 55, -1, 39, 48, 40, + -1, 52, -1, 48, 41, 52, -1, 49, 50, -1, + 50, -1, 8, -1, 51, -1, 54, -1, 16, 7, + 17, -1, 16, 7, 42, 49, 17, -1, 6, -1, + 52, 33, 52, -1, 51, -1, 54, -1, 56, -1, + 14, 49, 15, -1, 14, 15, -1, 9, -1, 10, + -1, 11, -1, 7, 37, 52, 38, -1, 7, 37, + 52, 38, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 106, 106, 107, 110, 111, 112, 113, 114, 115, - 116, 117, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 138, 139, - 142, 143, 146, 147, 151, 152, 155, 156, 159, 160, - 161, 162, 163, 164, 167, 176, 187, 190 + 0, 109, 109, 110, 113, 114, 115, 116, 117, 118, + 119, 120, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 141, 142, + 145, 146, 149, 150, 153, 154, 155, 158, 159, 162, + 163, 164, 165, 166, 167, 168, 171, 180, 191, 198, + 201 }; #endif @@ -498,14 +503,15 @@ static const yytype_uint8 yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "T_TRUE", "T_FALSE", "ERROR", "T_DIGIT", - "T_ID", "T_STRING", "T_REGEX", "T_REGEX_I", "T_OP_UNARY", "T_OP_BINARY", - "T_STR_BEGIN", "T_STR_END", "T_VAR_BEGIN", "T_VAR_END", "T_OP_EQ", - "T_OP_NE", "T_OP_LT", "T_OP_LE", "T_OP_GT", "T_OP_GE", "T_OP_REG", - "T_OP_NRE", "T_OP_IN", "T_OP_STR_EQ", "T_OP_STR_NE", "T_OP_STR_LT", - "T_OP_STR_LE", "T_OP_STR_GT", "T_OP_STR_GE", "T_OP_CONCAT", "T_OP_OR", - "T_OP_AND", "T_OP_NOT", "'('", "')'", "'{'", "'}'", "','", "':'", - "$accept", "root", "expr", "comparison", "wordlist", "words", "string", - "strpart", "var", "word", "regex", "lstfunccall", "strfunccall", 0 + "T_ID", "T_STRING", "T_REGEX", "T_REGEX_I", "T_REGEX_BACKREF", + "T_OP_UNARY", "T_OP_BINARY", "T_STR_BEGIN", "T_STR_END", "T_VAR_BEGIN", + "T_VAR_END", "T_OP_EQ", "T_OP_NE", "T_OP_LT", "T_OP_LE", "T_OP_GT", + "T_OP_GE", "T_OP_REG", "T_OP_NRE", "T_OP_IN", "T_OP_STR_EQ", + "T_OP_STR_NE", "T_OP_STR_LT", "T_OP_STR_LE", "T_OP_STR_GT", + "T_OP_STR_GE", "T_OP_CONCAT", "T_OP_OR", "T_OP_AND", "T_OP_NOT", "'('", + "')'", "'{'", "'}'", "','", "':'", "$accept", "root", "expr", + "comparison", "wordlist", "words", "string", "strpart", "var", "word", + "regex", "backref", "lstfunccall", "strfunccall", 0 }; #endif @@ -517,19 +523,20 @@ static const yytype_uint16 yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 40, 41, 123, 125, - 44, 58 + 285, 286, 287, 288, 289, 290, 291, 40, 41, 123, + 125, 44, 58 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 42, 43, 43, 44, 44, 44, 44, 44, 44, - 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, - 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, - 51, 51, 51, 51, 52, 52, 53, 54 + 0, 43, 44, 44, 45, 45, 45, 45, 45, 45, + 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, + 48, 48, 49, 49, 50, 50, 50, 51, 51, 52, + 52, 52, 52, 52, 52, 52, 53, 53, 54, 55, + 56 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -538,8 +545,9 @@ static const yytype_uint8 yyr2[] = 0, 2, 1, 1, 1, 1, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, - 1, 3, 2, 1, 1, 1, 3, 5, 1, 3, - 1, 1, 3, 2, 1, 1, 4, 4 + 1, 3, 2, 1, 1, 1, 1, 3, 5, 1, + 3, 1, 1, 1, 3, 2, 1, 1, 1, 4, + 4 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -547,22 +555,23 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 4, 5, 3, 38, 0, 0, 0, 0, 0, - 0, 0, 2, 9, 40, 0, 41, 0, 10, 34, - 43, 0, 33, 35, 0, 6, 0, 1, 0, 0, + 0, 4, 5, 3, 39, 0, 48, 0, 0, 0, + 0, 0, 0, 2, 9, 41, 0, 42, 43, 0, + 10, 34, 45, 0, 33, 35, 36, 0, 6, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 42, 32, - 36, 0, 11, 7, 8, 27, 12, 13, 14, 15, - 16, 17, 44, 45, 25, 26, 0, 0, 24, 28, - 18, 19, 20, 21, 22, 23, 39, 47, 0, 0, - 0, 30, 37, 0, 29, 0, 46, 31 + 0, 44, 32, 37, 0, 11, 7, 8, 27, 12, + 13, 14, 15, 16, 17, 46, 47, 25, 26, 0, + 0, 24, 28, 18, 19, 20, 21, 22, 23, 40, + 50, 0, 0, 0, 30, 38, 0, 29, 0, 49, + 31 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 11, 12, 13, 68, 80, 21, 22, 14, 15, - 64, 69, 16 + -1, 12, 13, 14, 71, 83, 23, 24, 15, 16, + 67, 17, 72, 18 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing @@ -570,22 +579,23 @@ static const yytype_int8 yydefgoto[] = #define YYPACT_NINF -29 static const yytype_int8 yypact[] = { - 49, -29, -29, -29, -29, 12, 1, 35, 25, 65, - 65, 57, -15, -29, -29, 85, -29, 1, 31, -29, - -29, 51, -29, -29, -10, -29, 53, -29, 65, 65, - 1, 1, 1, 1, 1, 1, 1, 11, 11, -5, - 1, 1, 1, 1, 1, 1, 1, -28, -29, -29, - -29, 36, -29, 33, -29, 31, 31, 31, 31, 31, - 31, 31, -29, -29, -29, -29, 34, 1, -29, -29, - 31, 31, 31, 31, 31, 31, -29, -29, -3, 1, - 6, 31, -29, -22, -29, 1, -29, 31 + 50, -29, -29, -29, -29, -13, -29, 9, -6, 14, + 85, 85, 48, -28, -29, -29, 87, -29, -29, 9, + 25, -29, -29, 36, -29, -29, -29, -9, -29, 45, + -29, 85, 85, 9, 9, 9, 9, 9, 9, 9, + 60, 60, 4, 9, 9, 9, 9, 9, 9, 9, + -16, -29, -29, -29, 74, -29, 43, -29, 25, 25, + 25, 25, 25, 25, 25, -29, -29, -29, -29, 23, + 9, -29, -29, 25, 25, 25, 25, 25, 25, -29, + -29, 57, 9, 5, 25, -29, 34, -29, 9, -29, + 25 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -29, -29, 13, -29, -29, -29, 24, -20, -4, -6, - 39, -29, -29 + -29, -29, 3, -29, -29, -29, 17, -22, -5, -7, + 52, -4, -29, -29 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -595,49 +605,52 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 18, 49, 66, 23, 46, 19, 50, 4, 5, 77, - 46, 47, 8, 82, 7, 86, 8, 23, 28, 29, - 62, 63, 25, 26, 55, 56, 57, 58, 59, 60, - 61, 51, 24, 67, 70, 71, 72, 73, 74, 75, - 76, 53, 54, 19, 19, 84, 85, 23, 17, 20, - 8, 8, 1, 2, 3, 4, 5, 27, 49, 19, - 6, 81, 7, 46, 8, 48, 8, 29, 1, 2, - 79, 4, 5, 83, 23, 78, 6, 65, 7, 87, - 8, 0, 0, 0, 9, 10, 28, 29, 0, 0, - 52, 0, 0, 0, 0, 0, 0, 30, 0, 0, - 9, 10, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46 + 20, 52, 21, 25, 26, 6, 31, 32, 53, 22, + 9, 69, 50, 28, 29, 4, 5, 49, 25, 26, + 6, 27, 80, 8, 19, 9, 58, 59, 60, 61, + 62, 63, 64, 54, 56, 57, 73, 74, 75, 76, + 77, 78, 79, 70, 21, 87, 88, 6, 30, 25, + 26, 51, 9, 1, 2, 3, 4, 5, 49, 52, + 82, 6, 7, 84, 8, 21, 9, 49, 6, 65, + 66, 81, 89, 9, 85, 86, 25, 26, 32, 31, + 32, 90, 21, 55, 0, 6, 10, 11, 1, 2, + 9, 4, 5, 68, 0, 0, 6, 7, 0, 8, + 33, 9, 0, 0, 0, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 10, 11 }; static const yytype_int8 yycheck[] = { - 6, 21, 7, 7, 32, 8, 16, 6, 7, 37, - 32, 17, 15, 16, 13, 37, 15, 21, 33, 34, - 9, 10, 9, 10, 30, 31, 32, 33, 34, 35, - 36, 41, 7, 38, 40, 41, 42, 43, 44, 45, - 46, 28, 29, 8, 8, 39, 40, 51, 36, 14, - 15, 15, 3, 4, 5, 6, 7, 0, 78, 8, - 11, 67, 13, 32, 15, 14, 15, 34, 3, 4, - 36, 6, 7, 79, 78, 51, 11, 38, 13, 85, - 15, -1, -1, -1, 35, 36, 33, 34, -1, -1, - 37, -1, -1, -1, -1, -1, -1, 12, -1, -1, - 35, 36, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32 + 7, 23, 8, 8, 8, 11, 34, 35, 17, 15, + 16, 7, 19, 10, 11, 6, 7, 33, 23, 23, + 11, 7, 38, 14, 37, 16, 33, 34, 35, 36, + 37, 38, 39, 42, 31, 32, 43, 44, 45, 46, + 47, 48, 49, 39, 8, 40, 41, 11, 0, 54, + 54, 15, 16, 3, 4, 5, 6, 7, 33, 81, + 37, 11, 12, 70, 14, 8, 16, 33, 11, 9, + 10, 54, 38, 16, 17, 82, 81, 81, 35, 34, + 35, 88, 8, 38, -1, 11, 36, 37, 3, 4, + 16, 6, 7, 41, -1, -1, 11, 12, -1, 14, + 13, 16, -1, -1, -1, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 36, 37 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 5, 6, 7, 11, 13, 15, 35, - 36, 43, 44, 45, 50, 51, 54, 36, 51, 8, - 14, 48, 49, 50, 7, 44, 44, 0, 33, 34, - 12, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 51, 14, 49, - 16, 41, 37, 44, 44, 51, 51, 51, 51, 51, - 51, 51, 9, 10, 52, 52, 7, 38, 46, 53, - 51, 51, 51, 51, 51, 51, 51, 37, 48, 36, - 47, 51, 16, 51, 39, 40, 37, 51 + 0, 3, 4, 5, 6, 7, 11, 12, 14, 16, + 36, 37, 44, 45, 46, 51, 52, 54, 56, 37, + 52, 8, 15, 49, 50, 51, 54, 7, 45, 45, + 0, 34, 35, 13, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 52, 15, 50, 17, 42, 38, 45, 45, 52, 52, + 52, 52, 52, 52, 52, 9, 10, 53, 53, 7, + 39, 47, 55, 52, 52, 52, 52, 52, 52, 52, + 38, 49, 37, 48, 52, 17, 52, 40, 41, 38, + 52 }; #define yyerrok (yyerrstatus = 0) @@ -1456,238 +1469,238 @@ yyreduce: case 2: /* Line 1455 of yacc.c */ -#line 106 "util_expr_parse.y" +#line 109 "util_expr_parse.y" { ctx->expr = (yyvsp[(1) - (1)].exVal); ;} break; case 3: /* Line 1455 of yacc.c */ -#line 107 "util_expr_parse.y" +#line 110 "util_expr_parse.y" { YYABORT; ;} break; case 4: /* Line 1455 of yacc.c */ -#line 110 "util_expr_parse.y" +#line 113 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_True, NULL, NULL, ctx); ;} break; case 5: /* Line 1455 of yacc.c */ -#line 111 "util_expr_parse.y" +#line 114 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_False, NULL, NULL, ctx); ;} break; case 6: /* Line 1455 of yacc.c */ -#line 112 "util_expr_parse.y" +#line 115 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_Not, (yyvsp[(2) - (2)].exVal), NULL, ctx); ;} break; case 7: /* Line 1455 of yacc.c */ -#line 113 "util_expr_parse.y" +#line 116 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_Or, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 8: /* Line 1455 of yacc.c */ -#line 114 "util_expr_parse.y" +#line 117 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_And, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 9: /* Line 1455 of yacc.c */ -#line 115 "util_expr_parse.y" +#line 118 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_Comp, (yyvsp[(1) - (1)].exVal), NULL, ctx); ;} break; case 10: /* Line 1455 of yacc.c */ -#line 116 "util_expr_parse.y" +#line 119 "util_expr_parse.y" { (yyval.exVal) = ap_expr_unary_op_make( (yyvsp[(1) - (2)].cpVal), (yyvsp[(2) - (2)].exVal), ctx); ;} break; case 11: /* Line 1455 of yacc.c */ -#line 117 "util_expr_parse.y" +#line 120 "util_expr_parse.y" { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;} break; case 12: /* Line 1455 of yacc.c */ -#line 120 "util_expr_parse.y" +#line 123 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_EQ, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 13: /* Line 1455 of yacc.c */ -#line 121 "util_expr_parse.y" +#line 124 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_NE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 14: /* Line 1455 of yacc.c */ -#line 122 "util_expr_parse.y" +#line 125 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_LT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 15: /* Line 1455 of yacc.c */ -#line 123 "util_expr_parse.y" +#line 126 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_LE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 16: /* Line 1455 of yacc.c */ -#line 124 "util_expr_parse.y" +#line 127 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_GT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 17: /* Line 1455 of yacc.c */ -#line 125 "util_expr_parse.y" +#line 128 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_GE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 18: /* Line 1455 of yacc.c */ -#line 126 "util_expr_parse.y" +#line 129 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_STR_EQ, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 19: /* Line 1455 of yacc.c */ -#line 127 "util_expr_parse.y" +#line 130 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_STR_NE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 20: /* Line 1455 of yacc.c */ -#line 128 "util_expr_parse.y" +#line 131 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_STR_LT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 21: /* Line 1455 of yacc.c */ -#line 129 "util_expr_parse.y" +#line 132 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_STR_LE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 22: /* Line 1455 of yacc.c */ -#line 130 "util_expr_parse.y" +#line 133 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_STR_GT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 23: /* Line 1455 of yacc.c */ -#line 131 "util_expr_parse.y" +#line 134 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_STR_GE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 24: /* Line 1455 of yacc.c */ -#line 132 "util_expr_parse.y" +#line 135 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_IN, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 25: /* Line 1455 of yacc.c */ -#line 133 "util_expr_parse.y" +#line 136 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_REG, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 26: /* Line 1455 of yacc.c */ -#line 134 "util_expr_parse.y" +#line 137 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_NRE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 27: /* Line 1455 of yacc.c */ -#line 135 "util_expr_parse.y" +#line 138 "util_expr_parse.y" { (yyval.exVal) = ap_expr_binary_op_make((yyvsp[(2) - (3)].cpVal), (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 28: /* Line 1455 of yacc.c */ -#line 138 "util_expr_parse.y" +#line 141 "util_expr_parse.y" { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;} break; case 29: /* Line 1455 of yacc.c */ -#line 139 "util_expr_parse.y" +#line 142 "util_expr_parse.y" { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;} break; case 30: /* Line 1455 of yacc.c */ -#line 142 "util_expr_parse.y" +#line 145 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(1) - (1)].exVal), NULL, ctx); ;} break; case 31: /* Line 1455 of yacc.c */ -#line 143 "util_expr_parse.y" +#line 146 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(3) - (3)].exVal), (yyvsp[(1) - (3)].exVal), ctx); ;} break; case 32: /* Line 1455 of yacc.c */ -#line 146 "util_expr_parse.y" +#line 149 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (2)].exVal), (yyvsp[(2) - (2)].exVal), ctx); ;} break; case 33: /* Line 1455 of yacc.c */ -#line 147 "util_expr_parse.y" +#line 150 "util_expr_parse.y" { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;} break; case 34: /* Line 1455 of yacc.c */ -#line 151 "util_expr_parse.y" +#line 153 "util_expr_parse.y" { (yyval.exVal) = ap_expr_make(op_String, (yyvsp[(1) - (1)].cpVal), NULL, ctx); ;} break; case 35: /* Line 1455 of yacc.c */ -#line 152 "util_expr_parse.y" +#line 154 "util_expr_parse.y" { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;} break; @@ -1695,62 +1708,76 @@ yyreduce: /* Line 1455 of yacc.c */ #line 155 "util_expr_parse.y" - { (yyval.exVal) = ap_expr_var_make((yyvsp[(2) - (3)].cpVal), ctx); ;} + { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;} break; case 37: /* Line 1455 of yacc.c */ -#line 156 "util_expr_parse.y" - { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(2) - (5)].cpVal), (yyvsp[(4) - (5)].exVal), ctx); ;} +#line 158 "util_expr_parse.y" + { (yyval.exVal) = ap_expr_var_make((yyvsp[(2) - (3)].cpVal), ctx); ;} break; case 38: /* Line 1455 of yacc.c */ #line 159 "util_expr_parse.y" - { (yyval.exVal) = ap_expr_make(op_Digit, (yyvsp[(1) - (1)].cpVal), NULL, ctx); ;} + { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(2) - (5)].cpVal), (yyvsp[(4) - (5)].exVal), ctx); ;} break; case 39: /* Line 1455 of yacc.c */ -#line 160 "util_expr_parse.y" - { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} +#line 162 "util_expr_parse.y" + { (yyval.exVal) = ap_expr_make(op_Digit, (yyvsp[(1) - (1)].cpVal), NULL, ctx); ;} break; case 40: /* Line 1455 of yacc.c */ -#line 161 "util_expr_parse.y" - { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;} +#line 163 "util_expr_parse.y" + { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;} break; case 41: /* Line 1455 of yacc.c */ -#line 162 "util_expr_parse.y" +#line 164 "util_expr_parse.y" { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;} break; case 42: /* Line 1455 of yacc.c */ -#line 163 "util_expr_parse.y" - { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;} +#line 165 "util_expr_parse.y" + { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;} break; case 43: /* Line 1455 of yacc.c */ -#line 164 "util_expr_parse.y" - { (yyval.exVal) = ap_expr_make(op_String, "", NULL, ctx); ;} +#line 166 "util_expr_parse.y" + { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;} break; case 44: /* Line 1455 of yacc.c */ #line 167 "util_expr_parse.y" + { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;} + break; + + case 45: + +/* Line 1455 of yacc.c */ +#line 168 "util_expr_parse.y" + { (yyval.exVal) = ap_expr_make(op_String, "", NULL, ctx); ;} + break; + + case 46: + +/* Line 1455 of yacc.c */ +#line 171 "util_expr_parse.y" { ap_regex_t *regex; if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal), @@ -1762,10 +1789,10 @@ yyreduce: ;} break; - case 45: + case 47: /* Line 1455 of yacc.c */ -#line 176 "util_expr_parse.y" +#line 180 "util_expr_parse.y" { ap_regex_t *regex; if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal), @@ -1777,24 +1804,35 @@ yyreduce: ;} break; - case 46: + case 48: /* Line 1455 of yacc.c */ -#line 187 "util_expr_parse.y" +#line 191 "util_expr_parse.y" + { + int *n = apr_palloc(ctx->pool, sizeof(int)); + *n = (yyvsp[(1) - (1)].num); + (yyval.exVal) = ap_expr_make(op_RegexBackref, n, NULL, ctx); + ;} + break; + + case 49: + +/* Line 1455 of yacc.c */ +#line 198 "util_expr_parse.y" { (yyval.exVal) = ap_expr_list_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); ;} break; - case 47: + case 50: /* Line 1455 of yacc.c */ -#line 190 "util_expr_parse.y" +#line 201 "util_expr_parse.y" { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); ;} break; /* Line 1455 of yacc.c */ -#line 1798 "util_expr_parse.c" +#line 1836 "util_expr_parse.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2006,7 +2044,7 @@ yyreturn: /* Line 1675 of yacc.c */ -#line 193 "util_expr_parse.y" +#line 204 "util_expr_parse.y" void yyerror(ap_expr_parse_ctx *ctx, char *s) diff --git a/server/util_expr_parse.h b/server/util_expr_parse.h index f806e0121f..f0f3431cb4 100644 --- a/server/util_expr_parse.h +++ b/server/util_expr_parse.h @@ -47,31 +47,32 @@ T_STRING = 263, T_REGEX = 264, T_REGEX_I = 265, - T_OP_UNARY = 266, - T_OP_BINARY = 267, - T_STR_BEGIN = 268, - T_STR_END = 269, - T_VAR_BEGIN = 270, - T_VAR_END = 271, - T_OP_EQ = 272, - T_OP_NE = 273, - T_OP_LT = 274, - T_OP_LE = 275, - T_OP_GT = 276, - T_OP_GE = 277, - T_OP_REG = 278, - T_OP_NRE = 279, - T_OP_IN = 280, - T_OP_STR_EQ = 281, - T_OP_STR_NE = 282, - T_OP_STR_LT = 283, - T_OP_STR_LE = 284, - T_OP_STR_GT = 285, - T_OP_STR_GE = 286, - T_OP_CONCAT = 287, - T_OP_OR = 288, - T_OP_AND = 289, - T_OP_NOT = 290 + T_REGEX_BACKREF = 266, + T_OP_UNARY = 267, + T_OP_BINARY = 268, + T_STR_BEGIN = 269, + T_STR_END = 270, + T_VAR_BEGIN = 271, + T_VAR_END = 272, + T_OP_EQ = 273, + T_OP_NE = 274, + T_OP_LT = 275, + T_OP_LE = 276, + T_OP_GT = 277, + T_OP_GE = 278, + T_OP_REG = 279, + T_OP_NRE = 280, + T_OP_IN = 281, + T_OP_STR_EQ = 282, + T_OP_STR_NE = 283, + T_OP_STR_LT = 284, + T_OP_STR_LE = 285, + T_OP_STR_GT = 286, + T_OP_STR_GE = 287, + T_OP_CONCAT = 288, + T_OP_OR = 289, + T_OP_AND = 290, + T_OP_NOT = 291 }; #endif @@ -86,11 +87,12 @@ typedef union YYSTYPE char *cpVal; ap_expr *exVal; + int num; /* Line 1676 of yacc.c */ -#line 94 "util_expr_parse.h" +#line 96 "util_expr_parse.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ diff --git a/server/util_expr_parse.y b/server/util_expr_parse.y index c79eee5940..568597f7ca 100644 --- a/server/util_expr_parse.y +++ b/server/util_expr_parse.y @@ -35,6 +35,7 @@ %union { char *cpVal; ap_expr *exVal; + int num; } %token T_TRUE @@ -47,6 +48,7 @@ %token T_STRING %token T_REGEX %token T_REGEX_I +%token T_REGEX_BACKREF %token T_OP_UNARY %token T_OP_BINARY @@ -92,6 +94,7 @@ %type string %type strpart %type var +%type backref %{ #include "util_expr_private.h" @@ -147,9 +150,9 @@ string : string strpart { $$ = ap_expr_make(op_Concat, $1, $2, | strpart { $$ = $1; } ; - strpart : T_STRING { $$ = ap_expr_make(op_String, $1, NULL, ctx); } | var { $$ = $1; } + | backref { $$ = $1; } ; var : T_VAR_BEGIN T_ID T_VAR_END { $$ = ap_expr_var_make($2, ctx); } @@ -159,6 +162,7 @@ var : T_VAR_BEGIN T_ID T_VAR_END { $$ = ap_expr_var_make($2, ct word : T_DIGIT { $$ = ap_expr_make(op_Digit, $1, NULL, ctx); } | word T_OP_CONCAT word { $$ = ap_expr_make(op_Concat, $1, $3, ctx); } | var { $$ = $1; } + | backref { $$ = $1; } | strfunccall { $$ = $1; } | T_STR_BEGIN string T_STR_END { $$ = $2; } | T_STR_BEGIN T_STR_END { $$ = ap_expr_make(op_String, "", NULL, ctx); } @@ -184,6 +188,13 @@ regex : T_REGEX { } ; +backref : T_REGEX_BACKREF { + int *n = apr_palloc(ctx->pool, sizeof(int)); + *n = $1; + $$ = ap_expr_make(op_RegexBackref, n, NULL, ctx); + } + ; + lstfunccall : T_ID '(' word ')' { $$ = ap_expr_list_func_make($1, $3, ctx); } ; diff --git a/server/util_expr_private.h b/server/util_expr_private.h index 48d1199a79..517c87d126 100644 --- a/server/util_expr_private.h +++ b/server/util_expr_private.h @@ -44,7 +44,7 @@ typedef enum { op_REG, op_NRE, op_STR_EQ, op_STR_NE, op_STR_LT, op_STR_LE, op_STR_GT, op_STR_GE, op_Concat, - op_Digit, op_String, op_Regex, + op_Digit, op_String, op_Regex, op_RegexBackref, op_Var, op_ListElement, /* diff --git a/server/util_expr_scan.c b/server/util_expr_scan.c index e9ff5a152e..a366134d87 100644 --- a/server/util_expr_scan.c +++ b/server/util_expr_scan.c @@ -358,8 +358,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 65 -#define YY_END_OF_BUFFER 66 +#define YY_NUM_RULES 67 +#define YY_END_OF_BUFFER 68 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -367,21 +367,22 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[119] = +static yyconst flex_int16_t yy_accept[124] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 66, 64, 1, 41, 2, 64, 64, 63, - 64, 42, 24, 61, 30, 28, 32, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 64, 13, - 4, 3, 16, 65, 16, 21, 4, 20, 18, 19, - 65, 15, 22, 25, 27, 26, 1, 29, 35, 17, - 37, 61, 57, 57, 57, 57, 57, 57, 31, 28, - 34, 33, 62, 62, 55, 62, 53, 52, 56, 51, - 50, 23, 23, 54, 62, 38, 62, 39, 13, 14, - 12, 5, 6, 10, 11, 7, 8, 9, 18, 58, - - 44, 46, 48, 43, 47, 49, 45, 36, 62, 40, - 62, 5, 6, 62, 59, 5, 60, 0 + 0, 0, 68, 66, 1, 43, 2, 66, 66, 66, + 65, 66, 44, 26, 63, 32, 30, 34, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 66, + 14, 4, 3, 17, 17, 67, 17, 23, 4, 22, + 20, 21, 67, 16, 16, 24, 27, 29, 28, 1, + 31, 37, 19, 18, 39, 63, 59, 59, 59, 59, + 59, 59, 33, 30, 36, 35, 64, 64, 57, 64, + 55, 54, 58, 53, 52, 25, 25, 56, 64, 40, + 64, 41, 14, 13, 15, 12, 5, 6, 10, 11, + + 7, 8, 9, 20, 60, 46, 48, 50, 45, 49, + 51, 47, 38, 64, 42, 64, 5, 6, 64, 61, + 5, 62, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -389,17 +390,17 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 6, 6, 7, 8, 5, 9, - 9, 1, 1, 10, 11, 12, 13, 14, 14, 14, - 14, 14, 14, 14, 14, 15, 15, 16, 6, 17, - 18, 19, 6, 1, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 1, 21, 1, 6, 22, 1, 23, 24, 20, 25, - - 26, 27, 28, 20, 29, 20, 20, 30, 31, 32, - 33, 20, 34, 35, 36, 37, 38, 20, 20, 20, - 20, 20, 39, 40, 41, 42, 1, 1, 1, 1, + 1, 2, 4, 5, 6, 7, 8, 9, 5, 10, + 10, 1, 1, 11, 12, 13, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 16, 16, 17, 6, 18, + 19, 20, 6, 1, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 1, 22, 1, 6, 23, 1, 24, 25, 21, 26, + + 27, 28, 29, 21, 30, 21, 21, 31, 32, 33, + 34, 21, 35, 36, 37, 38, 39, 21, 21, 21, + 21, 21, 40, 41, 42, 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -416,125 +417,129 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[43] = +static yyconst flex_int32_t yy_meta[44] = { 0, - 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, - 2, 1 + 1, 1, 2, 1, 2, 1, 2, 2, 1, 1, + 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, + 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, + 1, 2, 1 } ; -static yyconst flex_int16_t yy_base[128] = +static yyconst flex_int16_t yy_base[133] = { 0, - 0, 0, 40, 41, 82, 0, 122, 123, 0, 0, - 138, 133, 161, 260, 47, 33, 260, 121, 151, 260, - 151, 260, 260, 38, 140, 36, 139, 0, 124, 121, - 131, 29, 121, 30, 180, 31, 117, 116, 110, 0, - 260, 260, 110, 207, 260, 260, 260, 260, 0, 260, - 260, 260, 260, 260, 260, 260, 56, 260, 260, 260, - 260, 54, 0, 114, 34, 115, 37, 120, 260, 260, - 260, 260, 0, 120, 0, 112, 0, 0, 0, 0, - 0, 260, 0, 0, 104, 0, 102, 260, 0, 260, - 260, 58, 62, 260, 260, 260, 260, 260, 0, 260, - - 260, 260, 260, 260, 260, 260, 260, 0, 103, 0, - 112, 65, 117, 111, 0, 119, 0, 260, 244, 247, - 250, 133, 132, 253, 256, 67, 62 + 0, 0, 41, 47, 89, 0, 130, 136, 0, 0, + 147, 146, 175, 275, 54, 28, 275, 43, 134, 164, + 275, 164, 275, 275, 45, 152, 32, 151, 0, 136, + 133, 143, 26, 133, 35, 194, 38, 129, 128, 122, + 0, 275, 275, 51, 122, 221, 275, 275, 275, 275, + 0, 275, 275, 61, 121, 275, 275, 275, 275, 76, + 275, 275, 275, 275, 275, 65, 0, 125, 47, 126, + 107, 130, 275, 275, 275, 275, 0, 130, 0, 124, + 0, 0, 0, 0, 0, 275, 0, 0, 104, 0, + 101, 275, 0, 275, 275, 275, 71, 131, 275, 275, + + 275, 275, 275, 0, 275, 275, 275, 275, 275, 275, + 275, 275, 0, 99, 0, 61, 133, 135, 57, 0, + 138, 0, 275, 259, 262, 265, 79, 67, 268, 271, + 65, 42 } ; -static yyconst flex_int16_t yy_def[128] = +static yyconst flex_int16_t yy_def[133] = { 0, - 118, 1, 119, 119, 118, 5, 119, 119, 120, 120, - 121, 121, 118, 118, 118, 118, 118, 118, 118, 118, - 122, 118, 118, 118, 118, 118, 118, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 118, 124, - 118, 118, 118, 125, 118, 118, 118, 118, 126, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 127, 127, 127, 127, 127, 127, 118, 118, - 118, 118, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 118, 123, 123, 123, 123, 123, 118, 124, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 126, 118, - - 118, 118, 118, 118, 118, 118, 118, 123, 123, 123, - 123, 118, 118, 123, 123, 118, 123, 0, 118, 118, - 118, 118, 118, 118, 118, 118, 118 + 123, 1, 124, 124, 123, 5, 124, 124, 125, 125, + 126, 126, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 127, 123, 123, 123, 123, 123, 123, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 123, + 129, 123, 123, 123, 123, 130, 123, 123, 123, 123, + 131, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 132, 132, 132, 132, + 132, 132, 123, 123, 123, 123, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 123, 128, 128, 128, 128, + 128, 123, 129, 123, 123, 123, 123, 123, 123, 123, + + 123, 123, 123, 131, 123, 123, 123, 123, 123, 123, + 123, 123, 128, 128, 128, 128, 123, 123, 128, 128, + 123, 128, 0, 123, 123, 123, 123, 123, 123, 123, + 123, 123 } ; -static yyconst flex_int16_t yy_nxt[303] = +static yyconst flex_int16_t yy_nxt[319] = { 0, - 14, 15, 15, 16, 17, 14, 18, 19, 20, 20, - 21, 22, 23, 24, 24, 20, 25, 26, 27, 28, - 14, 14, 29, 28, 28, 30, 31, 32, 33, 34, - 35, 36, 37, 28, 28, 28, 38, 28, 20, 39, - 20, 14, 41, 41, 42, 42, 43, 43, 57, 57, - 58, 62, 62, 70, 77, 80, 84, 57, 57, 102, - 44, 44, 105, 85, 100, 78, 81, 62, 62, 99, - 103, 112, 113, 106, 59, 113, 113, 71, 116, 113, - 45, 45, 46, 46, 47, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 48, 46, 46, - - 46, 49, 46, 46, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 46, 46, 50, 46, 41, 41, 51, 51, 52, 52, - 113, 113, 113, 113, 73, 63, 117, 115, 114, 111, - 110, 109, 44, 44, 108, 107, 104, 101, 90, 88, - 87, 86, 79, 76, 75, 74, 72, 69, 61, 60, - 118, 56, 53, 53, 62, 62, 56, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 64, 118, 65, 66, - 67, 118, 68, 82, 82, 82, 82, 118, 118, 82, - 82, 82, 82, 118, 118, 82, 118, 118, 118, 118, - - 118, 83, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 82, - 92, 93, 118, 118, 118, 118, 118, 118, 118, 118, - 94, 118, 118, 95, 118, 118, 118, 118, 96, 118, - 118, 97, 118, 98, 40, 40, 40, 54, 54, 54, - 55, 55, 55, 89, 118, 89, 91, 91, 91, 13, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - - 118, 118 + 14, 15, 15, 16, 17, 14, 18, 19, 20, 21, + 21, 22, 23, 24, 25, 25, 21, 26, 27, 28, + 29, 14, 14, 30, 29, 29, 31, 32, 33, 34, + 35, 36, 37, 38, 29, 29, 29, 39, 29, 21, + 40, 21, 14, 42, 105, 43, 61, 44, 45, 42, + 74, 43, 81, 44, 45, 60, 60, 63, 63, 66, + 66, 84, 46, 82, 88, 94, 94, 104, 46, 77, + 62, 89, 85, 107, 75, 94, 94, 60, 60, 66, + 66, 67, 47, 122, 108, 117, 118, 120, 47, 48, + 48, 49, 48, 48, 48, 48, 48, 48, 48, 48, + + 48, 48, 48, 48, 48, 50, 48, 48, 48, 51, + 48, 48, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, + 52, 48, 42, 110, 53, 119, 54, 55, 42, 116, + 53, 115, 54, 55, 111, 118, 118, 121, 118, 118, + 118, 46, 118, 118, 114, 113, 112, 46, 109, 106, + 95, 95, 92, 91, 90, 83, 80, 79, 78, 76, + 73, 56, 65, 64, 123, 59, 59, 56, 66, 66, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 68, 123, 69, 70, 71, 123, 72, 86, 86, 86, + + 86, 86, 123, 123, 86, 86, 86, 86, 123, 123, + 86, 123, 123, 123, 123, 123, 87, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 86, 97, 98, 123, 123, 123, + 123, 123, 123, 123, 123, 99, 123, 123, 100, 123, + 123, 123, 123, 101, 123, 123, 102, 123, 103, 41, + 41, 41, 57, 57, 57, 58, 58, 58, 93, 123, + 93, 96, 96, 96, 13, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123 } ; -static yyconst flex_int16_t yy_chk[303] = +static yyconst flex_int16_t yy_chk[319] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 4, 3, 4, 3, 4, 15, 15, - 16, 24, 24, 26, 32, 34, 36, 57, 57, 65, - 3, 4, 67, 36, 127, 32, 34, 62, 62, 126, - 65, 92, 92, 67, 16, 93, 93, 26, 112, 112, - 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 1, 1, 1, 3, 132, 3, 16, 3, 3, 4, + 27, 4, 33, 4, 4, 15, 15, 18, 18, 25, + 25, 35, 3, 33, 37, 44, 44, 131, 4, 128, + 16, 37, 35, 69, 27, 54, 54, 60, 60, 66, + 66, 127, 3, 119, 69, 97, 97, 116, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 7, 8, 7, 8, 7, 8, - 113, 113, 116, 116, 123, 122, 114, 111, 109, 87, - 85, 76, 7, 8, 74, 68, 66, 64, 43, 39, - 38, 37, 33, 31, 30, 29, 27, 25, 19, 18, - 13, 12, 7, 8, 21, 21, 11, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 21, 0, 21, 21, - 21, 0, 21, 35, 35, 35, 35, 0, 0, 35, - 35, 35, 35, 0, 0, 35, 0, 0, 0, 0, - - 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, - 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, - 44, 0, 0, 44, 0, 0, 0, 0, 44, 0, - 0, 44, 0, 44, 119, 119, 119, 120, 120, 120, - 121, 121, 121, 124, 0, 124, 125, 125, 125, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - - 118, 118 + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 7, 71, 7, 114, 7, 7, 8, 91, + 8, 89, 8, 8, 71, 98, 98, 117, 117, 118, + 118, 7, 121, 121, 80, 78, 72, 8, 70, 68, + 55, 45, 40, 39, 38, 34, 32, 31, 30, 28, + 26, 7, 20, 19, 13, 12, 11, 8, 22, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 0, 22, 22, 22, 0, 22, 36, 36, 36, + + 36, 36, 0, 0, 36, 36, 36, 36, 0, 0, + 36, 0, 0, 0, 0, 0, 36, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 36, 46, 46, 0, 0, 0, + 0, 0, 0, 0, 0, 46, 0, 0, 46, 0, + 0, 0, 0, 46, 0, 0, 46, 0, 46, 124, + 124, 124, 125, 125, 125, 126, 126, 126, 129, 0, + 129, 130, 130, 130, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123 } ; /* The intent behind this definition is that it'll catch @@ -600,7 +605,7 @@ static yyconst flex_int16_t yy_chk[303] = #define str_buf (yyextra->scan_buf) #define str_del (yyextra->scan_del) -#line 604 "util_expr_scan.c" +#line 609 "util_expr_scan.c" #define INITIAL 0 #define str 1 @@ -855,7 +860,7 @@ YY_DECL /* * Whitespaces */ -#line 859 "util_expr_scan.c" +#line 864 "util_expr_scan.c" yylval = yylval_param; @@ -910,13 +915,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 119 ) + if ( yy_current_state >= 124 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 118 ); + while ( yy_current_state != 123 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1054,19 +1059,38 @@ YY_RULE_SETUP *str_ptr++ = yytext[1]; } YY_BREAK +/* regexp backref inside string/arg */ case 13: YY_RULE_SETUP -#line 145 "util_expr_scan.l" +#line 146 "util_expr_scan.l" +{ + if (str_ptr != str_buf) { + /* return what we have so far and scan '$x' again */ + *str_ptr = '\0'; + yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf); + str_ptr = str_buf; + yyless(0); + return T_STRING; + } + else { + yylval->num = yytext[1] - '0'; + return T_REGEX_BACKREF; + } +} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 161 "util_expr_scan.l" { char *cp = yytext; while (*cp != '\0') *str_ptr++ = *cp++; } YY_BREAK -/* variable inside string */ -case 14: +/* variable inside string/arg */ +case 15: YY_RULE_SETUP -#line 152 "util_expr_scan.l" +#line 168 "util_expr_scan.l" { if (str_ptr != str_buf) { /* return what we have so far and scan '%{' again */ @@ -1082,68 +1106,76 @@ YY_RULE_SETUP } } YY_BREAK -case 15: +case 16: YY_RULE_SETUP -#line 167 "util_expr_scan.l" +#line 183 "util_expr_scan.l" { *str_ptr++ = yytext[0]; } YY_BREAK -case 16: +case 17: YY_RULE_SETUP -#line 171 "util_expr_scan.l" +#line 187 "util_expr_scan.l" { *str_ptr++ = yytext[0]; } YY_BREAK -case 17: +case 18: YY_RULE_SETUP -#line 175 "util_expr_scan.l" +#line 191 "util_expr_scan.l" { yy_push_state(var, yyscanner); return T_VAR_BEGIN; } YY_BREAK +case 19: +YY_RULE_SETUP +#line 196 "util_expr_scan.l" +{ + yylval->num = yytext[1] - '0'; + return T_REGEX_BACKREF; +} + YY_BREAK /* * fixed name variable expansion %{XXX} and function call in %{func:arg} syntax */ -case 18: +case 20: YY_RULE_SETUP -#line 183 "util_expr_scan.l" +#line 204 "util_expr_scan.l" { yylval->cpVal = apr_pstrdup(yyextra->pool, yytext); return T_ID; } YY_BREAK -case 19: +case 21: YY_RULE_SETUP -#line 188 "util_expr_scan.l" +#line 209 "util_expr_scan.l" { yy_pop_state(yyscanner); return T_VAR_END; } YY_BREAK -case 20: +case 22: YY_RULE_SETUP -#line 193 "util_expr_scan.l" +#line 214 "util_expr_scan.l" { BEGIN(vararg); return yytext[0]; } YY_BREAK -case 21: -/* rule 21 can match eol */ +case 23: +/* rule 23 can match eol */ YY_RULE_SETUP -#line 198 "util_expr_scan.l" +#line 219 "util_expr_scan.l" { char *msg = apr_psprintf(yyextra->pool, "Invalid character in variable name '%c'", yytext[0]); PERROR(msg); } YY_BREAK -case 22: +case 24: YY_RULE_SETUP -#line 204 "util_expr_scan.l" +#line 225 "util_expr_scan.l" { if (str_ptr != str_buf) { /* return what we have so far and scan '}' again */ @@ -1162,28 +1194,28 @@ YY_RULE_SETUP /* * Regular Expression */ -case 23: +case 25: YY_RULE_SETUP -#line 222 "util_expr_scan.l" +#line 243 "util_expr_scan.l" { regex_del = yytext[1]; regex_ptr = regex_buf; BEGIN(regex); } YY_BREAK -case 24: +case 26: YY_RULE_SETUP -#line 227 "util_expr_scan.l" +#line 248 "util_expr_scan.l" { regex_del = yytext[0]; regex_ptr = regex_buf; BEGIN(regex); } YY_BREAK -case 25: -/* rule 25 can match eol */ +case 27: +/* rule 27 can match eol */ YY_RULE_SETUP -#line 232 "util_expr_scan.l" +#line 253 "util_expr_scan.l" { if (yytext[0] == regex_del) { *regex_ptr = '\0'; @@ -1194,19 +1226,19 @@ YY_RULE_SETUP } } YY_BREAK -case 26: +case 28: YY_RULE_SETUP -#line 241 "util_expr_scan.l" +#line 262 "util_expr_scan.l" { yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf); BEGIN(INITIAL); return T_REGEX_I; } YY_BREAK -case 27: -/* rule 27 can match eol */ +case 29: +/* rule 29 can match eol */ YY_RULE_SETUP -#line 246 "util_expr_scan.l" +#line 267 "util_expr_scan.l" { yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf); yyless(0); @@ -1215,7 +1247,7 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(regex_flags): -#line 252 "util_expr_scan.l" +#line 273 "util_expr_scan.l" { yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf); BEGIN(INITIAL); @@ -1225,163 +1257,163 @@ case YY_STATE_EOF(regex_flags): /* * Operators */ -case 28: +case 30: YY_RULE_SETUP -#line 261 "util_expr_scan.l" +#line 282 "util_expr_scan.l" { return T_OP_STR_EQ; } YY_BREAK -case 29: +case 31: YY_RULE_SETUP -#line 262 "util_expr_scan.l" +#line 283 "util_expr_scan.l" { return T_OP_STR_NE; } YY_BREAK -case 30: +case 32: YY_RULE_SETUP -#line 263 "util_expr_scan.l" +#line 284 "util_expr_scan.l" { return T_OP_STR_LT; } YY_BREAK -case 31: +case 33: YY_RULE_SETUP -#line 264 "util_expr_scan.l" +#line 285 "util_expr_scan.l" { return T_OP_STR_LE; } YY_BREAK -case 32: +case 34: YY_RULE_SETUP -#line 265 "util_expr_scan.l" +#line 286 "util_expr_scan.l" { return T_OP_STR_GT; } YY_BREAK -case 33: +case 35: YY_RULE_SETUP -#line 266 "util_expr_scan.l" +#line 287 "util_expr_scan.l" { return T_OP_STR_GE; } YY_BREAK -case 34: +case 36: YY_RULE_SETUP -#line 267 "util_expr_scan.l" +#line 288 "util_expr_scan.l" { return T_OP_REG; } YY_BREAK -case 35: +case 37: YY_RULE_SETUP -#line 268 "util_expr_scan.l" +#line 289 "util_expr_scan.l" { return T_OP_NRE; } YY_BREAK -case 36: +case 38: YY_RULE_SETUP -#line 269 "util_expr_scan.l" +#line 290 "util_expr_scan.l" { return T_OP_AND; } YY_BREAK -case 37: +case 39: YY_RULE_SETUP -#line 270 "util_expr_scan.l" +#line 291 "util_expr_scan.l" { return T_OP_AND; } YY_BREAK -case 38: +case 40: YY_RULE_SETUP -#line 271 "util_expr_scan.l" +#line 292 "util_expr_scan.l" { return T_OP_OR; } YY_BREAK -case 39: +case 41: YY_RULE_SETUP -#line 272 "util_expr_scan.l" +#line 293 "util_expr_scan.l" { return T_OP_OR; } YY_BREAK -case 40: +case 42: YY_RULE_SETUP -#line 273 "util_expr_scan.l" +#line 294 "util_expr_scan.l" { return T_OP_NOT; } YY_BREAK -case 41: +case 43: YY_RULE_SETUP -#line 274 "util_expr_scan.l" +#line 295 "util_expr_scan.l" { return T_OP_NOT; } YY_BREAK -case 42: +case 44: YY_RULE_SETUP -#line 275 "util_expr_scan.l" +#line 296 "util_expr_scan.l" { return T_OP_CONCAT; } YY_BREAK -case 43: +case 45: YY_RULE_SETUP -#line 276 "util_expr_scan.l" +#line 297 "util_expr_scan.l" { return T_OP_IN; } YY_BREAK -case 44: +case 46: YY_RULE_SETUP -#line 277 "util_expr_scan.l" +#line 298 "util_expr_scan.l" { return T_OP_EQ; } YY_BREAK -case 45: +case 47: YY_RULE_SETUP -#line 278 "util_expr_scan.l" +#line 299 "util_expr_scan.l" { return T_OP_NE; } YY_BREAK -case 46: +case 48: YY_RULE_SETUP -#line 279 "util_expr_scan.l" +#line 300 "util_expr_scan.l" { return T_OP_GE; } YY_BREAK -case 47: +case 49: YY_RULE_SETUP -#line 280 "util_expr_scan.l" +#line 301 "util_expr_scan.l" { return T_OP_LE; } YY_BREAK -case 48: +case 50: YY_RULE_SETUP -#line 281 "util_expr_scan.l" +#line 302 "util_expr_scan.l" { return T_OP_GT; } YY_BREAK -case 49: +case 51: YY_RULE_SETUP -#line 282 "util_expr_scan.l" +#line 303 "util_expr_scan.l" { return T_OP_LT; } YY_BREAK /* for compatibility with ssl_expr */ -case 50: +case 52: YY_RULE_SETUP -#line 285 "util_expr_scan.l" +#line 306 "util_expr_scan.l" { return T_OP_LT; } YY_BREAK -case 51: +case 53: YY_RULE_SETUP -#line 286 "util_expr_scan.l" +#line 307 "util_expr_scan.l" { return T_OP_LE; } YY_BREAK -case 52: +case 54: YY_RULE_SETUP -#line 287 "util_expr_scan.l" +#line 308 "util_expr_scan.l" { return T_OP_GT; } YY_BREAK -case 53: +case 55: YY_RULE_SETUP -#line 288 "util_expr_scan.l" +#line 309 "util_expr_scan.l" { return T_OP_GE; } YY_BREAK -case 54: +case 56: YY_RULE_SETUP -#line 289 "util_expr_scan.l" +#line 310 "util_expr_scan.l" { return T_OP_NE; } YY_BREAK -case 55: +case 57: YY_RULE_SETUP -#line 290 "util_expr_scan.l" +#line 311 "util_expr_scan.l" { return T_OP_EQ; } YY_BREAK -case 56: +case 58: YY_RULE_SETUP -#line 291 "util_expr_scan.l" +#line 312 "util_expr_scan.l" { return T_OP_IN; } YY_BREAK -case 57: +case 59: YY_RULE_SETUP -#line 293 "util_expr_scan.l" +#line 314 "util_expr_scan.l" { yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1); return T_OP_UNARY; } YY_BREAK -case 58: +case 60: YY_RULE_SETUP -#line 298 "util_expr_scan.l" +#line 319 "util_expr_scan.l" { yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1); return T_OP_BINARY; @@ -1390,22 +1422,22 @@ YY_RULE_SETUP /* * Specials */ -case 59: +case 61: YY_RULE_SETUP -#line 306 "util_expr_scan.l" +#line 327 "util_expr_scan.l" { return T_TRUE; } YY_BREAK -case 60: +case 62: YY_RULE_SETUP -#line 307 "util_expr_scan.l" +#line 328 "util_expr_scan.l" { return T_FALSE; } YY_BREAK /* * Digits */ -case 61: +case 63: YY_RULE_SETUP -#line 312 "util_expr_scan.l" +#line 333 "util_expr_scan.l" { yylval->cpVal = apr_pstrdup(yyextra->pool, yytext); return T_DIGIT; @@ -1414,9 +1446,9 @@ YY_RULE_SETUP /* * Identifiers */ -case 62: +case 64: YY_RULE_SETUP -#line 320 "util_expr_scan.l" +#line 341 "util_expr_scan.l" { yylval->cpVal = apr_pstrdup(yyextra->pool, yytext); return T_ID; @@ -1425,9 +1457,9 @@ YY_RULE_SETUP /* * These are parts of the grammar and are returned as is */ -case 63: +case 65: YY_RULE_SETUP -#line 328 "util_expr_scan.l" +#line 349 "util_expr_scan.l" { return yytext[0]; } @@ -1435,21 +1467,21 @@ YY_RULE_SETUP /* * Anything else is an error */ -case 64: -/* rule 64 can match eol */ +case 66: +/* rule 66 can match eol */ YY_RULE_SETUP -#line 335 "util_expr_scan.l" +#line 356 "util_expr_scan.l" { char *msg = apr_psprintf(yyextra->pool, "Parse error near '%c'", yytext[0]); PERROR(msg); } YY_BREAK -case 65: +case 67: YY_RULE_SETUP -#line 340 "util_expr_scan.l" +#line 361 "util_expr_scan.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1453 "util_expr_scan.c" +#line 1485 "util_expr_scan.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(regex): yyterminate(); @@ -1745,7 +1777,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 119 ) + if ( yy_current_state >= 124 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1774,11 +1806,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 119 ) + if ( yy_current_state >= 124 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 118); + yy_is_jam = (yy_current_state == 123); return yy_is_jam ? 0 : yy_current_state; } @@ -2610,7 +2642,7 @@ void ap_expr_yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 340 "util_expr_scan.l" +#line 361 "util_expr_scan.l" diff --git a/server/util_expr_scan.l b/server/util_expr_scan.l index 05ff3a116b..79bdbc16f9 100644 --- a/server/util_expr_scan.l +++ b/server/util_expr_scan.l @@ -142,14 +142,30 @@ *str_ptr++ = yytext[1]; } -[^\\\n"'%}]+ { + /* regexp backref inside string/arg */ +[$][0-9] { + if (str_ptr != str_buf) { + /* return what we have so far and scan '$x' again */ + *str_ptr = '\0'; + yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf); + str_ptr = str_buf; + yyless(0); + return T_STRING; + } + else { + yylval->num = yytext[1] - '0'; + return T_REGEX_BACKREF; + } +} + +[^\\\n"'%}$]+ { char *cp = yytext; while (*cp != '\0') *str_ptr++ = *cp++; } - /* variable inside string */ -%\{ { + /* variable inside string/arg */ +%\{ { if (str_ptr != str_buf) { /* return what we have so far and scan '%{' again */ *str_ptr = '\0'; @@ -164,11 +180,11 @@ } } -% { +[%$] { *str_ptr++ = yytext[0]; } -[%}] { +[%}$] { *str_ptr++ = yytext[0]; } @@ -177,6 +193,11 @@ return T_VAR_BEGIN; } +[$][0-9] { + yylval->num = yytext[1] - '0'; + return T_REGEX_BACKREF; +} + /* * fixed name variable expansion %{XXX} and function call in %{func:arg} syntax */