Fix a denial of service attack against mod_reqtimeout.
[Stefan Fritsch]
+ *) core, mod_include, mod_ssl: Move the expression parser derived from
+ mod_include back into mod_include. Replace ap_expr with a parser
+ derived from mod_ssl's parser. Make mod_ssl use the new parser. Rework
+ ap_expr's public interface and provide hooks for modules to add variables
+ and functions. [Stefan Fritsch]
+
*) core: Do the hook sorting earlier so that the hooks are properly sorted
for the pre_config hook and during parsing the config. [Stefan Fritsch]
> httpd.spec )
fi
-# ensure that the mod_ssl expression parser sources are never regenerated
+# ensure that the ap_expr expression parser sources are never regenerated
# when running make
-echo fixing timestamps for mod_ssl sources
-cd modules/ssl
-touch ssl_expr_parse.y
+echo fixing timestamps for ap_expr sources
+cd server
+touch util_expr_parse.y
sleep 1
-touch ssl_expr_parse.c ssl_expr_parse.h ssl_expr_scan.l
+touch util_expr_parse.c util_expr_parse.h util_expr_scan.l
sleep 1
-touch ssl_expr_scan.c
-cd ../..
+touch util_expr_scan.c
+cd ..
exit 0
#define AP_EXPR_H
#include "httpd.h"
+#include "http_config.h"
#include "ap_regex.h"
#ifdef __cplusplus
extern "C" {
#endif
-/* conditional expression parser stuff */
-typedef enum {
- TOKEN_STRING,
- TOKEN_RE,
- TOKEN_AND,
- TOKEN_OR,
- TOKEN_NOT,
- TOKEN_EQ,
- TOKEN_NE,
- TOKEN_RBRACE,
- TOKEN_LBRACE,
- TOKEN_GROUP,
- TOKEN_GE,
- TOKEN_LE,
- TOKEN_GT,
- TOKEN_LT,
- TOKEN_ACCESS,
- TOKEN_IN
-} token_type_t;
+/** A node in the expression parse tree */
+typedef struct ap_expr_node ap_expr;
+/** Struct describing a parsed expression */
typedef struct {
- token_type_t type;
- const char *value;
-#ifdef DEBUG_INCLUDE
- const char *s;
-#endif
-} token_t;
-
-typedef struct parse_node {
- struct parse_node *parent;
- struct parse_node *left;
- struct parse_node *right;
- token_t token;
- int value;
- int done;
-#ifdef DEBUG_INCLUDE
- int dump_done;
-#endif
-} ap_parse_node_t;
+ /** The root of the actual expression parse tree */
+ ap_expr *root_node;
+ /** The filename where the expression has been defined (for logging).
+ * May be NULL
+ */
+ const char *filename;
+ /** The line number where the expression has been defined (for logging). */
+ unsigned int line_number;
+#define AP_EXPR_FLAGS_SSL_EXPR_COMPAT 1
+ /** Flags relevant for the expression */
+ unsigned int flags;
+ /** The module that is used for loglevel configuration (XXX put into eval_ctx?) */
+ int module_index;
+} ap_expr_info_t;
-typedef struct {
- const char *source;
- const char *rexp;
- apr_size_t nsub;
- ap_regmatch_t match[AP_MAX_REG_MATCH];
- int have_match;
-} backref_t;
-typedef const char *(*string_func_t)(request_rec*, const char*);
-typedef int (*opt_func_t)(request_rec*, ap_parse_node_t*, string_func_t);
-
-/**
- * Parse an expression into a parse tree
- * @param pool Pool
- * @param expr The expression to parse
- * @param was_error On return, set to zero if parse successful, nonzero on error
- * @return The parse tree
- */
-AP_DECLARE(ap_parse_node_t*) ap_expr_parse(apr_pool_t *pool, const char *expr,
- int *was_error);
/**
* Evaluate a parse tree
* @param r The current request
- * @param root The root node of the parse tree
- * @param was_error On return, set to zero if parse successful, nonzero on error
- * @param reptr Regular expression memory for backreferencing if a regexp was parsed
- * @param string_func String parser function - perform variable substitutions
- * Use ap_expr_string where applicable
- * @param eval_func Option evaluation function (e.g. -A filename)
- * @return the value the expression parsed to
+ * @param expr The expression to be evaluated
+ * @param err A more detailed error string
+ * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
*/
-AP_DECLARE(int) ap_expr_eval(request_rec *r, const ap_parse_node_t *root,
- int *was_error, backref_t **reptr,
- string_func_t string_func, opt_func_t eval_func);
+AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *expr,
+ const char **err);
+
+/** Context used during evaluation of a parse tree, created by ap_expr_exec */
+typedef struct {
+ /** the current request */
+ request_rec *r;
+ /** the current connection */
+ conn_rec *c;
+ /** the current connection */
+ server_rec *s;
+ /** the pool to use */
+ apr_pool_t *p;
+ /** where to store the error string */
+ const char **err;
+ /** ap_expr_info_t for the expression */
+ const ap_expr_info_t *info;
+} ap_expr_eval_ctx;
+
+
/**
- * Evaluate an expression. This is functionally equivalent to
- * ap_expr_parse followed by ap_expr_eval, but faster and more efficient
- * when an expression only needs to be parsed once and discarded.
- * @param r The current request
- * @param expr The expression to parse
- * @param was_error On return, set to zero if parse successful, nonzero on error
- * @param reptr Regular expression memory for backreferencing if a regexp was parsed
- * @param string_func String parser function - perform variable substitutions
- * Use ap_expr_string where applicable
- * @param eval_func Option evaluation function (e.g. -A filename)
- * @return the value the expression parsed to
+ * The parse can be extended with variable lookup, functions, and
+ * and operators.
+ *
+ * During parsing, the parser calls the lookup function to resolve a
+ * name into a function pointer and an opaque context for the function.
+ *
+ * The default lookup function is the hook 'ap_run_expr_lookup'.
+ * Modules can use it to make functions and variables generally available.
+ *
+ * An ap_expr consumer can also provide its own custom lookup function to
+ * modify the set of variables and functions that are available. The custom
+ * lookup function can in turn call 'ap_run_expr_lookup'.
+ */
+
+/** Unary operator, takes one string argument and returns a bool value.
+ * The name must have the form '-z' (one letter only).
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @param arg The (right) operand
+ * @return 0 or 1
+ */
+typedef int ap_expr_op_unary_t(ap_expr_eval_ctx *ctx, const void *data,
+ const char *arg);
+
+/** Binary operator, takes two string arguments and returns a bool value.
+ * The name must have the form '-cmp' (at least two letters).
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @param arg1 The left operand
+ * @param arg2 The right operand
+ * @return 0 or 1
+ */
+typedef int ap_expr_op_binary_t(ap_expr_eval_ctx *ctx, const void *data,
+ const char *arg1, const char *arg2);
+
+/** String valued function, takes a string argument and returns a string
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @param arg The argument
+ * @return The functions result string, may be NULL for 'empty string'
+ */
+typedef const char *(ap_expr_string_func_t)(ap_expr_eval_ctx *ctx, const void *data,
+ const char *arg);
+
+/** List valued function, takes a string argument and returns a list of strings
+ * Can currently only be called following the builtin '-in' operator.
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @param arg The argument
+ * @return The functions result list of strings, may be NULL for 'empty array'
*/
-AP_DECLARE(int) ap_expr_evalstring(request_rec *r, const char *expr,
- int *was_error, backref_t **reptr,
- string_func_t string_func,
- opt_func_t eval_func);
+typedef apr_array_header_t *(ap_expr_list_func_t)(ap_expr_eval_ctx *ctx, const void *data,
+ const char *arg);
+
+/** Variable lookup function, takes no argument and returns a string
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @return The expanded variable
+ */
+typedef const char *(ap_expr_var_func_t)(ap_expr_eval_ctx *ctx, const void *data);
+
+/** parameter struct passed to the lookup hook functions */
+typedef struct {
+ /** type of the looked up object */
+ int type;
+#define AP_EXPR_FUNC_VAR 0
+#define AP_EXPR_FUNC_STRING 1
+#define AP_EXPR_FUNC_LIST 2
+#define AP_EXPR_FUNC_OP_UNARY 3
+#define AP_EXPR_FUNC_OP_BINARY 4
+ /** name of the looked up object */
+ const char *name;
+
+ int flags;
+
+ apr_pool_t *pool;
+ apr_pool_t *ptemp;
+
+ /** where to store the function pointer */
+ const void **func;
+ /** where to store the function's context */
+ const void **data;
+ /** Where to store the error message (if any) */
+ const char **err;
+} ap_expr_lookup_parms;
+
+/** Function for looking up the provider function for a variable, operator
+ * or function in an expression.
+ * @param parms The parameter struct, also determins where the result is
+ * stored.
+ * @return OK on success,
+ * !OK on failure,
+ * DECLINED if the requested name is not handled by this function
+ */
+typedef int (ap_expr_lookup_fn)(ap_expr_lookup_parms *parms);
+
+AP_DECLARE_HOOK(int, expr_lookup, (ap_expr_lookup_parms *parms))
/**
- * Internal initialisation of ap_expr (for httpd)
+ * Parse an expression into a parse tree
* @param pool Pool
- * @return APR_SUCCESS or error
+ * @param ptemp temp pool
+ * @param info The ap_expr_info_t struct (with values filled in)
+ * @param expr The expression string to parse
+ * @param lookup_fn The lookup function to use, NULL for default
+ * @return NULL on success, error message on error.
+ * A pointer to the resulting parse tree will be stored in
+ * info->root_node.
*/
-AP_DECLARE(apr_status_t) ap_expr_init(apr_pool_t *pool);
+AP_DECLARE(const char *) ap_expr_parse(apr_pool_t *pool, apr_pool_t *ptemp,
+ ap_expr_info_t *info, const char *expr,
+ ap_expr_lookup_fn *lookup_fn);
/**
- * Default string evaluation function for passing to ap_expr_eval and
- * ap_expr_evalstring. Use this (and update as necessary) to offer
- * a consistent expression syntax across different modules.
- * Supports the following:
- * $req{foo} - request header "foo"
- * $resp{foo} - response header "foo"
- * $env{foo} - environment variable "foo"
- * $handler - r->handler
- * $content-type - r->content_type
- * Other strings are returned unmodified.
- * @param r The current request
- * @param str The string to evaluate
- * @return The evaluated string
+ * High level interface to ap_expr_parse that also creates ap_expr_info_t and
+ * uses info from cmd_parms to fill in most of it.
+ * @param cmd The cmd_parms struct
+ * @param expr The expression string to parse
+ * @param err Set to NULL on success, error message on error
+ * @return The parsed expression
*/
-AP_DECLARE_NONSTD(const char*) ap_expr_string(request_rec *r,
- const char *str);
+AP_DECLARE(ap_expr_info_t *) ap_expr_parse_cmd(const cmd_parms *cmd,
+ const char *expr,
+ const char **err,
+ ap_expr_lookup_fn *lookup_fn);
+
+
+ /**
+ * Internal initialisation of ap_expr (for httpd internal use)
+ */
+void ap_expr_init(apr_pool_t *pool);
#ifdef __cplusplus
}
* 20101016.0 (2.3.9-dev) Remove ap_cache_check_allowed().
* 20101017.0 (2.3.9-dev) Make ap_cache_control() public, add cache_control_t
* to mod_disk_cache format.
+ * 20101106.0 (2.3.9-dev) Replace the ap_expr parser derived from
+ * mod_include's parser with one derived from
+ * mod_ssl's parser. Clean up ap_expr's public
+ * interface.
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20101017
+#define MODULE_MAGIC_NUMBER_MAJOR 20101106
#endif
#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
#define USE_CANONICAL_PHYS_PORT_UNSET (2)
unsigned use_canonical_phys_port : 2;
- ap_parse_node_t *condition; /* Conditionally merge <If> sections */
+ ap_expr_info_t *condition; /* Conditionally merge <If> sections */
/** per-dir log config */
struct ap_logconf *log;
const char *require_line,
const void *parsed_require_line)
{
- int err = 0;
- const ap_parse_node_t *expr = parsed_require_line;
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_line;
+ int rc = ap_expr_exec(r, expr, &err);
- if (ap_expr_eval(r, expr, &err, NULL, ap_expr_string, NULL))
- return AUTHZ_GRANTED;
- else
+ if (err || !rc)
+ /* XXX: real error handling? */
return AUTHZ_DENIED;
+ else
+ return AUTHZ_GRANTED;
}
static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
const void **parsed_require_line)
{
- int expr_err = 0;
- ap_parse_node_t *expr = ap_expr_parse(cmd->pool, require_line, &expr_err);
+ const char *expr_err = NULL;
+ ap_expr_info_t *expr = ap_expr_parse_cmd(cmd, require_line, &expr_err, NULL);
if (expr_err)
return "Cannot parse expression in require line";
* (2.0-compatible) ap_filter_rec_t* frec.
*/
struct ap_filter_provider_t {
- ap_parse_node_t *expr;
+ ap_expr_info_t *expr;
/** The filter that implements this provider */
ap_filter_rec_t *frec;
{
ap_filter_provider_t *provider;
int match;
- int err = 0;
+ const char *err = NULL;
unsigned int proto_flags;
request_rec *r = f->r;
harness_ctx *ctx = f->ctx;
/* Check registered providers in order */
for (provider = filter->providers; provider; provider = provider->next) {
- match = ap_expr_eval(r, provider->expr, &err, NULL, ap_expr_string, NULL);
+ match = ap_expr_exec(r, provider->expr, &err);
if (err) {
/* log error but accept match value ? */
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Error evaluating filter dispatch condition");
+ "Error evaluating filter dispatch condition: %s",
+ err);
}
if (match) {
const char *c;
ap_filter_rec_t* frec;
ap_filter_rec_t* provider_frec;
- ap_parse_node_t *node;
- int err = 0;
+ ap_expr_info_t *node;
+ const char *err = NULL;
/* fname has been declared with DeclareFilter, so we can look it up */
frec = apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING);
if (!provider_frec) {
return apr_psprintf(cmd->pool, "Unknown filter provider %s", pname);
}
- node = ap_expr_parse(cmd->pool, expr, &err);
+ node = ap_expr_parse_cmd(cmd, expr, &err, NULL);
if (err) {
- return "Error parsing FilterProvider expression.";
+ return apr_pstrcat(cmd->pool,
+ "Error parsing FilterProvider expression:", err,
+ NULL);
}
provider = apr_palloc(cmd->pool, sizeof(ap_filter_provider_t));
*p++ = *type++;
} while (*type);
*p = 0;
- expr = apr_psprintf(cmd->temp_pool, "$content-type = /^%s/", etype);
+ expr = apr_psprintf(cmd->temp_pool, "%%{CONTENT_TYPE} =~ m!^%s!", etype);
rv = filter_provider(cmd, CFG, fname, pname, expr);
ap_regex_t *regex;
const char *condition_var;
const char *subs;
- ap_parse_node_t *expr;
+ ap_expr_info_t *expr;
} header_entry;
/* echo_do is used for Header echo to iterate through the request headers*/
const char *condition_var = NULL;
const char *colon;
header_entry *new;
- ap_parse_node_t *expr = NULL;
+ ap_expr_info_t *expr = NULL;
apr_array_header_t *fixup = (cmd->info == &hdr_in)
? dirconf->fixup_in : (cmd->info == &hdr_out_always)
condition_var = envclause + 4;
}
else {
- int err = 0;
- expr = ap_expr_parse(cmd->pool, envclause, &err);
+ const char *err = NULL;
+ expr = ap_expr_parse_cmd(cmd, envclause, &err, NULL);
if (err) {
- return "Can't parse envclause/expression";
+ return apr_pstrcat(cmd->pool,
+ "Can't parse envclause/expression: ", err,
+ NULL);
}
}
}
}
/* Do we have an expression to evaluate? */
else if (hdr->expr != NULL) {
- int err = 0;
- int eval = ap_expr_eval(r, hdr->expr, &err, NULL,
- ap_expr_string, NULL);
+ const char *err = NULL;
+ int eval = ap_expr_exec(r, hdr->expr, &err);
if (err) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Failed to evaluate expression - ignoring");
+ "Failed to evaluate expression (%s) - ignoring",
+ err);
}
else if (!eval) {
continue;
#
include $(top_srcdir)/build/special.mk
-
-#
-# developer stuff
-# (we really don't expect end users to use these targets!)
-#
-
-ssl_expr_scan.c: $(top_srcdir)/modules/ssl/ssl_expr_scan.l ssl_expr_parse.h
- flex -Pssl_expr_yy -o ssl_expr_scan.c $(top_srcdir)/ssl_expr_scan.l
- mv ssl_expr_scan.c ssl_expr_scan.c.tmp
- sed -e "s|\"`pwd`/|\"|g" <ssl_expr_scan.c.tmp >ssl_expr_scan.c
- rm -f ssl_expr_scan.c.tmp
-
-ssl_expr_parse.c ssl_expr_parse.h: $(top_srcdir)/modules/ssl/ssl_expr_parse.y
- bison -pssl_expr_yy --defines=ssl_expr_parse.h -o ssl_expr_parse.c $(top_srcdir)/modules/ssl/ssl_expr_parse.y
- mv ssl_expr_parse.c ssl_expr_parse.c.tmp
- sed -e "s|\"`pwd`/|\"|g" < ssl_expr_parse.c.tmp > ssl_expr_parse.c
- rm -f ssl_expr_parse.c.tmp
ssl_engine_pphrase.lo dnl
ssl_engine_rand.lo dnl
ssl_engine_vars.lo dnl
-ssl_expr.lo dnl
-ssl_expr_eval.lo dnl
-ssl_expr_parse.lo dnl
-ssl_expr_scan.lo dnl
ssl_scache.lo dnl
ssl_util_stapling.lo dnl
ssl_util.lo dnl
&ssl_authz_provider_verify_client,
AP_AUTH_INTERNAL_PER_CONF);
- ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl-require",
- AUTHZ_PROVIDER_VERSION,
- &ssl_authz_provider_sslrequire,
- AP_AUTH_INTERNAL_PER_CONF);
-
}
module AP_MODULE_DECLARE_DATA ssl_module = {
const char *arg)
{
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- ssl_expr *expr;
+ ap_expr_info_t *info = apr_pcalloc(cmd->pool, sizeof(ap_expr_info_t));
ssl_require_t *require;
const char *errstring;
- if (!(expr = ssl_expr_comp(cmd->pool, arg, &errstring))) {
+ info->flags = AP_EXPR_FLAGS_SSL_EXPR_COMPAT;
+ info->filename = cmd->directive->filename;
+ info->line_number = cmd->directive->line_num;
+ errstring = ap_expr_parse(cmd->pool, cmd->temp_pool, info, arg, NULL);
+ if (errstring) {
return apr_pstrcat(cmd->pool, "SSLRequire: ", errstring, NULL);
}
require = apr_array_push(dc->aRequirement);
require->cpExpr = apr_pstrdup(cmd->pool, arg);
- require->mpExpr = expr;
+ require->mpExpr = info;
return NULL;
}
SSL_CTX *ctx = NULL;
apr_array_header_t *requires;
ssl_require_t *ssl_requires;
- char *cp;
int ok, i;
BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
X509 *cert;
for (i = 0; i < requires->nelts; i++) {
ssl_require_t *req = &ssl_requires[i];
const char *errstring;
- ok = ssl_expr_exec(r, req->mpExpr, &errstring);
+ ok = ap_expr_exec(r, req->mpExpr, &errstring);
if (ok < 0) {
- cp = apr_psprintf(r->pool,
- "Failed to execute "
- "SSL requirement expression: %s",
- errstring);
-
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "access to %s failed, reason: %s",
- r->filename, cp);
+ "access to %s failed, reason: Failed to execute "
+ "SSL requirement expression: %s",
+ r->filename, errstring);
/* remember forbidden access for strict require option */
apr_table_setn(r->notes, "ssl-access-forbidden", "1");
};
-static authz_status ssl_authz_sslrequire_check(request_rec *r,
- const char *require_line,
- const void *parsed)
-{
- const ssl_expr *expr = parsed;
- const char *errstring;
- int ok = ssl_expr_exec(r, expr, &errstring);
-
- if (ok < 0) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Failed to execute SSL requirement expression in "
- "'Require ssl-require': %s",
- errstring);
- return AUTHZ_DENIED;
- }
-
- if (ok != 1) {
- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
- "SSL requirement expression in 'Require ssl-require' "
- "not fulfilled");
- return AUTHZ_DENIED;
- }
-
- return AUTHZ_GRANTED;
-}
-
-static const char *ssl_authz_sslrequire_parse(cmd_parms *cmd,
- const char *require_line,
- const void **parsed)
-{
- const char *errstring;
- ssl_expr *expr = ssl_expr_comp(cmd->pool, require_line, &errstring);
-
- if (!expr)
- return apr_psprintf(cmd->pool, "Error in 'Require require-ssl': %s",
- errstring);
-
- *parsed = expr;
-
- return NULL;
-}
-
-const authz_provider ssl_authz_provider_sslrequire =
-{
- &ssl_authz_sslrequire_check,
- &ssl_authz_sslrequire_parse,
-};
-
/* _________________________________________________________________
**
-- Unknown */
#include "ssl_private.h"
#include "mod_ssl.h"
+#include "ap_expr.h"
#include "apr_time.h"
static char var_library_interface[] = SSL_LIBRARY_TEXT;
static char *var_library = NULL;
+static apr_array_header_t *expr_peer_ext_list_fn(ap_expr_eval_ctx *ctx,
+ const void *dummy,
+ const char *arg)
+{
+ return ssl_ext_list(ctx->p, ctx->c, 1, arg);
+}
+
+static const char *expr_var_fn(ap_expr_eval_ctx *ctx, const void *data)
+{
+ char *var = (char *)data;
+ return ssl_var_lookup_ssl(ctx->p, ctx->c, var);
+}
+
+static int ssl_expr_lookup(ap_expr_lookup_parms *parms)
+{
+ switch (parms->type) {
+ case AP_EXPR_FUNC_VAR:
+ /* for now, we just handle everything that starts with SSL_, but
+ * register our hook as APR_HOOK_LAST
+ * XXX: This can be optimized
+ */
+ if (strcEQn(parms->name, "SSL_", 4)) {
+ *parms->func = expr_var_fn;
+ *parms->data = parms->name + 4;
+ return OK;
+ }
+ break;
+ case AP_EXPR_FUNC_LIST:
+ if (strcEQ(parms->name, "PeerExtList")) {
+ *parms->func = expr_peer_ext_list_fn;
+ *parms->data = "PeerExtList";
+ return OK;
+ }
+ break;
+ }
+ return DECLINED;
+}
+
+
void ssl_var_register(apr_pool_t *p)
{
char *cp, *cp2;
if ((cp2 = strchr(cp, ' ')) != NULL)
*cp2 = NUL;
}
+
+ ap_hook_expr_lookup(ssl_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
}
/* This function must remain safe to use for a non-SSL connection. */
return result;
}
+
+++ /dev/null
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_expr.c
- * Expression Handling
- */
- /* ``It is hard to fly with
- the eagles when you work
- with the turkeys.''
- -- Unknown */
-#include "ssl_private.h"
-
-/* _________________________________________________________________
-**
-** Expression Handling
-** _________________________________________________________________
-*/
-
-
-ssl_expr *ssl_expr_comp(apr_pool_t *p, const char *expr, const char **err)
-{
- ssl_expr_info_type context;
- int rc;
-
- context.pool = p;
- context.inputbuf = expr;
- context.inputlen = strlen(expr);
- context.inputptr = context.inputbuf;
- context.expr = FALSE;
- context.error = NULL;
-
- ssl_expr_yylex_init(&context.scanner);
- ssl_expr_yyset_extra(&context, context.scanner);
- rc = ssl_expr_yyparse(&context);
- ssl_expr_yylex_destroy(context.scanner);
- *err = context.error;
-
- if (rc)
- return NULL;
-
- return context.expr;
-}
-
-ssl_expr *ssl_expr_make(ssl_expr_node_op op, void *a1, void *a2,
- ssl_expr_info_type *context)
-{
- ssl_expr *node;
-
- node = (ssl_expr *)apr_palloc(context->pool, sizeof(ssl_expr));
- node->node_op = op;
- node->node_arg1 = (char *)a1;
- node->node_arg2 = (char *)a2;
- return node;
-}
-
-int ssl_expr_exec(request_rec *r, const ssl_expr *expr, const char **err)
-{
- BOOL rc;
-
- *err = NULL;
- rc = ssl_expr_eval(r, expr, err);
- if (*err != NULL)
- return (-1);
- else
- return (rc ? 1 : 0);
-}
+++ /dev/null
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @verbatim
- _ _
- _ __ ___ ___ __| | ___ ___| | mod_ssl
- | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- | | | | | | (_) | (_| | \__ \__ \ |
- |_| |_| |_|\___/ \__,_|___|___/___/_|
- |_____|
- @endverbatim
- * @file ssl_expr.h
- * @brief Expression Handling (Header).
- * ``May all your PUSHes be POPed.''
- *
- * @defgroup MOD_SSL_EXPR Expression Handling
- * @ingroup MOD_SSL
- * @{
- */
-
-#ifndef __SSL_EXPR_H__
-#define __SSL_EXPR_H__
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE !FALSE
-#endif
-
-#ifndef YY_NULL
-#define YY_NULL 0
-#endif
-
-#ifndef MIN
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-
-#ifndef BOOL
-#define BOOL unsigned int
-#endif
-
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
-#ifndef NUL
-#define NUL '\0'
-#endif
-
-#ifndef YYDEBUG
-#define YYDEBUG 0
-#endif
-
-typedef enum {
- op_NOP, op_ListElement, op_PeerExtElement,
- op_True, op_False, op_Not, op_Or, op_And, op_Comp,
- op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE, op_IN, op_REG, op_NRE,
- op_Digit, op_String, op_Regex, op_Var, op_Func
-} ssl_expr_node_op;
-
-typedef struct {
- ssl_expr_node_op node_op;
- void *node_arg1;
- void *node_arg2;
-} ssl_expr_node;
-
-typedef ssl_expr_node ssl_expr;
-
-typedef struct {
- apr_pool_t *pool;
- const char *inputbuf;
- int inputlen;
- const char *inputptr;
- ssl_expr *expr;
- void *scanner;
- char *error;
-} ssl_expr_info_type;
-
-int ssl_expr_yyparse(ssl_expr_info_type *context);
-int ssl_expr_yyerror(ssl_expr_info_type *context, char *errstring);
-int ssl_expr_yylex_init(void **scanner);
-int ssl_expr_yylex_destroy(void *scanner);
-void ssl_expr_yyset_extra(ssl_expr_info_type *context, void *scanner);
-
-ssl_expr *ssl_expr_comp(apr_pool_t *p, const char *exprstr, const char **err);
-int ssl_expr_exec(request_rec *r, const ssl_expr *expr, const char **err);
-ssl_expr *ssl_expr_make(ssl_expr_node_op op, void *arg1, void *arg2,
- ssl_expr_info_type *context);
-BOOL ssl_expr_eval(request_rec *r, const ssl_expr *expr, const char **err);
-
-#endif /* __SSL_EXPR_H__ */
-/** @} */
-
+++ /dev/null
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_expr_eval.c
- * Expression Evaluation
- */
- /* ``Make love,
- not software!''
- -- Unknown */
-#include "ssl_private.h"
-
-/* _________________________________________________________________
-**
-** Expression Evaluation
-** _________________________________________________________________
-*/
-
-static BOOL ssl_expr_eval_comp(request_rec *, ssl_expr *, const char **err);
-static char *ssl_expr_eval_word(request_rec *, ssl_expr *, const char **err);
-static BOOL ssl_expr_eval_oid(request_rec *r, const char *word,
- const char *oidstr, const char **err);
-static char *ssl_expr_eval_func_file(request_rec *, char *, const char **err);
-static int ssl_expr_eval_strcmplex(char *, char *, const char **err);
-
-BOOL ssl_expr_eval(request_rec *r, const ssl_expr *node, const char **err)
-{
- switch (node->node_op) {
- case op_True: {
- return TRUE;
- }
- case op_False: {
- return FALSE;
- }
- case op_Not: {
- ssl_expr *e = (ssl_expr *)node->node_arg1;
- return (!ssl_expr_eval(r, e, err));
- }
- case op_Or: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval(r, e1, err) || ssl_expr_eval(r, e2, err));
- }
- case op_And: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval(r, e1, err) && ssl_expr_eval(r, e2, err));
- }
- case op_Comp: {
- ssl_expr *e = (ssl_expr *)node->node_arg1;
- return ssl_expr_eval_comp(r, e, err);
- }
- default: {
- *err = "Internal evaluation error: Unknown expression node";
- return FALSE;
- }
- }
-}
-
-static BOOL ssl_expr_eval_comp(request_rec *r, ssl_expr *node, const char **err)
-{
- switch (node->node_op) {
- case op_EQ: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (strcmp(ssl_expr_eval_word(r, e1, err), ssl_expr_eval_word(r, e2, err)) == 0);
- }
- case op_NE: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (strcmp(ssl_expr_eval_word(r, e1, err), ssl_expr_eval_word(r, e2, err)) != 0);
- }
- case op_LT: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1, err), ssl_expr_eval_word(r, e2, err), err) < 0);
- }
- case op_LE: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1, err), ssl_expr_eval_word(r, e2, err), err) <= 0);
- }
- case op_GT: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1, err), ssl_expr_eval_word(r, e2, err), err) > 0);
- }
- case op_GE: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1, err), ssl_expr_eval_word(r, e2, err), err) >= 0);
- }
- case op_IN: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- ssl_expr *e3;
- char *w1 = ssl_expr_eval_word(r, e1, err);
- BOOL found = FALSE;
- do {
- ssl_expr_node_op op = e2->node_op;
- e3 = (ssl_expr *)e2->node_arg1;
- e2 = (ssl_expr *)e2->node_arg2;
-
- if (op == op_PeerExtElement) {
- char *w3 = ssl_expr_eval_word(r, e3, err);
-
- found = ssl_expr_eval_oid(r, w1, w3, err);
-
- /* There will be no more nodes on the list, so the result is authoritative */
- break;
- }
-
- if (strcmp(w1, ssl_expr_eval_word(r, e3, err)) == 0) {
- found = TRUE;
- break;
- }
- } while (e2 != NULL);
- return found;
- }
- case op_REG: {
- ssl_expr *e1;
- ssl_expr *e2;
- char *word;
- ap_regex_t *regex;
-
- e1 = (ssl_expr *)node->node_arg1;
- e2 = (ssl_expr *)node->node_arg2;
- word = ssl_expr_eval_word(r, e1, err);
- regex = (ap_regex_t *)(e2->node_arg1);
- return (ap_regexec(regex, word, 0, NULL, 0) == 0);
- }
- case op_NRE: {
- ssl_expr *e1;
- ssl_expr *e2;
- char *word;
- ap_regex_t *regex;
-
- e1 = (ssl_expr *)node->node_arg1;
- e2 = (ssl_expr *)node->node_arg2;
- word = ssl_expr_eval_word(r, e1, err);
- regex = (ap_regex_t *)(e2->node_arg1);
- return !(ap_regexec(regex, word, 0, NULL, 0) == 0);
- }
- default: {
- *err = "Internal evaluation error: Unknown expression node";
- return FALSE;
- }
- }
-}
-
-static char *ssl_expr_eval_word(request_rec *r, ssl_expr *node, const char **err)
-{
- switch (node->node_op) {
- case op_Digit: {
- char *string = (char *)node->node_arg1;
- return string;
- }
- case op_String: {
- char *string = (char *)node->node_arg1;
- return string;
- }
- case op_Var: {
- char *var = (char *)node->node_arg1;
- char *val = ssl_var_lookup(r->pool, r->server, r->connection, r, var);
- return (val == NULL ? "" : val);
- }
- case op_Func: {
- char *name = (char *)node->node_arg1;
- ssl_expr *args = (ssl_expr *)node->node_arg2;
- if (strEQ(name, "file"))
- return ssl_expr_eval_func_file(r, (char *)(args->node_arg1), err);
- else {
- *err = "Internal evaluation error: Unknown function name";
- return "";
- }
- }
- default: {
- *err = "Internal evaluation error: Unknown expression node";
- return FALSE;
- }
- }
-}
-
-static BOOL ssl_expr_eval_oid(request_rec *r, const char *word,
- const char *oidstr, const char **err)
-{
- int j;
- BOOL result = FALSE;
- apr_array_header_t *oid_array;
- char **oid_value;
-
- if (NULL == (oid_array = ssl_ext_list(r->pool, r->connection, 1, oidstr))) {
- return FALSE;
- }
-
- oid_value = (char **) oid_array->elts;
- for (j = 0; j < oid_array->nelts; j++) {
- if (strcmp(word, oid_value[j]) == 0) {
- result = TRUE;
- break;
- }
- }
- return result;
-}
-
-
-static char *ssl_expr_eval_func_file(request_rec *r, char *filename, const char **err)
-{
- apr_file_t *fp;
- char *buf;
- apr_off_t offset;
- apr_size_t len;
- apr_finfo_t finfo;
-
- if (apr_file_open(&fp, filename, APR_READ|APR_BUFFERED,
- APR_OS_DEFAULT, r->pool) != APR_SUCCESS) {
- *err = "Cannot open file";
- return "";
- }
- apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
- if ((finfo.size + 1) != ((apr_size_t)finfo.size + 1)) {
- *err = "Huge file cannot be read";
- apr_file_close(fp);
- return "";
- }
- len = (apr_size_t)finfo.size;
- if (len == 0) {
- buf = (char *)apr_palloc(r->pool, sizeof(char) * 1);
- *buf = NUL;
- }
- else {
- if ((buf = (char *)apr_palloc(r->pool, sizeof(char)*(len+1))) == NULL) {
- *err = "Cannot allocate memory";
- apr_file_close(fp);
- return "";
- }
- offset = 0;
- apr_file_seek(fp, APR_SET, &offset);
- if (apr_file_read(fp, buf, &len) != APR_SUCCESS) {
- *err = "Cannot read from file";
- apr_file_close(fp);
- return "";
- }
- buf[len] = NUL;
- }
- apr_file_close(fp);
- return buf;
-}
-
-/* a variant of strcmp(3) which works correctly also for number strings */
-static int ssl_expr_eval_strcmplex(char *cpNum1, char *cpNum2, const char **err)
-{
- int i, n1, n2;
-
- if (cpNum1 == NULL)
- return -1;
- if (cpNum2 == NULL)
- return +1;
- n1 = strlen(cpNum1);
- n2 = strlen(cpNum2);
- if (n1 > n2)
- return 1;
- if (n1 < n2)
- return -1;
- for (i = 0; i < n1; i++) {
- if (cpNum1[i] > cpNum2[i])
- return 1;
- if (cpNum1[i] < cpNum2[i])
- return -1;
- }
- return 0;
-}
+++ /dev/null
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| |
- * | '_ ` _ \ / _ \ / _` | / __/ __| |
- * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL
- * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/
- * |_____|
- * ssl_expr_parse.y
- * Expression LR(1) Parser
- */
- /* ``What you see is all you get.''
- -- Brian Kernighan */
-
-/* _________________________________________________________________
-**
-** Expression Parser
-** _________________________________________________________________
-*/
-
-%pure-parser
-%defines
-%error-verbose
-%lex-param { void *yyscanner }
-%parse-param { ssl_expr_info_type *context }
-
-%{
-#include "ssl_private.h"
-%}
-
-%union {
- char *cpVal;
- ssl_expr *exVal;
-}
-
-%token T_TRUE
-%token T_FALSE
-
-%token <cpVal> T_DIGIT
-%token <cpVal> T_ID
-%token <cpVal> T_STRING
-%token <cpVal> T_REGEX
-%token <cpVal> T_REGEX_I
-
-%token T_FUNC_FILE
-
-%token T_OP_EQ
-%token T_OP_NE
-%token T_OP_LT
-%token T_OP_LE
-%token T_OP_GT
-%token T_OP_GE
-%token T_OP_REG
-%token T_OP_NRE
-%token T_OP_IN
-%token T_OP_PEEREXTLIST
-
-%token T_OP_OR
-%token T_OP_AND
-%token T_OP_NOT
-
-%left T_OP_OR
-%left T_OP_AND
-%left T_OP_NOT
-
-%type <exVal> expr
-%type <exVal> comparison
-%type <exVal> funccall
-%type <exVal> regex
-%type <exVal> words
-%type <exVal> wordlist
-%type <exVal> word
-
-%{
-#include "ssl_expr.h"
-#define yyscanner context->scanner
-
-int ssl_expr_yyerror(ssl_expr_info_type *context, char *err);
-int ssl_expr_yylex(YYSTYPE *lvalp, void *scanner);
-%}
-
-
-%%
-
-root : expr { context->expr = $1; }
- ;
-
-expr : T_TRUE { $$ = ssl_expr_make(op_True, NULL, NULL, context); }
- | T_FALSE { $$ = ssl_expr_make(op_False, NULL, NULL, context); }
- | T_OP_NOT expr { $$ = ssl_expr_make(op_Not, $2, NULL, context); }
- | expr T_OP_OR expr { $$ = ssl_expr_make(op_Or, $1, $3, context); }
- | expr T_OP_AND expr { $$ = ssl_expr_make(op_And, $1, $3, context); }
- | comparison { $$ = ssl_expr_make(op_Comp, $1, NULL, context); }
- | '(' expr ')' { $$ = $2; }
- ;
-
-comparison: word T_OP_EQ word { $$ = ssl_expr_make(op_EQ, $1, $3, context); }
- | word T_OP_NE word { $$ = ssl_expr_make(op_NE, $1, $3, context); }
- | word T_OP_LT word { $$ = ssl_expr_make(op_LT, $1, $3, context); }
- | word T_OP_LE word { $$ = ssl_expr_make(op_LE, $1, $3, context); }
- | word T_OP_GT word { $$ = ssl_expr_make(op_GT, $1, $3, context); }
- | word T_OP_GE word { $$ = ssl_expr_make(op_GE, $1, $3, context); }
- | word T_OP_IN wordlist { $$ = ssl_expr_make(op_IN, $1, $3, context); }
- | word T_OP_REG regex { $$ = ssl_expr_make(op_REG, $1, $3, context); }
- | word T_OP_NRE regex { $$ = ssl_expr_make(op_NRE, $1, $3, context); }
- ;
-
-wordlist : T_OP_PEEREXTLIST '(' word ')' { $$ = ssl_expr_make(op_PeerExtElement, $3, NULL, context); }
- | '{' words '}' { $$ = $2 ; }
- ;
-
-words : word { $$ = ssl_expr_make(op_ListElement, $1, NULL, context); }
- | words ',' word { $$ = ssl_expr_make(op_ListElement, $3, $1, context); }
- ;
-
-word : T_DIGIT { $$ = ssl_expr_make(op_Digit, $1, NULL, context); }
- | T_STRING { $$ = ssl_expr_make(op_String, $1, NULL, context); }
- | '%' '{' T_ID '}' { $$ = ssl_expr_make(op_Var, $3, NULL, context); }
- | funccall { $$ = $1; }
- ;
-
-regex : T_REGEX {
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(context->pool, $1,
- AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
- context->error = "Failed to compile regular expression";
- YYERROR;
- }
- $$ = ssl_expr_make(op_Regex, regex, NULL, context);
- }
- | T_REGEX_I {
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(context->pool, $1,
- AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
- context->error = "Failed to compile regular expression";
- YYERROR;
- }
- $$ = ssl_expr_make(op_Regex, regex, NULL, context);
- }
- ;
-
-funccall : T_FUNC_FILE '(' T_STRING ')' {
- ssl_expr *args = ssl_expr_make(op_ListElement, $3, NULL, context);
- $$ = ssl_expr_make(op_Func, "file", args, context);
- }
- ;
-
-%%
-
-int yyerror(ssl_expr_info_type *context, char *s)
-{
- context->error = s;
- return 2;
-}
-
+++ /dev/null
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| |
- * | '_ ` _ \ / _ \ / _` | / __/ __| |
- * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL
- * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/
- * |_____|
- * ssl_expr_scan.l
- * Expression Scanner
- */
- /* ``Killing for peace is
- like fucking for virginity.''
- -- Unknown */
-
-/* _________________________________________________________________
-**
-** Expression Scanner
-** _________________________________________________________________
-*/
-
-%pointer
-%option batch
-%option never-interactive
-%option nodefault
-%option noyywrap
-%option reentrant
-%option bison-bridge
-%option warn
-%option noinput nounput
-%x str
-%x regex regex_flags
-
-%{
-#include "ssl_private.h"
-
-#include "ssl_expr_parse.h"
-#include "ssl_expr.h"
-
-#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-{ \
- if ((result = MIN(max_size, yyextra->inputbuf \
- + yyextra->inputlen \
- - yyextra->inputptr)) <= 0) \
- { \
- result = YY_NULL; \
- } \
- else { \
- memcpy(buf, yyextra->inputptr, result); \
- yyextra->inputptr += result; \
- } \
-}
-
-#define MAX_STR_LEN 2048
-#define YY_EXTRA_TYPE ssl_expr_info_type*
-%}
-
-
-%%
-
- char caStr[MAX_STR_LEN];
- char *cpStr = NULL;
- char caRegex[MAX_STR_LEN];
- char *cpRegex = NULL;
- char cRegexDel = NUL;
-
- /*
- * Whitespaces
- */
-[ \t\n]+ {
- /* NOP */
-}
-
- /*
- * C-style strings ("...")
- */
-\" {
- cpStr = caStr;
- BEGIN(str);
-}
-<str>\" {
- BEGIN(INITIAL);
- *cpStr = NUL;
- yylval->cpVal = apr_pstrdup(yyextra->pool, caStr);
- return T_STRING;
-}
-<str>\n {
- ssl_expr_yyerror(yyextra, "Unterminated string");
-}
-<str>\\[0-7]{1,3} {
- int result;
-
- (void)sscanf(yytext+1, "%o", &result);
- if (result > 0xff)
- ssl_expr_yyerror(yyextra, "Escape sequence out of bound");
- else
- *cpStr++ = result;
-}
-<str>\\[0-9]+ {
- ssl_expr_yyerror(yyextra, "Bad escape sequence");
-}
-<str>\\n { *cpStr++ = '\n'; }
-<str>\\r { *cpStr++ = '\r'; }
-<str>\\t { *cpStr++ = '\t'; }
-<str>\\b { *cpStr++ = '\b'; }
-<str>\\f { *cpStr++ = '\f'; }
-<str>\\(.|\n) {
- *cpStr++ = yytext[1];
-}
-<str>[^\\\n\"]+ {
- char *cp = yytext;
- while (*cp != NUL)
- *cpStr++ = *cp++;
-}
-<str>. {
- *cpStr++ = yytext[1];
-}
-
- /*
- * Regular Expression
- */
-"m". {
- cRegexDel = yytext[1];
- cpRegex = caRegex;
- BEGIN(regex);
-}
-<regex>.|\n {
- if (yytext[0] == cRegexDel) {
- *cpRegex = NUL;
- BEGIN(regex_flags);
- }
- else {
- *cpRegex++ = yytext[0];
- }
-}
-<regex_flags>i {
- yylval->cpVal = apr_pstrdup(yyextra->pool, caRegex);
- BEGIN(INITIAL);
- return T_REGEX_I;
-}
-<regex_flags>.|\n {
- yylval->cpVal = apr_pstrdup(yyextra->pool, caRegex);
- yyless(0);
- BEGIN(INITIAL);
- return T_REGEX;
-}
-<regex_flags><<EOF>> {
- yylval->cpVal = apr_pstrdup(yyextra->pool, caRegex);
- BEGIN(INITIAL);
- return T_REGEX;
-}
-
- /*
- * Operators
- */
-"eq" { return T_OP_EQ; }
-"==" { return T_OP_EQ; }
-"ne" { return T_OP_NE; }
-"!=" { return T_OP_NE; }
-"lt" { return T_OP_LT; }
-"<" { return T_OP_LT; }
-"le" { return T_OP_LE; }
-"<=" { return T_OP_LE; }
-"gt" { return T_OP_GT; }
-">" { return T_OP_GT; }
-"ge" { return T_OP_GE; }
-">=" { return T_OP_GE; }
-"=~" { return T_OP_REG; }
-"!~" { return T_OP_NRE; }
-"and" { return T_OP_AND; }
-"&&" { return T_OP_AND; }
-"or" { return T_OP_OR; }
-"||" { return T_OP_OR; }
-"not" { return T_OP_NOT; }
-"!" { return T_OP_NOT; }
-"in" { return T_OP_IN; }
-[Pp][Ee][Ee][Rr][Ee][Xx][Tt][Ll][Ii][Ss][Tt] { return T_OP_PEEREXTLIST; }
-
- /*
- * Functions
- */
-"file" { return T_FUNC_FILE; }
-
- /*
- * Specials
- */
-"true" { return T_TRUE; }
-"false" { return T_FALSE; }
-
- /*
- * Digits
- */
-[0-9]+ {
- yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
- return T_DIGIT;
-}
-
- /*
- * Identifiers
- */
-[a-zA-Z][a-zA-Z0-9_:-]* {
- yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
- return T_ID;
-}
-
- /*
- * Anything else is returned as is...
- */
-.|\n {
- return yytext[0];
-}
-
-%%
-
-
#define MOD_SSL_VERSION AP_SERVER_BASEREVISION
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+
+#ifndef YY_NULL
+#define YY_NULL 0
+#endif
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifndef BOOL
+#define BOOL unsigned int
+#endif
+
+#ifndef NULL
+#define NULL (void *)0
+#endif
+
+#ifndef NUL
+#define NUL '\0'
+#endif
+
+
/* mod_ssl headers */
#include "ssl_toolkit_compat.h"
-#include "ssl_expr.h"
+#include "ap_expr.h"
#include "ssl_util_ssl.h"
/* The #ifdef macros are only defined AFTER including the above
* Define the SSL requirement structure
*/
typedef struct {
- char *cpExpr;
- ssl_expr *mpExpr;
+ char *cpExpr;
+ ap_expr_info_t *mpExpr;
} ssl_require_t;
/**
/** Apache authz provisders */
extern const authz_provider ssl_authz_provider_require_ssl;
extern const authz_provider ssl_authz_provider_verify_client;
-extern const authz_provider ssl_authz_provider_sslrequire;
/** OpenSSL callbacks */
RSA *ssl_callback_TmpRSA(SSL *, int, int);
util_script.c util_md5.c util_cfgtree.c util_ebcdic.c util_time.c \
connection.c listen.c util_mutex.c mpm_common.c mpm_unix.c \
util_charset.c util_cookies.c util_debug.c util_xml.c \
- util_expr.c util_filter.c util_pcre.c util_regex.c exports.c \
+ util_filter.c util_pcre.c util_regex.c exports.c \
scoreboard.c error_bucket.c protocol.c core.c request.c provider.c \
- eoc_bucket.c eor_bucket.c core_filters.c
+ eoc_bucket.c eor_bucket.c core_filters.c \
+ util_expr_parse.c util_expr_scan.c util_expr_eval.c
TARGETS = delete-exports $(LTLIBRARY_NAME) $(CORE_IMPLIB_FILE) export_vars.h httpd.exp
@echo "* Please do not edit by hand." >> $@
$(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) exports.c | grep "ap_hack_" | grep -v apr_ | sed -e 's/^.*[)]\(.*\);$$/\1/' >> $@
$(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep -v apr_ | sed -e 's/^\#[^!]*//' | sed -e '/^$$/d' >> $@
+
+
+# developer stuff
+# (we really don't expect end users to use these targets!)
+#
+util_expr_scan.c util_expr_parse.c util_expr_parse.h: util_expr_scan.l util_expr_parse.y
+ bison -pap_expr_yy --defines=$(builddir)/util_expr_parse.h \
+ -o $(builddir)/util_expr_parse.c $(srcdir)/util_expr_parse.y
+ flex -Pap_expr_yy -o $(builddir)/util_expr_scan.c $(srcdir)/util_expr_scan.l
+ set -e ; \
+ for f in util_expr_scan.c util_expr_parse.c util_expr_parse.h ; do \
+ sed -e "s|\"$(builddir)/|\"|g" < $(builddir)/$$f > \
+ $(builddir)/$$f.$$$$ && \
+ mv $(builddir)/$$f.$$$$ $(builddir)/$$f ; \
+ done
+
const char *err = ap_check_cmd_context(cmd,
NOT_IN_LOCATION | NOT_IN_LIMIT);
const char *condition;
- int expr_err = 0;
+ const char *expr_err;
if (err != NULL) {
return err;
conf = ap_set_config_vectors(cmd->server, new_file_conf, cmd->path,
&core_module, cmd->pool);
- conf->condition = ap_expr_parse(cmd->pool, condition, &expr_err);
+ conf->condition = ap_expr_parse_cmd(cmd, condition, &expr_err, NULL);
if (expr_err) {
- return "Cannot parse condition clause";
+ return apr_psprintf(cmd->pool, "Cannot parse condition clause: %s", expr_err);
}
errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_file_conf);
{
errorlog_hash = apr_hash_make(p);
ap_register_log_hooks(p);
+ ap_expr_init(p);
/* create_connection and pre_connection should always be hooked
* APR_HOOK_REALLY_LAST by core to give other modules the opportunity
#include "apr_uri.h"
#include "util_ebcdic.h"
#include "ap_mpm.h"
-#include "ap_expr.h"
#if APR_HAVE_UNISTD_H
#include <unistd.h>
destroy_and_exit_process(process, 1);
}
#endif
- if (ap_expr_init(ap_pglobal) != APR_SUCCESS) {
- destroy_and_exit_process(process, 1);
- }
apr_pool_create(&pcommands, ap_pglobal);
apr_pool_tag(pcommands, "pcommands");
* really try them with the most general first.
*/
for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) {
- int err = 0;
+ const char *err = NULL;
core_dir_config *entry_core;
entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module);
if (entry_core->condition) {
- if (!ap_expr_eval(r, entry_core->condition, &err, NULL,
- ap_expr_string, NULL)) {
+ /* XXX: error handling */
+ if (!ap_expr_exec(r, entry_core->condition, &err)) {
continue;
}
}
+++ /dev/null
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "apr.h"
-#include "apr_strings.h"
-#include "apr_lib.h"
-
-#define APR_WANT_STRFUNC
-#define APR_WANT_MEMFUNC
-#include "apr_want.h"
-
-#include "httpd.h"
-#include "http_log.h"
-#include "http_core.h"
-
-#include "ap_expr.h"
-
-APLOG_USE_MODULE(core);
-
-#if 1
-/*
- * +-------------------------------------------------------+
- * | |
- * | Debugging Utilities
- * | |
- * +-------------------------------------------------------+
- */
-
-#ifdef DEBUG_INCLUDE
-
-#define TYPE_TOKEN(token, ttype) do { \
- (token)->type = ttype; \
- (token)->s = #ttype; \
-} while(0)
-
-#define CREATE_NODE(pool,name) do { \
- (name) = apr_pcalloc(pool, sizeof(*(name))); \
-} while(0)
-
-static void debug_printf(request_rec *r, const char *fmt, ...)
-{
- va_list ap;
- char *debug__str;
-
- va_start(ap, fmt);
- debug__str = apr_pvsprintf(r->pool, fmt, ap);
- va_end(ap);
-/*
- APR_BRIGADE_INSERT_TAIL(ctx->intern->debug.bb, apr_bucket_pool_create(
- debug__str, strlen(debug__str), ctx->pool,
- ctx->intern->debug.f->c->bucket_alloc));
- */
-}
-
-#define DUMP__CHILD(ctx, is, node, child) if (1) { \
- ap_parse_node_t *d__c = node->child; \
- if (d__c) { \
- if (!d__c->dump_done) { \
- if (d__c->parent != node) { \
- debug_printf(ctx, "!!! Parse tree is not consistent !!!\n"); \
- if (!d__c->parent) { \
- debug_printf(ctx, "Parent of " #child " child node is " \
- "NULL.\n"); \
- } \
- else { \
- debug_printf(ctx, "Parent of " #child " child node " \
- "points to another node (of type %s)!\n", \
- d__c->parent->token.s); \
- } \
- return; \
- } \
- node = d__c; \
- continue; \
- } \
- } \
- else { \
- debug_printf(ctx, "%s(missing)\n", is); \
- } \
-}
-
-static void debug_dump_tree(include_ctx_t *ctx, ap_parse_node_t *root)
-{
- ap_parse_node_t *current;
- char *is;
-
- if (!root) {
- debug_printf(ctx, " -- Parse Tree empty --\n\n");
- return;
- }
-
- debug_printf(ctx, " ----- Parse Tree -----\n");
- current = root;
- is = " ";
-
- while (current) {
- switch (current->token.type) {
- case TOKEN_STRING:
- case TOKEN_RE:
- debug_printf(ctx, "%s%s (%s)\n", is, current->token.s,
- current->token.value);
- current->dump_done = 1;
- current = current->parent;
- continue;
-
- case TOKEN_NOT:
- case TOKEN_GROUP:
- case TOKEN_RBRACE:
- case TOKEN_LBRACE:
- if (!current->dump_done) {
- debug_printf(ctx, "%s%s\n", is, current->token.s);
- is = apr_pstrcat(ctx->dpool, is, " ", NULL);
- current->dump_done = 1;
- }
-
- DUMP__CHILD(ctx, is, current, right)
-
- if (!current->right || current->right->dump_done) {
- is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4);
- if (current->right) current->right->dump_done = 0;
- current = current->parent;
- }
- continue;
-
- default:
- if (!current->dump_done) {
- debug_printf(ctx, "%s%s\n", is, current->token.s);
- is = apr_pstrcat(ctx->dpool, is, " ", NULL);
- current->dump_done = 1;
- }
-
- DUMP__CHILD(ctx, is, current, left)
- DUMP__CHILD(ctx, is, current, right)
-
- if ((!current->left || current->left->dump_done) &&
- (!current->right || current->right->dump_done)) {
-
- is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4);
- if (current->left) current->left->dump_done = 0;
- if (current->right) current->right->dump_done = 0;
- current = current->parent;
- }
- continue;
- }
- }
-
- /* it is possible to call this function within the parser loop, to see
- * how the tree is built. That way, we must cleanup after us to dump
- * always the whole tree
- */
- root->dump_done = 0;
- if (root->left) root->left->dump_done = 0;
- if (root->right) root->right->dump_done = 0;
-
- debug_printf(ctx, " --- End Parse Tree ---\n\n");
-
- return;
-}
-
-#define DEBUG_INIT(ctx, filter, brigade) do { \
- (ctx)->intern->debug.f = filter; \
- (ctx)->intern->debug.bb = brigade; \
-} while(0)
-
-#define DEBUG_PRINTF(arg) debug_printf arg
-
-#define DEBUG_DUMP_TOKEN(ctx, token) do { \
- token_t *d__t = (token); \
- \
- if (d__t->type == TOKEN_STRING || d__t->type == TOKEN_RE) { \
- DEBUG_PRINTF(((ctx), " Found: %s (%s)\n", d__t->s, d__t->value)); \
- } \
- else { \
- DEBUG_PRINTF((ctx, " Found: %s\n", d__t->s)); \
- } \
-} while(0)
-
-#define DEBUG_DUMP_EVAL(r, node) do { \
- char c = '"'; \
- switch ((node)->token.type) { \
- case TOKEN_STRING: \
- debug_printf((r), " Evaluate: %s (%s) -> %c\n", (node)->token.s,\
- (node)->token.value, ((node)->value) ? '1':'0'); \
- break; \
- case TOKEN_AND: \
- case TOKEN_OR: \
- debug_printf((r), " Evaluate: %s (Left: %s; Right: %s) -> %c\n",\
- (node)->token.s, \
- (((node)->left->done) ? ((node)->left->value ?"1":"0") \
- : "short circuited"), \
- (((node)->right->done) ? ((node)->right->value?"1":"0") \
- : "short circuited"), \
- (node)->value ? '1' : '0'); \
- break; \
- case TOKEN_EQ: \
- case TOKEN_NE: \
- case TOKEN_GT: \
- case TOKEN_GE: \
- case TOKEN_LT: \
- case TOKEN_LE: \
- if ((node)->right->token.type == TOKEN_RE) c = '/'; \
- debug_printf((r), " Compare: %s (\"%s\" with %c%s%c) -> %c\n", \
- (node)->token.s, \
- (node)->left->token.value, \
- c, (node)->right->token.value, c, \
- (node)->value ? '1' : '0'); \
- break; \
- default: \
- debug_printf((r), " Evaluate: %s -> %c\n", (node)->token.s, \
- (node)->value ? '1' : '0'); \
- break; \
- } \
-} while(0)
-
-#define DEBUG_DUMP_UNMATCHED(r, unmatched) do { \
- if (unmatched) { \
- DEBUG_PRINTF(((r), " Unmatched %c\n", (char)(unmatched))); \
- } \
-} while(0)
-
-#define DEBUG_DUMP_COND(ctx, text) \
- DEBUG_PRINTF(((ctx), "**** %s cond status=\"%c\"\n", (text), \
- ((ctx)->flags & SSI_FLAG_COND_TRUE) ? '1' : '0'))
-
-#define DEBUG_DUMP_TREE(ctx, root) debug_dump_tree(ctx, root)
-
-#else /* DEBUG_INCLUDE */
-
-#define TYPE_TOKEN(token, ttype) (token)->type = ttype
-
-#define CREATE_NODE(pool,name) do { \
- (name) = apr_pcalloc(pool, sizeof(*(name))); \
-} while(0)
-
-#define DEBUG_INIT(ctx, f, bb)
-#define DEBUG_PRINTF(arg)
-#define DEBUG_DUMP_TOKEN(ctx, token)
-#define DEBUG_DUMP_EVAL(ctx, node)
-#define DEBUG_DUMP_UNMATCHED(ctx, unmatched)
-#define DEBUG_DUMP_COND(ctx, text)
-#define DEBUG_DUMP_TREE(ctx, root)
-
-#endif /* !DEBUG_INCLUDE */
-
-#endif /* 0 */
-
-
-/*
- * +-------------------------------------------------------+
- * | |
- * | Conditional Expression Parser
- * | |
- * +-------------------------------------------------------+
- */
-static APR_INLINE int re_check(request_rec *r, const char *string,
- const char *rexp, backref_t **reptr)
-{
- ap_regex_t *compiled;
- backref_t *re = reptr ? *reptr : NULL;
-
- compiled = ap_pregcomp(r->pool, rexp, AP_REG_EXTENDED);
- if (!compiled) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unable to "
- "compile pattern \"%s\"", rexp);
- return -1;
- }
-
- if (!re) {
- re = apr_palloc(r->pool, sizeof(*re));
- if (reptr) {
- *reptr = re;
- }
- }
-
- re->source = apr_pstrdup(r->pool, string);
- re->rexp = apr_pstrdup(r->pool, rexp);
- re->nsub = compiled->re_nsub;
- re->have_match = !ap_regexec(compiled, string, AP_MAX_REG_MATCH,
- re->match, 0);
-
- ap_pregfree(r->pool, compiled);
- return re->have_match;
-}
-
-static int get_ptoken(apr_pool_t *pool, const char **parse, token_t *token,
- token_t *previous)
-{
- const char *p;
- apr_size_t shift;
- int unmatched;
-
- token->value = NULL;
-
- if (!*parse) {
- return 0;
- }
-
- /* Skip leading white space */
- while (apr_isspace(**parse)) {
- ++*parse;
- }
-
- if (!**parse) {
- *parse = NULL;
- return 0;
- }
-
- TYPE_TOKEN(token, TOKEN_STRING); /* the default type */
- p = *parse;
- unmatched = 0;
-
- switch (*(*parse)++) {
- case '(':
- TYPE_TOKEN(token, TOKEN_LBRACE);
- return 0;
- case ')':
- TYPE_TOKEN(token, TOKEN_RBRACE);
- return 0;
- case '=':
- if (**parse == '=') ++*parse;
- TYPE_TOKEN(token, TOKEN_EQ);
- return 0;
- case '!':
- if (**parse == '=') {
- TYPE_TOKEN(token, TOKEN_NE);
- ++*parse;
- return 0;
- }
- TYPE_TOKEN(token, TOKEN_NOT);
- return 0;
- case '\'':
- unmatched = '\'';
- break;
- case '/':
- /* if last token was ACCESS, this token is STRING */
- if (previous != NULL && TOKEN_ACCESS == previous->type) {
- break;
- }
- TYPE_TOKEN(token, TOKEN_RE);
- unmatched = '/';
- break;
- case '|':
- if (**parse == '|') {
- TYPE_TOKEN(token, TOKEN_OR);
- ++*parse;
- return 0;
- }
- break;
- case '&':
- if (**parse == '&') {
- TYPE_TOKEN(token, TOKEN_AND);
- ++*parse;
- return 0;
- }
- break;
- case '>':
- if (**parse == '=') {
- TYPE_TOKEN(token, TOKEN_GE);
- ++*parse;
- return 0;
- }
- TYPE_TOKEN(token, TOKEN_GT);
- return 0;
- case '<':
- if (**parse == '=') {
- TYPE_TOKEN(token, TOKEN_LE);
- ++*parse;
- return 0;
- }
- TYPE_TOKEN(token, TOKEN_LT);
- return 0;
- case '-':
- if (apr_isalnum(**parse) && apr_isspace((*parse)[1])) {
- TYPE_TOKEN(token, TOKEN_ACCESS);
- token->value = *parse;
- ++*parse;
- return 0;
- }
- break;
- case 'I':
- if (**parse == 'N') {
- TYPE_TOKEN(token, TOKEN_IN);
- ++*parse;
- return 0;
- }
- break;
- }
-
- /* It's a string or regex token
- * Now search for the next token, which finishes this string
- */
- shift = 0;
- p = *parse = token->value = unmatched ? *parse : p;
-
- for (; **parse; p = ++*parse) {
- if (**parse == '\\') {
- if (!*(++*parse)) {
- p = *parse;
- break;
- }
-
- ++shift;
- }
- else {
- if (unmatched) {
- if (**parse == unmatched) {
- unmatched = 0;
- ++*parse;
- break;
- }
- }
- else if (apr_isspace(**parse)) {
- break;
- }
- else {
- int found = 0;
-
- switch (**parse) {
- case '(':
- case ')':
- case '=':
- case '!':
- case '<':
- case '>':
- ++found;
- break;
-
- case '|':
- case '&':
- if ((*parse)[1] == **parse) {
- ++found;
- }
- break;
- }
-
- if (found) {
- break;
- }
- }
- }
- }
-
- if (unmatched) {
- token->value = apr_pstrdup(pool, "");
- }
- else {
- apr_size_t len = p - token->value - shift;
- char *c = apr_palloc(pool, len + 1);
-
- p = token->value;
- token->value = c;
-
- while (shift--) {
- const char *e = ap_strchr_c(p, '\\');
-
- memcpy(c, p, e-p);
- c += e-p;
- *c++ = *++e;
- len -= e-p;
- p = e+1;
- }
-
- if (len) {
- memcpy(c, p, len);
- }
- c[len] = '\0';
- }
-
- return unmatched;
-}
-
-/* This is what we export. We can split it in two. */
-AP_DECLARE(ap_parse_node_t*) ap_expr_parse(apr_pool_t* pool, const char *expr,
- int *was_error)
-{
- ap_parse_node_t *new, *root = NULL, *current = NULL;
- const char *error = "Invalid expression \"%s\" in file %s";
- const char *parse = expr;
- int was_unmatched = 0;
- unsigned regex = 0;
-
- *was_error = 0;
-
- if (!parse) {
- return 0;
- }
-
- /* Create Parse Tree */
- while (1) {
- /* uncomment this to see how the tree a built:
- *
- * DEBUG_DUMP_TREE(ctx, root);
- */
- CREATE_NODE(pool, new);
-
- was_unmatched = get_ptoken(pool, &parse, &new->token,
- (current != NULL ? ¤t->token : NULL));
- if (!parse) {
- break;
- }
-
- DEBUG_DUMP_UNMATCHED(ctx, was_unmatched);
- DEBUG_DUMP_TOKEN(ctx, &new->token);
-
- if (!current) {
- switch (new->token.type) {
- case TOKEN_STRING:
- case TOKEN_NOT:
- case TOKEN_ACCESS:
- case TOKEN_LBRACE:
- root = current = new;
- continue;
-
- default:
- *was_error = 1;
- return 0;
- }
- }
-
- switch (new->token.type) {
- case TOKEN_STRING:
- switch (current->token.type) {
- case TOKEN_STRING:
- current->token.value =
- apr_pstrcat(pool, current->token.value,
- *current->token.value ? " " : "",
- new->token.value, NULL);
- continue;
-
- case TOKEN_RE:
- case TOKEN_RBRACE:
- case TOKEN_GROUP:
- break;
-
- default:
- new->parent = current;
- current = current->right = new;
- continue;
- }
- break;
-
- case TOKEN_RE:
- switch (current->token.type) {
- case TOKEN_EQ:
- case TOKEN_NE:
- new->parent = current;
- current = current->right = new;
- ++regex;
- continue;
-
- default:
- break;
- }
- break;
-
- case TOKEN_AND:
- case TOKEN_OR:
- switch (current->token.type) {
- case TOKEN_STRING:
- case TOKEN_RE:
- case TOKEN_GROUP:
- current = current->parent;
-
- while (current) {
- switch (current->token.type) {
- case TOKEN_AND:
- case TOKEN_OR:
- case TOKEN_LBRACE:
- break;
-
- default:
- current = current->parent;
- continue;
- }
- break;
- }
-
- if (!current) {
- new->left = root;
- root->parent = new;
- current = root = new;
- continue;
- }
-
- new->left = current->right;
- new->left->parent = new;
- new->parent = current;
- current = current->right = new;
- continue;
-
- default:
- break;
- }
- break;
-
- case TOKEN_EQ:
- case TOKEN_NE:
- case TOKEN_GE:
- case TOKEN_GT:
- case TOKEN_LE:
- case TOKEN_LT:
- case TOKEN_IN:
- if (current->token.type == TOKEN_STRING) {
- current = current->parent;
-
- if (!current) {
- new->left = root;
- root->parent = new;
- current = root = new;
- continue;
- }
-
- switch (current->token.type) {
- case TOKEN_LBRACE:
- case TOKEN_AND:
- case TOKEN_OR:
- new->left = current->right;
- new->left->parent = new;
- new->parent = current;
- current = current->right = new;
- continue;
-
- default:
- break;
- }
- }
- break;
-
- case TOKEN_RBRACE:
- while (current && current->token.type != TOKEN_LBRACE) {
- current = current->parent;
- }
-
- if (current) {
- TYPE_TOKEN(¤t->token, TOKEN_GROUP);
- continue;
- }
-
- error = "Unmatched ')' in \"%s\" in file %s";
- break;
-
- case TOKEN_NOT:
- case TOKEN_ACCESS:
- case TOKEN_LBRACE:
- switch (current->token.type) {
- case TOKEN_STRING:
- case TOKEN_RE:
- case TOKEN_RBRACE:
- case TOKEN_GROUP:
- break;
-
- default:
- current->right = new;
- new->parent = current;
- current = new;
- continue;
- }
- break;
-
- default:
- break;
- }
-
- *was_error = 1;
- return 0;
- }
-
- DEBUG_DUMP_TREE(ctx, root);
- return root;
-}
-
-static ap_parse_node_t *ap_expr_clone_tree(apr_pool_t *pool,
- const ap_parse_node_t *pnode,
- ap_parse_node_t *parent)
-{
- ap_parse_node_t *ret;
- ret = apr_pmemdup(pool, pnode, sizeof(ap_parse_node_t));
- if (pnode->left) {
- ret->left = ap_expr_clone_tree(pool, pnode->left, ret);
- }
- if (pnode->right) {
- ret->right = ap_expr_clone_tree(pool, pnode->right, ret);
- }
- ret->parent = parent;
- return ret;
-}
-
-#define PARSE_STRING(r,s) (string_func ? string_func((r),(s)) : (s))
-static int expr_eval(request_rec *r, ap_parse_node_t *root,
- int *was_error, backref_t **reptr,
- string_func_t string_func, opt_func_t eval_func)
-{
- ap_parse_node_t *current = root;
- const char *error = NULL;
- unsigned int regex = 0;
- const char *val;
- const char *lval;
- const char *rval;
-
- /* Evaluate Parse Tree */
- while (current) {
- switch (current->token.type) {
- case TOKEN_STRING:
- val = PARSE_STRING(r, current->token.value);
- current->value = !!*val;
- break;
-
- case TOKEN_AND:
- case TOKEN_OR:
- if (!current->left || !current->right) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Invalid expression in file %s", r->filename);
- *was_error = 1;
- return 0;
- }
-
- if (!current->left->done) {
- switch (current->left->token.type) {
- case TOKEN_STRING:
- lval = PARSE_STRING(r, current->left->token.value);
- current->left->value = !!*lval;
- DEBUG_DUMP_EVAL(ctx, current->left);
- current->left->done = 1;
- break;
-
- default:
- current = current->left;
- continue;
- }
- }
-
- /* short circuit evaluation */
- if (!current->right->done && !regex &&
- ((current->token.type == TOKEN_AND && !current->left->value) ||
- (current->token.type == TOKEN_OR && current->left->value))) {
- current->value = current->left->value;
- }
- else {
- if (!current->right->done) {
- switch (current->right->token.type) {
- case TOKEN_STRING:
- rval = PARSE_STRING(r,current->right->token.value);
- current->right->value = !!*rval;
- DEBUG_DUMP_EVAL(r, current->right);
- current->right->done = 1;
- break;
-
- default:
- current = current->right;
- continue;
- }
- }
-
- if (current->token.type == TOKEN_AND) {
- current->value = current->left->value &&
- current->right->value;
- }
- else {
- current->value = current->left->value ||
- current->right->value;
- }
- }
- break;
-
- case TOKEN_EQ:
- case TOKEN_NE:
- if (!current->left || !current->right ||
- current->left->token.type != TOKEN_STRING ||
- (current->right->token.type != TOKEN_STRING &&
- current->right->token.type != TOKEN_RE)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Invalid expression in file %s", r->filename);
- *was_error = 1;
- return 0;
- }
- lval = PARSE_STRING(r, current->left->token.value);
- rval = PARSE_STRING(r, current->right->token.value);
-
- if (current->right->token.type == TOKEN_RE) {
- current->value = re_check(r, lval, rval, reptr);
- --regex;
- }
- else {
- current->value = !strcmp(lval, rval);
- }
-
- if (current->token.type == TOKEN_NE) {
- current->value = !current->value;
- }
- break;
-
- case TOKEN_GE:
- case TOKEN_GT:
- case TOKEN_LE:
- case TOKEN_LT:
- if (!current->left || !current->right ||
- current->left->token.type != TOKEN_STRING ||
- current->right->token.type != TOKEN_STRING) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Invalid expression in file %s", r->filename);
- *was_error = 1;
- return 0;
- }
-
- lval = PARSE_STRING(r, current->left->token.value);
- rval = PARSE_STRING(r, current->right->token.value);
-
- current->value = strcmp(lval, rval);
-
- switch (current->token.type) {
- case TOKEN_GE: current->value = current->value >= 0; break;
- case TOKEN_GT: current->value = current->value > 0; break;
- case TOKEN_LE: current->value = current->value <= 0; break;
- case TOKEN_LT: current->value = current->value < 0; break;
- default: current->value = 0; break; /* should not happen */
- }
- break;
- case TOKEN_IN:
- if (!current->left || !current->right ||
- current->left->token.type != TOKEN_STRING ||
- current->right->token.type != TOKEN_STRING) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Invalid expression in file %s", r->filename);
- *was_error = 1;
- return 0;
- }
-
- lval = PARSE_STRING(r, current->left->token.value);
- rval = PARSE_STRING(r, current->right->token.value);
- val = ap_strstr_c(rval, lval);
- /* should be included as a complete word, not a subword
- * as in regexp /\bLVAL\b/
- */
- current->value = (val != NULL
- && (val == rval || !isalnum(val[-1]))
- && !isalnum(val[strlen(val)]))
- ? 1 : 0;
- break;
-
- case TOKEN_NOT:
- case TOKEN_GROUP:
- if (current->right) {
- if (!current->right->done) {
- current = current->right;
- continue;
- }
- current->value = current->right->value;
- }
- else {
- current->value = 1;
- }
-
- if (current->token.type == TOKEN_NOT) {
- current->value = !current->value;
- }
- break;
- case TOKEN_ACCESS:
- if (eval_func) {
- *was_error = eval_func(r, current, string_func);
- if (*was_error) {
- return 0;
- }
- }
- break;
-
- case TOKEN_RE:
- if (!error) {
- error = "No operator before regex in file %s";
- }
- case TOKEN_LBRACE:
- if (!error) {
- error = "Unmatched '(' in file %s";
- }
- default:
- if (!error) {
- error = "internal parser error in file %s";
- }
-
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, r->filename);
- *was_error = 1;
- return 0;
- }
-
- DEBUG_DUMP_EVAL(r, current);
- current->done = 1;
- current = current->parent;
- }
-
- return (root ? root->value : 0);
-}
-AP_DECLARE(int) ap_expr_eval(request_rec *r, const ap_parse_node_t *root,
- int *was_error, backref_t **reptr,
- string_func_t string_func, opt_func_t eval_func)
-{
- ap_parse_node_t *clone;
- if (root == NULL) { /* no condition == unconditional */
- return 1;
- }
- clone = ap_expr_clone_tree(r->pool, root, NULL);
- return expr_eval(r, clone, was_error, reptr, string_func, eval_func);
-}
-AP_DECLARE(int) ap_expr_evalstring(request_rec *r, const char *expr,
- int *was_error, backref_t **reptr,
- string_func_t string_func,
- opt_func_t eval_func)
-{
- ap_parse_node_t *root = ap_expr_parse(r->pool, expr, was_error);
- if (*was_error || !root) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Error parsing expression in %s", r->filename);
- return 0;
- }
- return expr_eval(r, root, was_error, reptr, string_func, eval_func);
-}
-
-
-static ap_regex_t *isvar = NULL;
-AP_DECLARE_NONSTD(const char*) ap_expr_string(request_rec *r,
- const char *str)
-{
- /* a default string evaluator: support headers and env */
- const char *ret = str;
- ap_regmatch_t match[3];
- const char *p;
-
- ap_assert(isvar != NULL);
- if (ap_regexec(isvar, str, 3, match, 0) == 0) {
- apr_table_t *table = NULL;
- int len = match[1].rm_eo-match[1].rm_so;
- const char *name = str+match[1].rm_so;
- if (!strncasecmp("req", name, len)) {
- table = r->headers_in;
- }
- else if (!strncasecmp("resp", name, len)) {
- table = r->headers_out;
- }
- else if (!strncasecmp("env", name, len)) {
- table = r->subprocess_env;
- }
- if (table != NULL) {
- char *key = apr_pstrndup(r->pool, str+match[2].rm_so,
- match[2].rm_eo-match[2].rm_so);
- ret = apr_table_get(table, key);
- }
- }
- else if (str[0] == '$') {
- if (!strcasecmp(str, "$handler")) {
- ret = r->handler;
- }
- else if (!strcasecmp(str, "$content-type")) {
- ret = r->content_type;
- }
- }
-
- /* copy wholesale from mod_rewrite to support its %{varname} vars */
- else if ((str[0] == '%') && (str[1] == '{')
- && (p = ap_strchr_c(str, '}'), p != NULL)) {
- char *ch, *var;
- apr_time_exp_t tm;
-
- var = apr_pstrndup(r->pool, str+2, p-str-2);
- for (ch = var; *ch; ++ch) {
- *ch = apr_toupper(*ch);
- }
-
- switch (strlen(var)) {
- case 4:
- if (!strcmp(var, "TIME")) {
- apr_time_exp_lt(&tm, apr_time_now());
- ret = apr_psprintf(r->pool, "%04d%02d%02d%02d%02d%02d",
- tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- return (char *)ret;
- }
- else if (!strcmp(var, "IPV6")) {
- int flag = FALSE;
-#if APR_HAVE_IPV6
- apr_sockaddr_t *addr = r->connection->remote_addr;
- flag = (addr->family == AF_INET6 &&
- !IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr));
-#endif
- ret = (flag ? "on" : "off");
- }
- break;
-
-#if FIXME
- case 5:
- if (!strcmp(var, "HTTPS")) {
- int flag = rewrite_is_https && rewrite_is_https(r->connection);
- return apr_pstrdup(r->pool, flag ? "on" : "off");
- }
- break;
-#endif
- case 8:
- switch (var[6]) {
- case 'A':
- if (!strcmp(var, "TIME_DAY")) {
- apr_time_exp_lt(&tm, apr_time_now());
- return apr_psprintf(r->pool, "%02d", tm.tm_mday);
- }
- break;
-
- case 'E':
- if (!strcmp(var, "TIME_SEC")) {
- apr_time_exp_lt(&tm, apr_time_now());
- return apr_psprintf(r->pool, "%02d", tm.tm_sec);
- }
- break;
-
- case 'I':
- if (!strcmp(var, "TIME_MIN")) {
- apr_time_exp_lt(&tm, apr_time_now());
- return apr_psprintf(r->pool, "%02d", tm.tm_min);
- }
- break;
-
- case 'O':
- if (!strcmp(var, "TIME_MON")) {
- apr_time_exp_lt(&tm, apr_time_now());
- return apr_psprintf(r->pool, "%02d", tm.tm_mon+1);
- }
- break;
- }
- break;
-
- case 9:
- switch (var[7]) {
- case 'A':
- if (var[8] == 'Y' && !strcmp(var, "TIME_WDAY")) {
- apr_time_exp_lt(&tm, apr_time_now());
- return apr_psprintf(r->pool, "%d", tm.tm_wday);
- }
- else if (!strcmp(var, "TIME_YEAR")) {
- apr_time_exp_lt(&tm, apr_time_now());
- return apr_psprintf(r->pool, "%04d", tm.tm_year+1900);
- }
- break;
-
- case 'E':
- if (!strcmp(var, "IS_SUBREQ")) {
- ret = (r->main ? "true" : "false");
- }
- break;
-
- case 'F':
- if (!strcmp(var, "PATH_INFO")) {
- ret = r->path_info;
- }
- break;
-
- case 'P':
- if (!strcmp(var, "AUTH_TYPE")) {
- ret = r->ap_auth_type;
- }
- break;
-
- case 'S':
- if (!strcmp(var, "HTTP_HOST")) {
- ret = apr_table_get(r->headers_in, "Host");
- }
- break;
-
- case 'U':
- if (!strcmp(var, "TIME_HOUR")) {
- apr_time_exp_lt(&tm, apr_time_now());
- return apr_psprintf(r->pool, "%02d", tm.tm_hour);
- }
- break;
- }
- break;
-
- case 11:
- switch (var[8]) {
- case 'A':
- if (!strcmp(var, "SERVER_NAME")) {
- ret = ap_get_server_name(r);
- }
- break;
-
- case 'D':
- if (*var == 'R' && !strcmp(var, "REMOTE_ADDR")) {
- ret = r->connection->remote_ip;
- }
- else if (!strcmp(var, "SERVER_ADDR")) {
- ret = r->connection->local_ip;
- }
- break;
-
- case 'E':
- if (*var == 'H' && !strcmp(var, "HTTP_ACCEPT")) {
- ret = apr_table_get(r->headers_in, "Accept");
- }
- else if (!strcmp(var, "THE_REQUEST")) {
- ret = r->the_request;
- }
- break;
-
- case 'I':
- if (!strcmp(var, "API_VERSION")) {
- return apr_psprintf(r->pool, "%d:%d",
- MODULE_MAGIC_NUMBER_MAJOR,
- MODULE_MAGIC_NUMBER_MINOR);
- }
- break;
-
- case 'K':
- if (!strcmp(var, "HTTP_COOKIE")) {
- ret = apr_table_get(r->headers_in, "Cookie");
- }
- break;
-
- case 'O':
- if (*var == 'S' && !strcmp(var, "SERVER_PORT")) {
- return apr_psprintf(r->pool, "%u", ap_get_server_port(r));
- }
- else if (var[7] == 'H' && !strcmp(var, "REMOTE_HOST")) {
- ret = ap_get_remote_host(r->connection,r->per_dir_config,
- REMOTE_NAME, NULL);
- }
- else if (!strcmp(var, "REMOTE_PORT")) {
- return apr_itoa(r->pool, r->connection->remote_addr->port);
- }
- break;
-
- case 'S':
- if (*var == 'R' && !strcmp(var, "REMOTE_USER")) {
- ret = r->user;
- }
- else if (!strcmp(var, "SCRIPT_USER")) {
- ret = "<unknown>";
- if (r->finfo.valid & APR_FINFO_USER) {
- apr_uid_name_get((char **)&ret, r->finfo.user,
- r->pool);
- }
- }
- break;
-
- case 'U':
- if (!strcmp(var, "REQUEST_URI")) {
- ret = r->uri;
- }
- break;
- }
- break;
-
- case 12:
- switch (var[3]) {
- case 'I':
- if (!strcmp(var, "SCRIPT_GROUP")) {
- ret = "<unknown>";
- if (r->finfo.valid & APR_FINFO_GROUP) {
- apr_gid_name_get((char **)&ret, r->finfo.group,
- r->pool);
- }
- }
- break;
-
- case 'O':
- if (!strcmp(var, "REMOTE_IDENT")) {
- ret = ap_get_remote_logname(r);
- }
- break;
-
- case 'P':
- if (!strcmp(var, "HTTP_REFERER")) {
- ret = apr_table_get(r->headers_in, "Referer");
- }
- break;
-
- case 'R':
- if (!strcmp(var, "QUERY_STRING")) {
- ret = r->args;
- }
- break;
-
- case 'V':
- if (!strcmp(var, "SERVER_ADMIN")) {
- ret = r->server->server_admin;
- }
- break;
- }
- break;
-
- case 13:
- if (!strcmp(var, "DOCUMENT_ROOT")) {
- ret = ap_document_root(r);
- }
- break;
-
- case 14:
- if (*var == 'H' && !strcmp(var, "HTTP_FORWARDED")) {
- ret = apr_table_get(r->headers_in, "Forwarded");
- }
- else if (!strcmp(var, "REQUEST_METHOD")) {
- ret = r->method;
- }
- break;
-
- case 15:
- switch (var[7]) {
- case 'E':
- if (!strcmp(var, "HTTP_USER_AGENT")) {
- ret = apr_table_get(r->headers_in, "User-Agent");
- }
- break;
-
- case 'F':
- if (!strcmp(var, "SCRIPT_FILENAME")) {
- ret = r->filename; /* same as request_filename (16) */
- }
- break;
-
- case 'P':
- if (!strcmp(var, "SERVER_PROTOCOL")) {
- ret = r->protocol;
- }
- break;
-
- case 'S':
- if (!strcmp(var, "SERVER_SOFTWARE")) {
- ret = ap_get_server_banner();
- }
- break;
- }
- break;
-
- case 16:
- if (!strcmp(var, "REQUEST_FILENAME")) {
- ret = r->filename; /* same as script_filename (15) */
- }
- break;
-
- case 21:
- if (!strcmp(var, "HTTP_PROXY_CONNECTION")) {
- ret = apr_table_get(r->headers_in, "Proxy-Connection");
- }
- break;
- }
- }
-
- /* TODO: provide a hook so modules can interpret other patterns */
- /* OhBugger, where's the regexp for backreferences ? */
- if (!ret) {
- ret = "";
- }
- return ret; /* default - literal string as-is */
-}
-static apr_status_t ap_expr_term(void *expr)
-{
- if (isvar) {
- ap_regfree(isvar);
- isvar = NULL;
- }
- return APR_SUCCESS;
-}
-AP_DECLARE(apr_status_t) ap_expr_init(apr_pool_t *pool)
-{
- static ap_regex_t var;
- if (!isvar) {
- isvar = &var;
- if (ap_regcomp(isvar, "\\$([A-Za-z0-9]+)\\{([^\\}]+)\\}", 0)) {
- isvar = NULL;
- }
- else {
- apr_pool_cleanup_register(pool, isvar, ap_expr_term,
- apr_pool_cleanup_null);
- }
- }
- return isvar ? APR_SUCCESS : APR_EGENERAL;
-}
--- /dev/null
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* _ _
+ * ap_expr_eval.c, based on ssl_expr_eval.c from mod_ssl
+ */
+
+#include "httpd.h"
+#include "http_log.h"
+#include "http_core.h"
+#include "http_protocol.h"
+#include "ap_provider.h"
+#include "util_expr_private.h"
+
+#include "apr_lib.h"
+
+APLOG_USE_MODULE(core);
+
+APR_HOOK_STRUCT(
+ APR_HOOK_LINK(expr_lookup)
+)
+
+AP_IMPLEMENT_HOOK_RUN_FIRST(int, expr_lookup, (ap_expr_lookup_parms *parms),
+ (parms), DECLINED)
+
+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_var(ap_expr_eval_ctx *ctx,
+ const ap_expr_var_func_t *func,
+ const void *data);
+static void expr_dump_tree(const ap_expr *e, const server_rec *s, int loglevel, int indent);
+
+static const char *ap_expr_eval_word(ap_expr_eval_ctx *ctx, const ap_expr *node)
+{
+ const char *result = "";
+ switch (node->node_op) {
+ case op_Digit:
+ result = node->node_arg1;
+ break;
+ case op_String:
+ result = node->node_arg1;
+ break;
+ case op_Var:
+ result = ap_expr_eval_var(ctx, node->node_arg1, node->node_arg2);
+ 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;
+ }
+ default:
+ *ctx->err = "Internal evaluation error: Unknown expression node";
+ break;
+ }
+ if (!result)
+ result = "";
+ return result;
+}
+
+static const char *ap_expr_eval_var(ap_expr_eval_ctx *ctx,
+ const ap_expr_var_func_t *func,
+ const void *data)
+{
+ AP_DEBUG_ASSERT(func != NULL);
+ AP_DEBUG_ASSERT(data != NULL);
+ return (*func)(ctx, data);
+}
+
+static const char *ap_expr_eval_string_func(ap_expr_eval_ctx *ctx, const ap_expr *info,
+ const ap_expr *arg)
+{
+ ap_expr_string_func_t *func = info->node_arg1;
+ const void *data = info->node_arg2;
+
+ AP_DEBUG_ASSERT(info->node_op == op_StringFuncInfo);
+ AP_DEBUG_ASSERT(func != NULL);
+ AP_DEBUG_ASSERT(data != NULL);
+ return (*func)(ctx, data, ap_expr_eval_word(ctx, arg));
+}
+
+static int intstrcmp(const char *s1, const char *s2)
+{
+ apr_int64_t i1 = apr_atoi64(s1);
+ apr_int64_t i2 = apr_atoi64(s2);
+
+ if (i1 < i2)
+ return -1;
+ else if (i1 == i2)
+ return 0;
+ else
+ return 1;
+}
+
+static int ap_expr_eval_comp(ap_expr_eval_ctx *ctx, const ap_expr *node)
+{
+ switch (node->node_op) {
+ case op_EQ: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) == 0);
+ }
+ case op_NE: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) != 0);
+ }
+ case op_LT: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) < 0);
+ }
+ case op_LE: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <= 0);
+ }
+ case op_GT: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) > 0);
+ }
+ case op_GE: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >= 0);
+ }
+ case op_STR_EQ: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) == 0);
+ }
+ case op_STR_NE: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) != 0);
+ }
+ case op_STR_LT: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) < 0);
+ }
+ case op_STR_LE: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <= 0);
+ }
+ case op_STR_GT: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) > 0);
+ }
+ case op_STR_GE: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >= 0);
+ }
+ case op_IN: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ const char *needle = ap_expr_eval_word(ctx, e1);
+ if (e2->node_op == op_ListElement) {
+ do {
+ const ap_expr *val = e2->node_arg1;
+ AP_DEBUG_ASSERT(e2->node_op == op_ListElement);
+ if (strcmp(needle, ap_expr_eval_word(ctx, val)) == 0) {
+ return 1;
+ break;
+ }
+ e2 = e2->node_arg2;
+ } while (e2 != NULL);
+ }
+ else if (e2->node_op == op_ListFuncCall) {
+ const ap_expr *info = e2->node_arg1;
+ const ap_expr *arg = e2->node_arg2;
+ ap_expr_list_func_t *func = info->node_arg1;
+ apr_array_header_t *haystack;
+ int i = 0;
+ AP_DEBUG_ASSERT(func != NULL);
+ AP_DEBUG_ASSERT(info->node_op == op_ListFuncInfo);
+ haystack = (*func)(ctx, info->node_arg2, ap_expr_eval_word(ctx, arg));
+ if (haystack == NULL)
+ return 0;
+ for (; i < haystack->nelts; i++) {
+ if (strcmp(needle, APR_ARRAY_IDX(haystack,i,char *)) == 0)
+ return 1;
+ }
+ }
+ 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_NRE: {
+ 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);
+ }
+ default: {
+ *ctx->err = "Internal evaluation error: Unknown expression node";
+ return -1;
+ }
+ }
+}
+
+/* combined string/int comparison for compatibility with ssl_expr */
+static int strcmplex(const char *str1, const char *str2)
+{
+ int i, n1, n2;
+
+ if (str1 == NULL)
+ return -1;
+ if (str2 == NULL)
+ return +1;
+ n1 = strlen(str1);
+ n2 = strlen(str2);
+ if (n1 > n2)
+ return 1;
+ if (n1 < n2)
+ return -1;
+ for (i = 0; i < n1; i++) {
+ if (str1[i] > str2[i])
+ return 1;
+ if (str1[i] < str2[i])
+ return -1;
+ }
+ return 0;
+}
+
+static int ssl_expr_eval_comp(ap_expr_eval_ctx *ctx, const ap_expr *node)
+{
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ switch (node->node_op) {
+ case op_EQ:
+ case op_STR_EQ:
+ return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) == 0);
+ case op_NE:
+ case op_STR_NE:
+ return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) != 0);
+ case op_LT:
+ case op_STR_LT:
+ return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) < 0);
+ case op_LE:
+ case op_STR_LE:
+ return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <= 0);
+ case op_GT:
+ case op_STR_GT:
+ return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) > 0);
+ case op_GE:
+ case op_STR_GE:
+ return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >= 0);
+ default:
+ return ap_expr_eval_comp(ctx, node);
+ }
+}
+
+
+AP_DECLARE(const char *) ap_expr_parse(apr_pool_t *pool, apr_pool_t *ptemp,
+ ap_expr_info_t *info, const char *expr,
+ ap_expr_lookup_fn *lookup_fn)
+{
+ ap_expr_parse_ctx ctx;
+ int rc;
+
+ ctx.pool = pool;
+ ctx.ptemp = ptemp;
+ ctx.inputbuf = expr;
+ ctx.inputlen = strlen(expr);
+ ctx.inputptr = ctx.inputbuf;
+ ctx.expr = NULL;
+ ctx.error = NULL; /* generic bison error message (usually not very useful) */
+ ctx.error2 = NULL; /* additional error message */
+ ctx.flags = info->flags;
+ ctx.scan_del = '\0';
+ ctx.scan_buf[0] = '\0';
+ ctx.scan_ptr = ctx.scan_buf;
+ ctx.lookup_fn = lookup_fn ? lookup_fn : ap_run_expr_lookup;
+
+ ap_expr_yylex_init(&ctx.scanner);
+ ap_expr_yyset_extra(&ctx, ctx.scanner);
+ rc = ap_expr_yyparse(&ctx);
+ ap_expr_yylex_destroy(ctx.scanner);
+ if (ctx.error) {
+ if (ctx.error2)
+ return apr_psprintf(pool, "%s: %s", ctx.error, ctx.error2);
+ else
+ return ctx.error;
+ }
+ else if (ctx.error2) {
+ return ctx.error2;
+ }
+
+ if (rc) /* XXX can this happen? */
+ return "syntax error";
+
+ /* XXX Make this properly depend on the loglevel, which requires
+ * XXX having a server_rec
+ */
+ /*
+ if (ctx.expr)
+ expr_dump_tree(ctx.expr, NULL, APLOG_NOTICE, 2);
+ */
+
+ info->root_node = ctx.expr;
+
+ return NULL;
+}
+
+AP_DECLARE(ap_expr_info_t*) ap_expr_parse_cmd(const cmd_parms *cmd,
+ const char *expr,
+ const char **err,
+ ap_expr_lookup_fn *lookup_fn)
+{
+ ap_expr_info_t *info = apr_pcalloc(cmd->pool, sizeof(ap_expr_info_t));
+ info->filename = cmd->directive->filename;
+ info->line_number = cmd->directive->line_num;
+ *err = ap_expr_parse(cmd->pool, cmd->temp_pool, info, expr, lookup_fn);
+
+ if (*err)
+ return NULL;
+
+ return info;
+}
+
+ap_expr *ap_expr_make(ap_expr_node_op op, const void *a1, const void *a2,
+ ap_expr_parse_ctx *ctx)
+{
+ ap_expr *node = apr_palloc(ctx->pool, sizeof(ap_expr));
+ node->node_op = op;
+ node->node_arg1 = a1;
+ node->node_arg2 = a2;
+ return node;
+}
+
+
+static ap_expr *ap_expr_info_make(int type, const char *name, ap_expr_parse_ctx *ctx)
+{
+ ap_expr *info = apr_palloc(ctx->pool, sizeof(ap_expr));
+ ap_expr_lookup_parms parms;
+ parms.type = type;
+ parms.flags = 0;
+ parms.pool = ctx->pool;
+ parms.ptemp = ctx->ptemp;
+ parms.name = name;
+ parms.func = &info->node_arg1;
+ parms.data = &info->node_arg2;
+ parms.err = &ctx->error2;
+ if (ctx->lookup_fn(&parms) != OK)
+ return NULL;
+ return info;
+}
+
+ap_expr *ap_expr_str_func_make(const char *name, const ap_expr *arg,
+ ap_expr_parse_ctx *ctx)
+{
+ ap_expr *info = ap_expr_info_make(AP_EXPR_FUNC_STRING, name, ctx);
+ if (!info)
+ return NULL;
+
+ info->node_op = op_StringFuncInfo;
+ return ap_expr_make(op_StringFuncCall, info, arg, ctx);
+}
+
+ap_expr *ap_expr_list_func_make(const char *name, const ap_expr *arg,
+ ap_expr_parse_ctx *ctx)
+{
+ ap_expr *info = ap_expr_info_make(AP_EXPR_FUNC_LIST, name, ctx);
+ if (!info)
+ return NULL;
+
+ info->node_op = op_ListFuncInfo;
+ return ap_expr_make(op_ListFuncCall, info, arg, ctx);
+}
+
+ap_expr *ap_expr_unary_op_make(const char *name, const ap_expr *arg,
+ ap_expr_parse_ctx *ctx)
+{
+ ap_expr *info = ap_expr_info_make(AP_EXPR_FUNC_OP_UNARY, name, ctx);
+ if (!info)
+ return NULL;
+
+ info->node_op = op_UnaryOpInfo;
+ return ap_expr_make(op_UnaryOpCall, info, arg, ctx);
+}
+
+ap_expr *ap_expr_binary_op_make(const char *name, const ap_expr *arg1,
+ const ap_expr *arg2, ap_expr_parse_ctx *ctx)
+{
+ ap_expr *args;
+ ap_expr *info = ap_expr_info_make(AP_EXPR_FUNC_OP_UNARY, name, ctx);
+ if (!info)
+ return NULL;
+
+ info->node_op = op_BinaryOpInfo;
+ args = ap_expr_make(op_BinaryOpArgs, arg1, arg2, ctx);
+ return ap_expr_make(op_BinaryOpCall, info, args, ctx);
+}
+
+
+ap_expr *ap_expr_var_make(const char *name, ap_expr_parse_ctx *ctx)
+{
+ ap_expr *node = ap_expr_info_make(AP_EXPR_FUNC_VAR, name, ctx);
+ if (!node)
+ return NULL;
+
+ node->node_op = op_Var;
+ return node;
+}
+
+
+#define MARK APLOG_MARK,loglevel,0,s
+#define DUMP_E_E(op, e1, e2) \
+ do { ap_log_error(MARK,"%*s%s: %pp %pp", indent, " ", op, e1, e2); \
+ if (e1) expr_dump_tree(e1, s, loglevel, indent + 2); \
+ if (e2) expr_dump_tree(e2, s, loglevel, indent + 2); \
+ } while (0)
+#define DUMP_S_E(op, s1, e1) \
+ do { ap_log_error(MARK,"%*s%s: '%s' %pp", indent, " ", op, (char *)s1, e1); \
+ if (e1) expr_dump_tree(e1, s, loglevel, indent + 2); \
+ } while (0)
+#define DUMP_S_P(op, s1, p1) \
+ ap_log_error(MARK,"%*s%s: '%s' %pp", indent, " ", op, (char *)s1, p1);
+#define DUMP_P_P(op, p1, p2) \
+ ap_log_error(MARK,"%*s%s: %pp %pp", indent, " ", op, p1, p2);
+#define DUMP_S_S(op, s1, s2) \
+ 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_S(op, s1) \
+ ap_log_error(MARK,"%*s%s: '%s'", indent, " ", op, (char *)s1)
+
+#define CASE_OP(op) case op: name = #op ; break;
+
+static void expr_dump_tree(const ap_expr *e, const server_rec *s, int loglevel, int indent)
+{
+ switch (e->node_op) {
+ /* no arg */
+ case op_NOP:
+ case op_True:
+ case op_False:
+ {
+ char *name;
+ switch (e->node_op) {
+ CASE_OP(op_NOP);
+ CASE_OP(op_True);
+ CASE_OP(op_False);
+ default:
+ ap_assert(0);
+ }
+ ap_log_error(MARK, "%*s%s", indent, " ", name);
+ }
+ break;
+
+ /* arg1: string, arg2: expr */
+ case op_UnaryOpCall:
+ case op_BinaryOpCall:
+ case op_BinaryOpArgs:
+ {
+ char *name;
+ switch (e->node_op) {
+ CASE_OP(op_BinaryOpCall);
+ CASE_OP(op_UnaryOpCall);
+ CASE_OP(op_BinaryOpArgs);
+ default:
+ ap_assert(0);
+ }
+ DUMP_S_E(name, e->node_arg1, e->node_arg2);
+ }
+ break;
+
+ /* arg1: expr, arg2: expr */
+ case op_Comp:
+ case op_Not:
+ case op_Or:
+ case op_And:
+ case op_EQ:
+ case op_NE:
+ case op_LT:
+ case op_LE:
+ case op_GT:
+ case op_GE:
+ case op_STR_EQ:
+ case op_STR_NE:
+ case op_STR_LT:
+ case op_STR_LE:
+ case op_STR_GT:
+ case op_STR_GE:
+ case op_IN:
+ case op_REG:
+ case op_NRE:
+ case op_Concat:
+ case op_StringFuncCall:
+ case op_ListFuncCall:
+ case op_ListElement:
+ {
+ char *name;
+ switch (e->node_op) {
+ CASE_OP(op_Comp);
+ CASE_OP(op_Not);
+ CASE_OP(op_Or);
+ CASE_OP(op_And);
+ CASE_OP(op_EQ);
+ CASE_OP(op_NE);
+ CASE_OP(op_LT);
+ CASE_OP(op_LE);
+ CASE_OP(op_GT);
+ CASE_OP(op_GE);
+ CASE_OP(op_STR_EQ);
+ CASE_OP(op_STR_NE);
+ CASE_OP(op_STR_LT);
+ CASE_OP(op_STR_LE);
+ CASE_OP(op_STR_GT);
+ CASE_OP(op_STR_GE);
+ CASE_OP(op_IN);
+ CASE_OP(op_REG);
+ CASE_OP(op_NRE);
+ CASE_OP(op_Concat);
+ CASE_OP(op_StringFuncCall);
+ CASE_OP(op_ListFuncCall);
+ CASE_OP(op_ListElement);
+ default:
+ ap_assert(0);
+ }
+ DUMP_E_E(name, e->node_arg1, e->node_arg2);
+ }
+ break;
+ /* arg1: string */
+ case op_Digit:
+ case op_String:
+ {
+ char *name;
+ switch (e->node_op) {
+ CASE_OP(op_Digit);
+ CASE_OP(op_String);
+ default:
+ ap_assert(0);
+ }
+ DUMP_S(name, e->node_arg1);
+ }
+ break;
+ /* arg1: pointer, arg2: pointer */
+ case op_Var:
+ case op_StringFuncInfo:
+ case op_UnaryOpInfo:
+ case op_BinaryOpInfo:
+ case op_ListFuncInfo:
+ {
+ char *name;
+ switch (e->node_op) {
+ CASE_OP(op_Var);
+ CASE_OP(op_StringFuncInfo);
+ CASE_OP(op_UnaryOpInfo);
+ CASE_OP(op_BinaryOpInfo);
+ CASE_OP(op_ListFuncInfo);
+ default:
+ ap_assert(0);
+ }
+ DUMP_P_P(name, e->node_arg1, e->node_arg2);
+ }
+ break;
+ /* arg1: pointer */
+ case op_Regex:
+ DUMP_P("op_Regex", e->node_arg1);
+ break;
+ default:
+ ap_log_error(MARK, "%*sERROR: INVALID OP %d", indent, " ", e->node_op);
+ break;
+ }
+}
+static int ap_expr_eval_unary_op(ap_expr_eval_ctx *ctx, const ap_expr *info,
+ const ap_expr *arg)
+{
+ const ap_expr_op_unary_t *op_func = info->node_arg1;
+ const void *data = info->node_arg2;
+
+ AP_DEBUG_ASSERT(info->node_op == op_UnaryOpInfo);
+ AP_DEBUG_ASSERT(op_func != NULL);
+ AP_DEBUG_ASSERT(data != NULL);
+ return (*op_func)(ctx, data, ap_expr_eval_word(ctx, arg));
+}
+
+static int ap_expr_eval_binary_op(ap_expr_eval_ctx *ctx, const ap_expr *info,
+ const ap_expr *args)
+{
+ const ap_expr_op_binary_t *op_func = info->node_arg1;
+ const void *data = info->node_arg2;
+ const ap_expr *a1 = args->node_arg1;
+ const ap_expr *a2 = args->node_arg2;
+
+ AP_DEBUG_ASSERT(info->node_op == op_BinaryOpInfo);
+ AP_DEBUG_ASSERT(args->node_op == op_BinaryOpArgs);
+ AP_DEBUG_ASSERT(op_func != NULL);
+ AP_DEBUG_ASSERT(data != NULL);
+ return (*op_func)(ctx, data, ap_expr_eval_word(ctx, a1),
+ ap_expr_eval_word(ctx, a2));
+}
+
+
+static int ap_expr_eval(ap_expr_eval_ctx *ctx, const ap_expr *node)
+{
+ switch (node->node_op) {
+ case op_True: {
+ return 1;
+ }
+ case op_False: {
+ return 0;
+ }
+ case op_Not: {
+ const ap_expr *e = node->node_arg1;
+ return (!ap_expr_eval(ctx, e));
+ }
+ case op_Or: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (ap_expr_eval(ctx, e1) || ap_expr_eval(ctx, e2));
+ }
+ case op_And: {
+ const ap_expr *e1 = node->node_arg1;
+ const ap_expr *e2 = node->node_arg2;
+ return (ap_expr_eval(ctx, e1) && ap_expr_eval(ctx, e2));
+ }
+ case op_UnaryOpCall: {
+ const ap_expr *info = node->node_arg1;
+ const ap_expr *args = node->node_arg2;
+ return ap_expr_eval_unary_op(ctx, info, args);
+ }
+ case op_BinaryOpCall: {
+ const ap_expr *info = node->node_arg1;
+ const ap_expr *args = node->node_arg2;
+ return ap_expr_eval_binary_op(ctx, info, args);
+ }
+ case op_Comp: {
+ const ap_expr *e = node->node_arg1;
+ if (ctx->info->flags & AP_EXPR_FLAGS_SSL_EXPR_COMPAT)
+ return ssl_expr_eval_comp(ctx, e);
+ else
+ return ap_expr_eval_comp(ctx, e);
+ }
+ default: {
+ *ctx->err = "Internal evaluation error: Unknown expression node";
+ return FALSE;
+ }
+ }
+}
+
+
+AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *info, const char **err)
+{
+ ap_expr_eval_ctx ctx;
+ int rc;
+ ctx.r = r;
+ ctx.c = r->connection;
+ ctx.s = r->server;
+ ctx.p = r->pool;
+ ctx.err = err;
+ ctx.info = info;
+
+ *err = NULL;
+ rc = ap_expr_eval(&ctx, info->root_node);
+ if (*err != NULL)
+ return (-1);
+ else
+ return (rc ? 1 : 0);
+}
+
+static const char *req_func(ap_expr_eval_ctx *ctx, const char *name,
+ const char *arg)
+{
+ if (ctx->r)
+ return apr_table_get(ctx->r->headers_in, arg);
+ else
+ return "";
+}
+
+static const char *resp_func(ap_expr_eval_ctx *ctx, const char *name,
+ const char *arg)
+{
+ if (ctx->r)
+ return apr_table_get(ctx->r->headers_out, arg);
+ else
+ return "";
+}
+
+static const char *env_func(ap_expr_eval_ctx *ctx, const char *name,
+ const char *arg)
+{
+ if (ctx->r)
+ return apr_table_get(ctx->r->subprocess_env, arg);
+ else
+ return "";
+}
+
+static const char *osenv_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg)
+{
+ return getenv(arg);
+}
+
+static const char *tolower_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg)
+{
+ char *result = apr_pstrdup(ctx->p, arg);
+ ap_str_tolower(result);
+ return result;
+}
+
+static const char *toupper_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg)
+{
+ char *p;
+ char *result = apr_pstrdup(ctx->p, arg);
+
+ for (p = result; *p; ++p) {
+ *p = apr_toupper(*p);
+ }
+
+ return result;
+}
+
+static const char *escape_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg)
+{
+ return ap_escape_uri(ctx->p, arg);
+}
+
+static const char *unescape_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg)
+{
+ char *result = apr_pstrdup(ctx->p, arg);
+ if (ap_unescape_url(result))
+ return "";
+ else
+ return result;
+
+}
+
+static const char *request_var_names[] = {
+ "REQUEST_METHOD", /* 0 */
+ "REQUEST_SCHEME", /* 1 */
+ "REQUEST_URI", /* 2 */
+ "REQUEST_FILENAME", /* 3 */
+ "REMOTE_HOST", /* 4 */
+ "REMOTE_IDENT", /* 5 */
+ "REMOTE_USER", /* 6 */
+ "SERVER_ADMIN", /* 7 */
+ "SERVER_NAME", /* 8 */
+ "SERVER_PORT", /* 9 */
+ "SERVER_PROTOCOL", /* 10 */
+ "SCRIPT_FILENAME", /* 11 */
+ "PATH_INFO", /* 12 */
+ "QUERY_STRING", /* 13 */
+ "IS_SUBREQ", /* 14 */
+ "DOCUMENT_ROOT", /* 15 */
+ "AUTH_TYPE", /* 16 */
+ "THE_REQUEST", /* 17 */
+ "REMOTE_ADDR", /* 18 */
+ "CONTENT_TYPE", /* 19 */
+ NULL
+};
+
+static const char *request_var_fn(ap_expr_eval_ctx *ctx, const void *data)
+{
+ int index = ((const char **)data - request_var_names);
+ request_rec *r = ctx->r;
+ if (!r)
+ return "";
+
+ switch (index) {
+ case 0:
+ return r->method;
+ case 1:
+ return ap_http_scheme(r);
+ case 2:
+ return r->uri;
+ case 3:
+ return r->filename;
+ case 4:
+ return ap_get_remote_host(r->connection, r->per_dir_config,
+ REMOTE_NAME, NULL);
+ case 5:
+ return ap_get_remote_logname(r);
+ case 6:
+ return r->user;
+ case 7:
+ return r->server->server_admin;
+ case 8:
+ return ap_get_server_name(r);
+ case 9:
+ return apr_psprintf(ctx->p, "%u", ap_get_server_port(r));
+ case 10:
+ return r->protocol;
+ case 11:
+ return r->filename;
+ case 12:
+ return r->path_info;
+ case 13:
+ return r->args;
+ case 14:
+ return (r->main != NULL ? "true" : "false");
+ case 15:
+ return ap_document_root(r);
+ case 16:
+ return r->ap_auth_type;
+ case 17:
+ return r->the_request;
+ case 18:
+ return ctx->c->remote_ip;
+ case 19:
+ return r->content_type;
+ default:
+ ap_assert(0);
+ return NULL;
+ }
+}
+
+static const char *req_header_var_names[] = {
+ "HTTP_USER_AGENT", /* 0 */
+ "HTTP_PROXY_CONNECTION", /* 1 */
+ "HTTP_REFERER",
+ "HTTP_COOKIE",
+ "HTTP_FORWARDED",
+ "HTTP_HOST",
+ "HTTP_ACCEPT",
+ NULL
+};
+
+static const char *req_header_var_fn(ap_expr_eval_ctx *ctx, const void *data)
+{
+ const char **name = (const char **)data;
+ int index = (name - req_header_var_names);
+ if (!ctx->r)
+ return "";
+
+ switch (index) {
+ case 0:
+ return apr_table_get(ctx->r->headers_in, "User-Agent");
+ case 1:
+ return apr_table_get(ctx->r->headers_in, "Proxy-Connection");
+ default:
+ /* apr_table_get is case insensitive, just skip leading "HTTP_" */
+ return apr_table_get(ctx->r->headers_in, *name + 5);
+ }
+}
+
+static const char *misc_var_names[] = {
+ "TIME_YEAR", /* 0 */
+ "TIME_MON", /* 1 */
+ "TIME_DAY", /* 2 */
+ "TIME_HOUR", /* 3 */
+ "TIME_MIN", /* 4 */
+ "TIME_SEC", /* 5 */
+ "TIME_WDAY", /* 6 */
+ "TIME", /* 7 */
+ "SERVER_SOFTWARE", /* 8 */
+ "API_VERSION", /* 9 */
+ NULL
+};
+
+static const char *misc_var_fn(ap_expr_eval_ctx *ctx, const void *data)
+{
+ apr_time_exp_t tm;
+ apr_time_exp_lt(&tm, apr_time_now());
+ int index = ((const char **)data - misc_var_names);
+
+ switch (index) {
+ case 0:
+ return apr_psprintf(ctx->p, "%02d%02d", (tm.tm_year / 100) + 19,
+ tm.tm_year % 100);
+ case 1:
+ return apr_psprintf(ctx->p, "%02d", tm.tm_mon+1);
+ case 2:
+ return apr_psprintf(ctx->p, "%02d", tm.tm_mday);
+ case 3:
+ return apr_psprintf(ctx->p, "%02d", tm.tm_hour);
+ case 4:
+ return apr_psprintf(ctx->p, "%02d", tm.tm_min);
+ case 5:
+ return apr_psprintf(ctx->p, "%02d", tm.tm_sec);
+ case 6:
+ return apr_psprintf(ctx->p, "%d", tm.tm_wday);
+ case 7:
+ return apr_psprintf(ctx->p, "%02d%02d%02d%02d%02d%02d%02d",
+ (tm.tm_year / 100) + 19, (tm.tm_year % 100),
+ tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min,
+ tm.tm_sec);
+ case 8:
+ return ap_get_server_banner();
+ case 9:
+ return apr_itoa(ctx->p, MODULE_MAGIC_NUMBER);
+ default:
+ ap_assert(0);
+ }
+
+ return NULL;
+}
+
+struct expr_provider_single {
+ const void *func;
+ const char *name;
+};
+struct expr_provider_multi {
+ const void *func;
+ const char **names;
+};
+
+static const struct expr_provider_multi var_providers[] = {
+ { misc_var_fn, misc_var_names },
+ { req_header_var_fn, req_header_var_names },
+ { request_var_fn, request_var_names },
+ { NULL, NULL }
+};
+
+static const struct expr_provider_single string_func_providers[] = {
+ { osenv_func, "osenv" },
+ { env_func, "env" },
+ { resp_func, "resp" },
+ { req_func, "req" },
+ /* 'http' as alias for 'req' for compatibility with ssl_expr */
+ { req_func, "http" },
+ { tolower_func, "tolower" },
+ { toupper_func, "toupper" },
+ { escape_func, "escape" },
+ { unescape_func, "unescape" },
+ { NULL, NULL}
+};
+/* XXX: base64 encode/decode ? */
+
+static int core_expr_lookup(ap_expr_lookup_parms *parms)
+{
+ switch (parms->type) {
+ case AP_EXPR_FUNC_VAR: {
+ const struct expr_provider_multi *prov = var_providers;
+ while (prov->func) {
+ const char **name = prov->names;
+ while (*name) {
+ if (strcasecmp(*name, parms->name) == 0) {
+ *parms->func = prov->func;
+ *parms->data = name;
+ return OK;
+ }
+ name++;
+ }
+ prov++;
+ }
+ break;
+ }
+ case AP_EXPR_FUNC_STRING: {
+ const struct expr_provider_single *prov = string_func_providers;
+ while (prov->func) {
+ if (strcasecmp(prov->name, parms->name) == 0) {
+ *parms->func = prov->func;
+ *parms->data = prov->name;
+ return OK;
+ }
+ prov++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return DECLINED;
+}
+
+static int expr_lookup_not_found(ap_expr_lookup_parms *parms)
+{
+ const char *type;
+
+ switch (parms->type) {
+ case AP_EXPR_FUNC_VAR:
+ type = "Variable";
+ break;
+ case AP_EXPR_FUNC_STRING:
+ type = "Function";
+ break;
+ case AP_EXPR_FUNC_LIST:
+ type = "List-returning function";
+ break;
+ case AP_EXPR_FUNC_OP_UNARY:
+ type = "Unary operator";
+ break;
+ case AP_EXPR_FUNC_OP_BINARY:
+ type = "Binary operator";
+ break;
+ default:
+ *parms->err = "Inavalid expression type in expr_lookup";
+ return !OK;
+ }
+ *parms->err = apr_psprintf(parms->ptemp, "%s '%s' does not exist", type,
+ parms->name);
+ return !OK;
+}
+
+void ap_expr_init(apr_pool_t *p)
+{
+ ap_hook_expr_lookup(core_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_expr_lookup(expr_lookup_not_found, NULL, NULL, APR_HOOK_REALLY_LAST);
+}
+
#define YYLSP_NEEDED 0
/* Substitute the variable and function names. */
-#define yyparse ssl_expr_yyparse
-#define yylex ssl_expr_yylex
-#define yyerror ssl_expr_yyerror
-#define yylval ssl_expr_yylval
-#define yychar ssl_expr_yychar
-#define yydebug ssl_expr_yydebug
-#define yynerrs ssl_expr_yynerrs
+#define yyparse ap_expr_yyparse
+#define yylex ap_expr_yylex
+#define yyerror ap_expr_yyerror
+#define yylval ap_expr_yylval
+#define yychar ap_expr_yychar
+#define yydebug ap_expr_yydebug
+#define yynerrs ap_expr_yynerrs
/* Copy the first part of user declarations. */
/* Line 189 of yacc.c */
-#line 41 "ssl_expr_parse.y"
+#line 31 "util_expr_parse.y"
-#include "ssl_private.h"
+#include "util_expr_private.h"
/* Line 189 of yacc.c */
-#line 86 "ssl_expr_parse.c"
+#line 86 "util_expr_parse.c"
/* Enabling traces. */
#ifndef YYDEBUG
enum yytokentype {
T_TRUE = 258,
T_FALSE = 259,
- T_DIGIT = 260,
- T_ID = 261,
- T_STRING = 262,
- T_REGEX = 263,
- T_REGEX_I = 264,
- T_FUNC_FILE = 265,
- T_OP_EQ = 266,
- T_OP_NE = 267,
- T_OP_LT = 268,
- T_OP_LE = 269,
- T_OP_GT = 270,
- T_OP_GE = 271,
- T_OP_REG = 272,
- T_OP_NRE = 273,
- T_OP_IN = 274,
- T_OP_PEEREXTLIST = 275,
- T_OP_OR = 276,
- T_OP_AND = 277,
- T_OP_NOT = 278
+ ERROR = 260,
+ T_DIGIT = 261,
+ T_ID = 262,
+ 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
};
#endif
{
/* Line 214 of yacc.c */
-#line 45 "ssl_expr_parse.y"
+#line 35 "util_expr_parse.y"
- char *cpVal;
- ssl_expr *exVal;
+ char *cpVal;
+ ap_expr *exVal;
/* Line 214 of yacc.c */
-#line 152 "ssl_expr_parse.c"
+#line 164 "util_expr_parse.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
/* Copy the second part of user declarations. */
/* Line 264 of yacc.c */
-#line 88 "ssl_expr_parse.y"
+#line 96 "util_expr_parse.y"
-#include "ssl_expr.h"
-#define yyscanner context->scanner
+#include "util_expr_private.h"
+#define yyscanner ctx->scanner
-int ssl_expr_yyerror(ssl_expr_info_type *context, char *err);
-int ssl_expr_yylex(YYSTYPE *lvalp, void *scanner);
+int ap_expr_yylex(YYSTYPE *lvalp, void *scanner);
/* Line 264 of yacc.c */
-#line 173 "ssl_expr_parse.c"
+#line 184 "util_expr_parse.c"
#ifdef short
# undef short
#endif
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 18
+#define YYFINAL 27
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 56
+#define YYLAST 117
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 30
+#define YYNTOKENS 42
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 9
+#define YYNNTS 13
/* YYNRULES -- Number of rules. */
-#define YYNRULES 29
+#define YYNRULES 47
/* YYNRULES -- Number of states. */
-#define YYNSTATES 58
+#define YYNSTATES 88
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 278
+#define YYMAXUTOK 290
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
0, 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, 29, 2, 2,
- 24, 25, 2, 2, 28, 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,
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, 26, 2, 27, 2, 2, 2, 2,
+ 2, 2, 2, 38, 2, 39, 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, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35
};
#if YYDEBUG
YYRHS. */
static const yytype_uint8 yyprhs[] =
{
- 0, 0, 3, 5, 7, 9, 12, 16, 20, 22,
- 26, 30, 34, 38, 42, 46, 50, 54, 58, 62,
- 67, 71, 73, 77, 79, 81, 86, 88, 90, 92
+ 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
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 31, 0, -1, 32, -1, 3, -1, 4, -1, 23,
- 32, -1, 32, 21, 32, -1, 32, 22, 32, -1,
- 33, -1, 24, 32, 25, -1, 36, 11, 36, -1,
- 36, 12, 36, -1, 36, 13, 36, -1, 36, 14,
- 36, -1, 36, 15, 36, -1, 36, 16, 36, -1,
- 36, 19, 34, -1, 36, 17, 37, -1, 36, 18,
- 37, -1, 20, 24, 36, 25, -1, 26, 35, 27,
- -1, 36, -1, 35, 28, 36, -1, 5, -1, 7,
- -1, 29, 26, 6, 27, -1, 38, -1, 8, -1,
- 9, -1, 10, 24, 7, 25, -1
+ 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
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 99, 99, 102, 103, 104, 105, 106, 107, 108,
- 111, 112, 113, 114, 115, 116, 117, 118, 119, 122,
- 123, 126, 127, 130, 131, 132, 133, 136, 145, 156
+ 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
};
#endif
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "T_TRUE", "T_FALSE", "T_DIGIT", "T_ID",
- "T_STRING", "T_REGEX", "T_REGEX_I", "T_FUNC_FILE", "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_PEEREXTLIST", "T_OP_OR", "T_OP_AND", "T_OP_NOT", "'('",
- "')'", "'{'", "'}'", "','", "'%'", "$accept", "root", "expr",
- "comparison", "wordlist", "words", "word", "regex", "funccall", 0
+ "$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
};
#endif
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278, 40, 41, 123, 125, 44, 37
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 40, 41, 123, 125,
+ 44, 58
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 30, 31, 32, 32, 32, 32, 32, 32, 32,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 34,
- 34, 35, 35, 36, 36, 36, 36, 37, 37, 38
+ 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
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
- 0, 2, 1, 1, 1, 2, 3, 3, 1, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 4,
- 3, 1, 3, 1, 1, 4, 1, 1, 1, 4
+ 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
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 0, 3, 4, 23, 24, 0, 0, 0, 0, 0,
- 2, 8, 0, 26, 0, 5, 0, 0, 1, 0,
+ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 9, 0, 6, 7, 10, 11, 12, 13, 14,
- 15, 27, 28, 17, 18, 0, 0, 16, 29, 25,
- 0, 0, 21, 0, 20, 0, 19, 22
+ 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
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 9, 10, 11, 47, 51, 12, 43, 13
+ -1, 11, 12, 13, 68, 80, 21, 22, 14, 15,
+ 64, 69, 16
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -22
+#define YYPACT_NINF -29
static const yytype_int8 yypact[] =
{
- 3, -22, -22, -22, -22, -12, 3, 3, -10, 22,
- 23, -22, 24, -22, 17, -22, -2, 44, -22, 3,
- 3, 4, 4, 4, 4, 4, 4, 38, 38, -5,
- 26, -22, 1, 30, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, -22, -22, 29, 4, -22, -22, -22,
- 4, 21, -22, 31, -22, 4, -22, -22
+ 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
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -22, -22, 11, -22, -22, -22, -21, 27, -22
+ -29, -29, 13, -29, -29, -29, 24, -20, -4, -6,
+ 39, -29, -29
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
- 35, 36, 37, 38, 39, 40, 1, 2, 3, 3,
- 4, 4, 14, 5, 5, 45, 17, 15, 16, 19,
- 20, 46, 18, 31, 30, 52, 6, 7, 49, 53,
- 33, 34, 8, 8, 57, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 19, 20, 41, 42, 54, 55,
- 32, 48, 20, 50, 0, 44, 56
+ 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
};
static const yytype_int8 yycheck[] =
{
- 21, 22, 23, 24, 25, 26, 3, 4, 5, 5,
- 7, 7, 24, 10, 10, 20, 26, 6, 7, 21,
- 22, 26, 0, 25, 7, 46, 23, 24, 27, 50,
- 19, 20, 29, 29, 55, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 21, 22, 8, 9, 27, 28,
- 6, 25, 22, 24, -1, 28, 25
+ 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
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 3, 4, 5, 7, 10, 23, 24, 29, 31,
- 32, 33, 36, 38, 24, 32, 32, 26, 0, 21,
- 22, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 7, 25, 6, 32, 32, 36, 36, 36, 36, 36,
- 36, 8, 9, 37, 37, 20, 26, 34, 25, 27,
- 24, 35, 36, 36, 27, 28, 25, 36
+ 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
};
#define yyerrok (yyerrstatus = 0)
} \
else \
{ \
- yyerror (context, YY_("syntax error: cannot back up")); \
+ yyerror (ctx, YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (YYID (0))
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
- Type, Value, context); \
+ Type, Value, ctx); \
YYFPRINTF (stderr, "\n"); \
} \
} while (YYID (0))
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, ssl_expr_info_type *context)
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, ap_expr_parse_ctx *ctx)
#else
static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, context)
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx)
FILE *yyoutput;
int yytype;
YYSTYPE const * const yyvaluep;
- ssl_expr_info_type *context;
+ ap_expr_parse_ctx *ctx;
#endif
{
if (!yyvaluep)
return;
- YYUSE (context);
+ YYUSE (ctx);
# ifdef YYPRINT
if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, ssl_expr_info_type *context)
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, ap_expr_parse_ctx *ctx)
#else
static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, context)
+yy_symbol_print (yyoutput, yytype, yyvaluep, ctx)
FILE *yyoutput;
int yytype;
YYSTYPE const * const yyvaluep;
- ssl_expr_info_type *context;
+ ap_expr_parse_ctx *ctx;
#endif
{
if (yytype < YYNTOKENS)
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, context);
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx);
YYFPRINTF (yyoutput, ")");
}
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule, ssl_expr_info_type *context)
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule, ap_expr_parse_ctx *ctx)
#else
static void
-yy_reduce_print (yyvsp, yyrule, context)
+yy_reduce_print (yyvsp, yyrule, ctx)
YYSTYPE *yyvsp;
int yyrule;
- ssl_expr_info_type *context;
+ ap_expr_parse_ctx *ctx;
#endif
{
int yynrhs = yyr2[yyrule];
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
- , context);
+ , ctx);
YYFPRINTF (stderr, "\n");
}
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (yyvsp, Rule, context); \
+ yy_reduce_print (yyvsp, Rule, ctx); \
} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, ssl_expr_info_type *context)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, ap_expr_parse_ctx *ctx)
#else
static void
-yydestruct (yymsg, yytype, yyvaluep, context)
+yydestruct (yymsg, yytype, yyvaluep, ctx)
const char *yymsg;
int yytype;
YYSTYPE *yyvaluep;
- ssl_expr_info_type *context;
+ ap_expr_parse_ctx *ctx;
#endif
{
YYUSE (yyvaluep);
- YYUSE (context);
+ YYUSE (ctx);
if (!yymsg)
yymsg = "Deleting";
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
-int yyparse (ssl_expr_info_type *context);
+int yyparse (ap_expr_parse_ctx *ctx);
#else
int yyparse ();
#endif
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
int
-yyparse (ssl_expr_info_type *context)
+yyparse (ap_expr_parse_ctx *ctx)
#else
int
-yyparse (context)
- ssl_expr_info_type *context;
+yyparse (ctx)
+ ap_expr_parse_ctx *ctx;
#endif
#endif
{
case 2:
/* Line 1455 of yacc.c */
-#line 99 "ssl_expr_parse.y"
- { context->expr = (yyvsp[(1) - (1)].exVal); ;}
+#line 106 "util_expr_parse.y"
+ { ctx->expr = (yyvsp[(1) - (1)].exVal); ;}
break;
case 3:
/* Line 1455 of yacc.c */
-#line 102 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_True, NULL, NULL, context); ;}
+#line 107 "util_expr_parse.y"
+ { YYABORT; ;}
break;
case 4:
/* Line 1455 of yacc.c */
-#line 103 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_False, NULL, NULL, context); ;}
+#line 110 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_True, NULL, NULL, ctx); ;}
break;
case 5:
/* Line 1455 of yacc.c */
-#line 104 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_Not, (yyvsp[(2) - (2)].exVal), NULL, context); ;}
+#line 111 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_False, NULL, NULL, ctx); ;}
break;
case 6:
/* Line 1455 of yacc.c */
-#line 105 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_Or, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 112 "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 106 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_And, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 113 "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 107 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_Comp, (yyvsp[(1) - (1)].exVal), NULL, context); ;}
+#line 114 "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 108 "ssl_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;}
+#line 115 "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 111 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_EQ, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 116 "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 112 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_NE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 117 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;}
break;
case 12:
/* Line 1455 of yacc.c */
-#line 113 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_LT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 120 "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 114 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_LE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 121 "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 115 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_GT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 122 "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 116 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_GE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 123 "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 117 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_IN, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 124 "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 118 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_REG, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 125 "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 119 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_NRE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), context); ;}
+#line 126 "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 122 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_PeerExtElement, (yyvsp[(3) - (4)].exVal), NULL, context); ;}
+#line 127 "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 123 "ssl_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(2) - (3)].exVal) ; ;}
+#line 128 "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 126 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_ListElement, (yyvsp[(1) - (1)].exVal), NULL, context); ;}
+#line 129 "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 127 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_ListElement, (yyvsp[(3) - (3)].exVal), (yyvsp[(1) - (3)].exVal), context); ;}
+#line 130 "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 130 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_Digit, (yyvsp[(1) - (1)].cpVal), NULL, context); ;}
+#line 131 "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 131 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_String, (yyvsp[(1) - (1)].cpVal), NULL, context); ;}
+#line 132 "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 132 "ssl_expr_parse.y"
- { (yyval.exVal) = ssl_expr_make(op_Var, (yyvsp[(3) - (4)].cpVal), NULL, context); ;}
+#line 133 "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 133 "ssl_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
+#line 134 "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 136 "ssl_expr_parse.y"
- {
+#line 135 "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"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
+ break;
+
+ case 29:
+
+/* Line 1455 of yacc.c */
+#line 139 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;}
+ break;
+
+ case 30:
+
+/* Line 1455 of yacc.c */
+#line 142 "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"
+ { (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"
+ { (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"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
+ break;
+
+ case 34:
+
+/* Line 1455 of yacc.c */
+#line 151 "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"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
+ break;
+
+ case 36:
+
+/* Line 1455 of yacc.c */
+#line 155 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_var_make((yyvsp[(2) - (3)].cpVal), ctx); ;}
+ 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); ;}
+ 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); ;}
+ 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); ;}
+ break;
+
+ case 40:
+
+/* Line 1455 of yacc.c */
+#line 161 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
+ break;
+
+ case 41:
+
+/* Line 1455 of yacc.c */
+#line 162 "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); ;}
+ break;
+
+ case 43:
+
+/* Line 1455 of yacc.c */
+#line 164 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_String, "", NULL, ctx); ;}
+ break;
+
+ case 44:
+
+/* Line 1455 of yacc.c */
+#line 167 "util_expr_parse.y"
+ {
ap_regex_t *regex;
- if ((regex = ap_pregcomp(context->pool, (yyvsp[(1) - (1)].cpVal),
+ if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal),
AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
- context->error = "Failed to compile regular expression";
+ ctx->error = "Failed to compile regular expression";
YYERROR;
}
- (yyval.exVal) = ssl_expr_make(op_Regex, regex, NULL, context);
+ (yyval.exVal) = ap_expr_make(op_Regex, regex, NULL, ctx);
;}
break;
- case 28:
+ case 45:
/* Line 1455 of yacc.c */
-#line 145 "ssl_expr_parse.y"
+#line 176 "util_expr_parse.y"
{
ap_regex_t *regex;
- if ((regex = ap_pregcomp(context->pool, (yyvsp[(1) - (1)].cpVal),
+ if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal),
AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
- context->error = "Failed to compile regular expression";
+ ctx->error = "Failed to compile regular expression";
YYERROR;
}
- (yyval.exVal) = ssl_expr_make(op_Regex, regex, NULL, context);
+ (yyval.exVal) = ap_expr_make(op_Regex, regex, NULL, ctx);
;}
break;
- case 29:
+ case 46:
/* Line 1455 of yacc.c */
-#line 156 "ssl_expr_parse.y"
- {
- ssl_expr *args = ssl_expr_make(op_ListElement, (yyvsp[(3) - (4)].cpVal), NULL, context);
- (yyval.exVal) = ssl_expr_make(op_Func, "file", args, context);
- ;}
+#line 187 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_list_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); ;}
+ break;
+
+ case 47:
+
+/* Line 1455 of yacc.c */
+#line 190 "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 1620 "ssl_expr_parse.c"
+#line 1798 "util_expr_parse.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
{
++yynerrs;
#if ! YYERROR_VERBOSE
- yyerror (context, YY_("syntax error"));
+ yyerror (ctx, YY_("syntax error"));
#else
{
YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
if (0 < yysize && yysize <= yymsg_alloc)
{
(void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (context, yymsg);
+ yyerror (ctx, yymsg);
}
else
{
- yyerror (context, YY_("syntax error"));
+ yyerror (ctx, YY_("syntax error"));
if (yysize != 0)
goto yyexhaustedlab;
}
else
{
yydestruct ("Error: discarding",
- yytoken, &yylval, context);
+ yytoken, &yylval, ctx);
yychar = YYEMPTY;
}
}
yydestruct ("Error: popping",
- yystos[yystate], yyvsp, context);
+ yystos[yystate], yyvsp, ctx);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
yyexhaustedlab:
- yyerror (context, YY_("memory exhausted"));
+ yyerror (ctx, YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
if (yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval, context);
+ yytoken, &yylval, ctx);
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp, context);
+ yystos[*yyssp], yyvsp, ctx);
YYPOPSTACK (1);
}
#ifndef yyoverflow
/* Line 1675 of yacc.c */
-#line 162 "ssl_expr_parse.y"
+#line 193 "util_expr_parse.y"
-int yyerror(ssl_expr_info_type *context, char *s)
+void yyerror(ap_expr_parse_ctx *ctx, char *s)
{
- context->error = s;
- return 2;
+ ctx->error = s;
}
enum yytokentype {
T_TRUE = 258,
T_FALSE = 259,
- T_DIGIT = 260,
- T_ID = 261,
- T_STRING = 262,
- T_REGEX = 263,
- T_REGEX_I = 264,
- T_FUNC_FILE = 265,
- T_OP_EQ = 266,
- T_OP_NE = 267,
- T_OP_LT = 268,
- T_OP_LE = 269,
- T_OP_GT = 270,
- T_OP_GE = 271,
- T_OP_REG = 272,
- T_OP_NRE = 273,
- T_OP_IN = 274,
- T_OP_PEEREXTLIST = 275,
- T_OP_OR = 276,
- T_OP_AND = 277,
- T_OP_NOT = 278
+ ERROR = 260,
+ T_DIGIT = 261,
+ T_ID = 262,
+ 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
};
#endif
{
/* Line 1676 of yacc.c */
-#line 45 "ssl_expr_parse.y"
+#line 35 "util_expr_parse.y"
- char *cpVal;
- ssl_expr *exVal;
+ char *cpVal;
+ ap_expr *exVal;
/* Line 1676 of yacc.c */
-#line 82 "ssl_expr_parse.h"
+#line 94 "util_expr_parse.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
--- /dev/null
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* based on ap_expr_parse.y from mod_ssl */
+
+/* _________________________________________________________________
+**
+** Expression Parser
+** _________________________________________________________________
+*/
+
+%pure-parser
+%error-verbose
+%defines
+%lex-param { void *yyscanner }
+%parse-param { ap_expr_parse_ctx *ctx }
+
+%{
+#include "util_expr_private.h"
+%}
+
+%union {
+ char *cpVal;
+ ap_expr *exVal;
+}
+
+%token T_TRUE
+%token T_FALSE
+
+%token <cpVal> ERROR
+
+%token <cpVal> T_DIGIT
+%token <cpVal> T_ID
+%token <cpVal> T_STRING
+%token <cpVal> T_REGEX
+%token <cpVal> T_REGEX_I
+%token <cpVal> T_OP_UNARY
+%token <cpVal> T_OP_BINARY
+
+%token T_STR_BEGIN
+%token T_STR_END
+%token T_VAR_BEGIN
+%token T_VAR_END
+
+%token T_OP_EQ
+%token T_OP_NE
+%token T_OP_LT
+%token T_OP_LE
+%token T_OP_GT
+%token T_OP_GE
+%token T_OP_REG
+%token T_OP_NRE
+%token T_OP_IN
+%token T_OP_STR_EQ
+%token T_OP_STR_NE
+%token T_OP_STR_LT
+%token T_OP_STR_LE
+%token T_OP_STR_GT
+%token T_OP_STR_GE
+%token T_OP_CONCAT
+
+%token T_OP_OR
+%token T_OP_AND
+%token T_OP_NOT
+
+%left T_OP_OR
+%left T_OP_AND
+%left T_OP_NOT
+%left T_OP_CONCAT
+
+%type <exVal> expr
+%type <exVal> comparison
+%type <exVal> strfunccall
+%type <exVal> lstfunccall
+%type <exVal> regex
+%type <exVal> words
+%type <exVal> wordlist
+%type <exVal> word
+%type <exVal> string
+%type <exVal> strpart
+%type <exVal> var
+
+%{
+#include "util_expr_private.h"
+#define yyscanner ctx->scanner
+
+int ap_expr_yylex(YYSTYPE *lvalp, void *scanner);
+%}
+
+
+%%
+
+root : expr { ctx->expr = $1; }
+ | ERROR { YYABORT; }
+ ;
+
+expr : T_TRUE { $$ = ap_expr_make(op_True, NULL, NULL, ctx); }
+ | T_FALSE { $$ = ap_expr_make(op_False, NULL, NULL, ctx); }
+ | T_OP_NOT expr { $$ = ap_expr_make(op_Not, $2, NULL, ctx); }
+ | expr T_OP_OR expr { $$ = ap_expr_make(op_Or, $1, $3, ctx); }
+ | expr T_OP_AND expr { $$ = ap_expr_make(op_And, $1, $3, ctx); }
+ | comparison { $$ = ap_expr_make(op_Comp, $1, NULL, ctx); }
+ | T_OP_UNARY word { $$ = ap_expr_unary_op_make( $1, $2, ctx); }
+ | '(' expr ')' { $$ = $2; }
+ ;
+
+comparison: word T_OP_EQ word { $$ = ap_expr_make(op_EQ, $1, $3, ctx); }
+ | word T_OP_NE word { $$ = ap_expr_make(op_NE, $1, $3, ctx); }
+ | word T_OP_LT word { $$ = ap_expr_make(op_LT, $1, $3, ctx); }
+ | word T_OP_LE word { $$ = ap_expr_make(op_LE, $1, $3, ctx); }
+ | word T_OP_GT word { $$ = ap_expr_make(op_GT, $1, $3, ctx); }
+ | word T_OP_GE word { $$ = ap_expr_make(op_GE, $1, $3, ctx); }
+ | word T_OP_STR_EQ word { $$ = ap_expr_make(op_STR_EQ, $1, $3, ctx); }
+ | word T_OP_STR_NE word { $$ = ap_expr_make(op_STR_NE, $1, $3, ctx); }
+ | word T_OP_STR_LT word { $$ = ap_expr_make(op_STR_LT, $1, $3, ctx); }
+ | word T_OP_STR_LE word { $$ = ap_expr_make(op_STR_LE, $1, $3, ctx); }
+ | word T_OP_STR_GT word { $$ = ap_expr_make(op_STR_GT, $1, $3, ctx); }
+ | word T_OP_STR_GE word { $$ = ap_expr_make(op_STR_GE, $1, $3, ctx); }
+ | word T_OP_IN wordlist { $$ = ap_expr_make(op_IN, $1, $3, ctx); }
+ | word T_OP_REG regex { $$ = ap_expr_make(op_REG, $1, $3, ctx); }
+ | word T_OP_NRE regex { $$ = ap_expr_make(op_NRE, $1, $3, ctx); }
+ | word T_OP_BINARY word { $$ = ap_expr_binary_op_make($2, $1, $3, ctx); }
+ ;
+
+wordlist : lstfunccall { $$ = $1; }
+ | '{' words '}' { $$ = $2; }
+ ;
+
+words : word { $$ = ap_expr_make(op_ListElement, $1, NULL, ctx); }
+ | words ',' word { $$ = ap_expr_make(op_ListElement, $3, $1, ctx); }
+ ;
+
+string : string strpart { $$ = ap_expr_make(op_Concat, $1, $2, ctx); }
+ | strpart { $$ = $1; }
+ ;
+
+
+strpart : T_STRING { $$ = ap_expr_make(op_String, $1, NULL, ctx); }
+ | var { $$ = $1; }
+ ;
+
+var : T_VAR_BEGIN T_ID T_VAR_END { $$ = ap_expr_var_make($2, ctx); }
+ | T_VAR_BEGIN T_ID ':' string T_VAR_END { $$ = ap_expr_str_func_make($2, $4, ctx); }
+ ;
+
+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; }
+ | strfunccall { $$ = $1; }
+ | T_STR_BEGIN string T_STR_END { $$ = $2; }
+ | T_STR_BEGIN T_STR_END { $$ = ap_expr_make(op_String, "", NULL, ctx); }
+ ;
+
+regex : T_REGEX {
+ ap_regex_t *regex;
+ if ((regex = ap_pregcomp(ctx->pool, $1,
+ AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
+ ctx->error = "Failed to compile regular expression";
+ YYERROR;
+ }
+ $$ = ap_expr_make(op_Regex, regex, NULL, ctx);
+ }
+ | T_REGEX_I {
+ ap_regex_t *regex;
+ if ((regex = ap_pregcomp(ctx->pool, $1,
+ AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
+ ctx->error = "Failed to compile regular expression";
+ YYERROR;
+ }
+ $$ = ap_expr_make(op_Regex, regex, NULL, ctx);
+ }
+ ;
+
+lstfunccall : T_ID '(' word ')' { $$ = ap_expr_list_func_make($1, $3, ctx); }
+ ;
+
+strfunccall : T_ID '(' word ')' { $$ = ap_expr_str_func_make($1, $3, ctx); }
+ ;
+
+%%
+
+void yyerror(ap_expr_parse_ctx *ctx, char *s)
+{
+ ctx->error = s;
+}
+
--- /dev/null
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __AP_EXPR_PRIVATE_H__
+#define __AP_EXPR_PRIVATE_H__
+
+#include "httpd.h"
+#include "apr_strings.h"
+#include "apr_tables.h"
+#include "ap_expr.h"
+
+#ifndef YY_NULL
+#define YY_NULL 0
+#endif
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+
+/** The operations in a parse tree node */
+typedef enum {
+ op_NOP,
+ op_True, op_False,
+ op_Not, op_Or, op_And,
+ op_Comp,
+ op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE, op_IN,
+ 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_Var,
+ op_ListElement,
+ /*
+ * call external functions/operators.
+ * The info node contains the function pointer and some function specific
+ * info.
+ * For Binary operators, the Call node links to the Info node and the
+ * Args node, which in turn links to the left and right operand.
+ * For all other variants, the Call node links to the Info node and the
+ * argument.
+ */
+ op_UnaryOpCall, op_UnaryOpInfo,
+ op_BinaryOpCall, op_BinaryOpInfo, op_BinaryOpArgs,
+ op_StringFuncCall, op_StringFuncInfo,
+ op_ListFuncCall, op_ListFuncInfo
+} ap_expr_node_op;
+
+/** The basic parse tree node */
+struct ap_expr_node {
+ ap_expr_node_op node_op;
+ const void *node_arg1;
+ const void *node_arg2;
+};
+
+/** The context used by scanner and parser */
+typedef struct {
+ /* internal state of the scanner */
+ const char *inputbuf;
+ int inputlen;
+ const char *inputptr;
+ void *scanner;
+ char *scan_ptr;
+ char scan_buf[MAX_STRING_LEN];
+ char scan_del;
+
+ /* pools for result and temporary usage */
+ apr_pool_t *pool;
+ apr_pool_t *ptemp;
+
+ /* The created parse tree */
+ ap_expr *expr;
+
+ const char *error;
+ const char *error2;
+ unsigned flags;
+
+ /*
+ * The function to use to lookup provider functions for variables
+ * and funtctions
+ */
+ ap_expr_lookup_fn *lookup_fn;
+} ap_expr_parse_ctx;
+
+/* flex/bison functions */
+int ap_expr_yyparse(ap_expr_parse_ctx *context);
+void ap_expr_yyerror(ap_expr_parse_ctx *context, char *err);
+int ap_expr_yylex_init(void **scanner);
+int ap_expr_yylex_destroy(void *scanner);
+void ap_expr_yyset_extra(ap_expr_parse_ctx *context, void *scanner);
+
+/* create a parse tree node */
+ap_expr *ap_expr_make(ap_expr_node_op op, const void *arg1, const void *arg2,
+ ap_expr_parse_ctx *ctx);
+/* create parse tree node for the string-returning function 'name' */
+ap_expr *ap_expr_str_func_make(const char *name, const ap_expr *arg,
+ ap_expr_parse_ctx *ctx);
+/* create parse tree node for the list-returning function 'name' */
+ap_expr *ap_expr_list_func_make(const char *name, const ap_expr *arg,
+ ap_expr_parse_ctx *ctx);
+/* create parse tree node for the variable 'name' */
+ap_expr *ap_expr_var_make(const char *name, ap_expr_parse_ctx *ctx);
+/* create parse tree node for the unary operator 'name' */
+ap_expr *ap_expr_unary_op_make(const char *name, const ap_expr *arg,
+ ap_expr_parse_ctx *ctx);
+/* create parse tree node for the binary operator 'name' */
+ap_expr *ap_expr_binary_op_make(const char *name, const ap_expr *arg1,
+ const ap_expr *arg2, ap_expr_parse_ctx *ctx);
+
+
+#endif /* __AP_EXPR_PRIVATE_H__ */
+/** @} */
+
-#line 2 "ssl_expr_scan.c"
+#line 2 "util_expr_scan.c"
-#line 4 "ssl_expr_scan.c"
+#line 4 "util_expr_scan.c"
#define YY_INT_ALIGNED short int
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE ssl_expr_yyrestart(yyin ,yyscanner )
+#define YY_NEW_FILE ap_expr_yyrestart(yyin ,yyscanner )
#define YY_END_OF_BUFFER_CHAR 0
* possible backing-up.
*
* When we actually see the EOF, we change the status to "new"
- * (via ssl_expr_yyrestart()), so that the user can continue scanning by
+ * (via ap_expr_yyrestart()), so that the user can continue scanning by
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
*/
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-void ssl_expr_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void ssl_expr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE ssl_expr_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void ssl_expr_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void ssl_expr_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void ssl_expr_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void ssl_expr_yypop_buffer_state (yyscan_t yyscanner );
+void ap_expr_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void ap_expr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE ap_expr_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void ap_expr_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void ap_expr_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void ap_expr_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void ap_expr_yypop_buffer_state (yyscan_t yyscanner );
-static void ssl_expr_yyensure_buffer_stack (yyscan_t yyscanner );
-static void ssl_expr_yy_load_buffer_state (yyscan_t yyscanner );
-static void ssl_expr_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+static void ap_expr_yyensure_buffer_stack (yyscan_t yyscanner );
+static void ap_expr_yy_load_buffer_state (yyscan_t yyscanner );
+static void ap_expr_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER ssl_expr_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+#define YY_FLUSH_BUFFER ap_expr_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-YY_BUFFER_STATE ssl_expr_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE ssl_expr_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE ssl_expr_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+YY_BUFFER_STATE ap_expr_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE ap_expr_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE ap_expr_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-void *ssl_expr_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *ssl_expr_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void ssl_expr_yyfree (void * ,yyscan_t yyscanner );
+void *ap_expr_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *ap_expr_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void ap_expr_yyfree (void * ,yyscan_t yyscanner );
-#define yy_new_buffer ssl_expr_yy_create_buffer
+#define yy_new_buffer ap_expr_yy_create_buffer
#define yy_set_interactive(is_interactive) \
{ \
if ( ! YY_CURRENT_BUFFER ){ \
- ssl_expr_yyensure_buffer_stack (yyscanner); \
+ ap_expr_yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- ssl_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ ap_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
#define yy_set_bol(at_bol) \
{ \
if ( ! YY_CURRENT_BUFFER ){\
- ssl_expr_yyensure_buffer_stack (yyscanner); \
+ ap_expr_yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- ssl_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ ap_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
/* Begin user sect3 */
-#define ssl_expr_yywrap(n) 1
+#define ap_expr_yywrap(n) 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 47
-#define YY_END_OF_BUFFER 48
+#define YY_NUM_RULES 65
+#define YY_END_OF_BUFFER 66
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[97] =
+static yyconst flex_int16_t yy_accept[119] =
{ 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 48, 46,
- 1, 38, 2, 46, 44, 24, 46, 28, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 46, 13, 4, 3, 14, 16, 18, 17, 1, 22,
- 32, 34, 44, 26, 20, 31, 30, 45, 45, 45,
- 19, 45, 45, 29, 27, 39, 25, 23, 15, 15,
- 21, 45, 35, 45, 36, 13, 12, 5, 6, 10,
- 11, 7, 8, 9, 45, 33, 45, 45, 37, 45,
- 5, 6, 45, 45, 41, 42, 5, 45, 43, 45,
- 45, 45, 45, 45, 40, 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
} ;
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, 1, 1, 1, 6, 1, 1,
- 1, 1, 1, 1, 7, 1, 1, 8, 8, 8,
- 8, 8, 8, 8, 8, 9, 9, 7, 1, 10,
- 11, 12, 1, 1, 13, 13, 13, 13, 14, 13,
- 13, 13, 15, 13, 13, 16, 13, 13, 13, 17,
- 13, 18, 19, 20, 13, 13, 13, 21, 13, 13,
- 1, 22, 1, 1, 7, 1, 23, 24, 13, 25,
-
- 26, 27, 28, 13, 29, 13, 13, 30, 31, 32,
- 33, 17, 34, 35, 36, 37, 38, 13, 13, 21,
- 13, 13, 1, 39, 1, 40, 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, 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
} ;
-static yyconst flex_int32_t yy_meta[41] =
+static yyconst flex_int32_t yy_meta[43] =
{ 0,
- 1, 1, 2, 1, 3, 1, 4, 4, 4, 1,
- 1, 1, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 3, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 1, 1
+ 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
} ;
-static yyconst flex_int16_t yy_base[104] =
+static yyconst flex_int16_t yy_base[128] =
{ 0,
- 0, 0, 38, 39, 0, 0, 101, 100, 128, 174,
- 43, 36, 174, 121, 40, 115, 39, 114, 0, 37,
- 92, 89, 29, 27, 90, 28, 79, 29, 82, 81,
- 76, 0, 174, 174, 112, 174, 174, 174, 54, 174,
- 174, 174, 58, 174, 174, 174, 174, 0, 45, 87,
- 0, 81, 80, 0, 0, 0, 0, 0, 174, 0,
- 0, 71, 0, 69, 174, 0, 174, 60, 64, 174,
- 174, 174, 174, 174, 52, 0, 70, 79, 0, 78,
- 66, 69, 68, 74, 0, 0, 84, 78, 0, 66,
- 72, 80, 77, 77, 0, 174, 149, 153, 157, 94,
-
- 161, 165, 169
+ 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
} ;
-static yyconst flex_int16_t yy_def[104] =
+static yyconst flex_int16_t yy_def[128] =
{ 0,
- 96, 1, 97, 97, 98, 98, 99, 99, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 100, 100,
- 100, 100, 100, 100, 100, 100, 101, 100, 100, 100,
- 96, 102, 96, 96, 103, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 100, 100, 100,
- 100, 100, 100, 100, 100, 100, 100, 100, 96, 100,
- 100, 100, 100, 100, 96, 102, 96, 96, 96, 96,
- 96, 96, 96, 96, 100, 100, 100, 100, 100, 100,
- 96, 96, 100, 100, 100, 100, 96, 100, 100, 100,
- 100, 100, 100, 100, 100, 0, 96, 96, 96, 96,
-
- 96, 96, 96
+ 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
} ;
-static yyconst flex_int16_t yy_nxt[215] =
+static yyconst flex_int16_t yy_nxt[303] =
{ 0,
- 10, 11, 11, 12, 13, 14, 10, 15, 15, 16,
- 17, 18, 19, 19, 19, 19, 20, 19, 19, 19,
- 19, 10, 21, 19, 19, 22, 23, 24, 25, 26,
- 27, 28, 29, 19, 19, 19, 30, 19, 31, 10,
- 33, 33, 34, 34, 39, 39, 40, 43, 43, 45,
- 49, 52, 54, 57, 61, 39, 39, 53, 75, 35,
- 35, 62, 49, 55, 58, 43, 43, 81, 82, 83,
- 75, 82, 82, 87, 82, 41, 82, 82, 46, 59,
- 59, 88, 59, 59, 59, 91, 83, 92, 59, 59,
- 59, 82, 82, 88, 93, 94, 95, 48, 90, 89,
-
- 59, 92, 91, 86, 85, 84, 80, 79, 93, 78,
- 77, 76, 94, 95, 65, 64, 63, 59, 59, 68,
- 69, 56, 51, 50, 47, 44, 42, 96, 38, 38,
- 96, 96, 96, 96, 96, 70, 96, 96, 71, 96,
- 96, 96, 96, 72, 96, 96, 73, 96, 74, 32,
- 32, 32, 32, 36, 36, 36, 36, 37, 37, 37,
- 37, 60, 96, 60, 60, 66, 96, 96, 66, 67,
- 67, 67, 67, 9, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96
+ 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
} ;
-static yyconst flex_int16_t yy_chk[215] =
+static yyconst flex_int16_t yy_chk[303] =
{ 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,
- 3, 4, 3, 4, 11, 11, 12, 15, 15, 17,
- 20, 23, 24, 26, 28, 39, 39, 23, 49, 3,
- 4, 28, 20, 24, 26, 43, 43, 68, 68, 75,
- 49, 69, 69, 81, 81, 12, 82, 82, 17, 27,
- 27, 83, 27, 27, 27, 90, 75, 91, 27, 27,
- 27, 87, 87, 83, 92, 93, 94, 100, 88, 84,
-
- 27, 91, 90, 80, 78, 77, 64, 62, 92, 53,
- 52, 50, 93, 94, 31, 30, 29, 27, 27, 35,
- 35, 25, 22, 21, 18, 16, 14, 9, 8, 7,
- 0, 0, 0, 0, 0, 35, 0, 0, 35, 0,
- 0, 0, 0, 35, 0, 0, 35, 0, 35, 97,
- 97, 97, 97, 98, 98, 98, 98, 99, 99, 99,
- 99, 101, 0, 101, 101, 102, 0, 0, 102, 103,
- 103, 103, 103, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96
+ 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,
+ 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
} ;
/* The intent behind this definition is that it'll catch
#define yymore() yymore_used_but_not_detected
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "ssl_expr_scan.l"
+#line 1 "util_expr_scan.l"
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/* _ _
- * _ __ ___ ___ __| | ___ ___| |
- * | '_ ` _ \ / _ \ / _` | / __/ __| |
- * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL
- * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/
- * |_____|
- * ssl_expr_scan.l
- * Expression Scanner
+/*
+ * ap_expr_scan.l, based on ssl_expr_scan.l from mod_ssl
*/
-/* ``Killing for peace is
-like fucking for virginity.''
--- Unknown */
/* _________________________________________________________________
**
** Expression Scanner
#define YY_NO_INPUT 1
-#line 49 "ssl_expr_scan.l"
-#include "ssl_private.h"
-#include "ssl_expr_parse.h"
-#include "ssl_expr.h"
+
+#line 43 "util_expr_scan.l"
+#include "util_expr_private.h"
+#include "util_expr_parse.h"
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
} \
}
-#define MAX_STR_LEN 2048
-#define YY_EXTRA_TYPE ssl_expr_info_type*
-#line 580 "ssl_expr_scan.c"
+#define YY_EXTRA_TYPE ap_expr_parse_ctx*
+
+#define PERROR(msg) yyextra->error2 = msg ; return ERROR;
+
+#define str_ptr (yyextra->scan_ptr)
+#define str_buf (yyextra->scan_buf)
+#define str_del (yyextra->scan_del)
+
+#line 604 "util_expr_scan.c"
#define INITIAL 0
#define str 1
-#define regex 2
-#define regex_flags 3
+#define var 2
+#define vararg 3
+#define regex 4
+#define regex_flags 5
#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
* from bison output in section 1.*/
# define yylval yyg->yylval_r
-int ssl_expr_yylex_init (yyscan_t* scanner);
+int ap_expr_yylex_init (yyscan_t* scanner);
-int ssl_expr_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int ap_expr_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int ssl_expr_yylex_destroy (yyscan_t yyscanner );
+int ap_expr_yylex_destroy (yyscan_t yyscanner );
-int ssl_expr_yyget_debug (yyscan_t yyscanner );
+int ap_expr_yyget_debug (yyscan_t yyscanner );
-void ssl_expr_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+void ap_expr_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-YY_EXTRA_TYPE ssl_expr_yyget_extra (yyscan_t yyscanner );
+YY_EXTRA_TYPE ap_expr_yyget_extra (yyscan_t yyscanner );
-void ssl_expr_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+void ap_expr_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-FILE *ssl_expr_yyget_in (yyscan_t yyscanner );
+FILE *ap_expr_yyget_in (yyscan_t yyscanner );
-void ssl_expr_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+void ap_expr_yyset_in (FILE * in_str ,yyscan_t yyscanner );
-FILE *ssl_expr_yyget_out (yyscan_t yyscanner );
+FILE *ap_expr_yyget_out (yyscan_t yyscanner );
-void ssl_expr_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+void ap_expr_yyset_out (FILE * out_str ,yyscan_t yyscanner );
-int ssl_expr_yyget_leng (yyscan_t yyscanner );
+int ap_expr_yyget_leng (yyscan_t yyscanner );
-char *ssl_expr_yyget_text (yyscan_t yyscanner );
+char *ap_expr_yyget_text (yyscan_t yyscanner );
-int ssl_expr_yyget_lineno (yyscan_t yyscanner );
+int ap_expr_yyget_lineno (yyscan_t yyscanner );
-void ssl_expr_yyset_lineno (int line_number ,yyscan_t yyscanner );
+void ap_expr_yyset_lineno (int line_number ,yyscan_t yyscanner );
-YYSTYPE * ssl_expr_yyget_lval (yyscan_t yyscanner );
+YYSTYPE * ap_expr_yyget_lval (yyscan_t yyscanner );
-void ssl_expr_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+void ap_expr_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int ssl_expr_yywrap (yyscan_t yyscanner );
+extern "C" int ap_expr_yywrap (yyscan_t yyscanner );
#else
-extern int ssl_expr_yywrap (yyscan_t yyscanner );
+extern int ap_expr_yywrap (yyscan_t yyscanner );
#endif
#endif
#endif
+ static void yy_push_state (int new_state ,yyscan_t yyscanner);
+
+ static void yy_pop_state (yyscan_t yyscanner );
+
+ static int yy_top_state (yyscan_t yyscanner );
+
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#ifdef __ia64__
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
-extern int ssl_expr_yylex \
+extern int ap_expr_yylex \
(YYSTYPE * yylval_param ,yyscan_t yyscanner);
-#define YY_DECL int ssl_expr_yylex \
+#define YY_DECL int ap_expr_yylex \
(YYSTYPE * yylval_param , yyscan_t yyscanner)
#endif /* !YY_DECL */
register int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-#line 74 "ssl_expr_scan.l"
+#line 72 "util_expr_scan.l"
-
- char caStr[MAX_STR_LEN];
- char *cpStr = NULL;
- char caRegex[MAX_STR_LEN];
- char *cpRegex = NULL;
- char cRegexDel = NUL;
+
+ char regex_buf[MAX_STRING_LEN];
+ char *regex_ptr = NULL;
+ char regex_del = '\0';
/*
* Whitespaces
*/
-#line 831 "ssl_expr_scan.c"
+#line 861 "util_expr_scan.c"
yylval = yylval_param;
yyout = stdout;
if ( ! YY_CURRENT_BUFFER ) {
- ssl_expr_yyensure_buffer_stack (yyscanner);
+ ap_expr_yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- ssl_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ ap_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
}
- ssl_expr_yy_load_buffer_state(yyscanner );
+ ap_expr_yy_load_buffer_state(yyscanner );
}
while ( 1 ) /* loops until end-of-file is reached */
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 >= 97 )
+ if ( yy_current_state >= 119 )
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 != 96 );
+ while ( yy_current_state != 118 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
-#line 85 "ssl_expr_scan.l"
+#line 81 "util_expr_scan.l"
{
/* NOP */
}
YY_BREAK
/*
- * C-style strings ("...")
+ * strings ("..." and '...')
*/
case 2:
YY_RULE_SETUP
-#line 92 "ssl_expr_scan.l"
+#line 88 "util_expr_scan.l"
{
- cpStr = caStr;
+ str_ptr = str_buf;
+ str_del = yytext[0];
BEGIN(str);
+ return T_STR_BEGIN;
}
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 96 "ssl_expr_scan.l"
+#line 94 "util_expr_scan.l"
{
- BEGIN(INITIAL);
- *cpStr = NUL;
- yylval->cpVal = apr_pstrdup(yyextra->pool, caStr);
- return T_STRING;
+ if (yytext[0] == str_del) {
+ if (YY_START == var) {
+ PERROR("Unterminated variable in string");
+ }
+ else if (str_ptr == str_buf) {
+ BEGIN(INITIAL);
+ return T_STR_END;
+ }
+ else {
+ /* return what we have so far and scan delimiter again */
+ *str_ptr = '\0';
+ yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
+ yyless(0);
+ str_ptr = str_buf;
+ return T_STRING;
+ }
+ }
+ else {
+ *str_ptr++ = yytext[0];
+ }
}
YY_BREAK
case 4:
/* rule 4 can match eol */
YY_RULE_SETUP
-#line 102 "ssl_expr_scan.l"
+#line 116 "util_expr_scan.l"
{
- ssl_expr_yyerror(yyextra, "Unterminated string");
+ PERROR("Unterminated string or variable");
+}
+ YY_BREAK
+case YY_STATE_EOF(str):
+case YY_STATE_EOF(var):
+case YY_STATE_EOF(vararg):
+#line 119 "util_expr_scan.l"
+{
+ PERROR("Unterminated string or variable");
}
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 105 "ssl_expr_scan.l"
+#line 122 "util_expr_scan.l"
{
int result;
(void)sscanf(yytext+1, "%o", &result);
- if (result > 0xff)
- ssl_expr_yyerror(yyextra, "Escape sequence out of bound");
- else
- *cpStr++ = result;
+ if (result > 0xff) {
+ PERROR("Escape sequence out of bound");
+ }
+ else {
+ *str_ptr++ = result;
+ }
}
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 114 "ssl_expr_scan.l"
+#line 133 "util_expr_scan.l"
{
- ssl_expr_yyerror(yyextra, "Bad escape sequence");
+ PERROR("Bad escape sequence");
}
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 117 "ssl_expr_scan.l"
-{ *cpStr++ = '\n'; }
+#line 136 "util_expr_scan.l"
+{ *str_ptr++ = '\n'; }
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 118 "ssl_expr_scan.l"
-{ *cpStr++ = '\r'; }
+#line 137 "util_expr_scan.l"
+{ *str_ptr++ = '\r'; }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 119 "ssl_expr_scan.l"
-{ *cpStr++ = '\t'; }
+#line 138 "util_expr_scan.l"
+{ *str_ptr++ = '\t'; }
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 120 "ssl_expr_scan.l"
-{ *cpStr++ = '\b'; }
+#line 139 "util_expr_scan.l"
+{ *str_ptr++ = '\b'; }
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 121 "ssl_expr_scan.l"
-{ *cpStr++ = '\f'; }
+#line 140 "util_expr_scan.l"
+{ *str_ptr++ = '\f'; }
YY_BREAK
case 12:
/* rule 12 can match eol */
YY_RULE_SETUP
-#line 122 "ssl_expr_scan.l"
+#line 141 "util_expr_scan.l"
{
- *cpStr++ = yytext[1];
+ *str_ptr++ = yytext[1];
}
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 125 "ssl_expr_scan.l"
+#line 145 "util_expr_scan.l"
{
char *cp = yytext;
- while (*cp != NUL)
- *cpStr++ = *cp++;
+ while (*cp != '\0')
+ *str_ptr++ = *cp++;
}
YY_BREAK
+/* variable inside string */
case 14:
YY_RULE_SETUP
-#line 130 "ssl_expr_scan.l"
+#line 152 "util_expr_scan.l"
{
- *cpStr++ = yytext[1];
+ if (str_ptr != str_buf) {
+ /* return what we have so far and scan '%{' again */
+ *str_ptr = '\0';
+ yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
+ yyless(0);
+ str_ptr = str_buf;
+ return T_STRING;
+ }
+ else {
+ yy_push_state(var, yyscanner);
+ return T_VAR_BEGIN;
+ }
}
YY_BREAK
-/*
- * Regular Expression
- */
case 15:
YY_RULE_SETUP
-#line 137 "ssl_expr_scan.l"
+#line 167 "util_expr_scan.l"
{
- cRegexDel = yytext[1];
- cpRegex = caRegex;
- BEGIN(regex);
+ *str_ptr++ = yytext[0];
}
YY_BREAK
case 16:
-/* rule 16 can match eol */
YY_RULE_SETUP
-#line 142 "ssl_expr_scan.l"
+#line 171 "util_expr_scan.l"
{
- if (yytext[0] == cRegexDel) {
- *cpRegex = NUL;
- BEGIN(regex_flags);
- }
- else {
- *cpRegex++ = yytext[0];
- }
+ *str_ptr++ = yytext[0];
}
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 151 "ssl_expr_scan.l"
+#line 175 "util_expr_scan.l"
{
- yylval->cpVal = apr_pstrdup(yyextra->pool, caRegex);
- BEGIN(INITIAL);
- return T_REGEX_I;
+ yy_push_state(var, yyscanner);
+ return T_VAR_BEGIN;
}
YY_BREAK
+/*
+ * fixed name variable expansion %{XXX} and function call in %{func:arg} syntax
+ */
case 18:
-/* rule 18 can match eol */
YY_RULE_SETUP
-#line 156 "ssl_expr_scan.l"
-{
- yylval->cpVal = apr_pstrdup(yyextra->pool, caRegex);
- yyless(0);
- BEGIN(INITIAL);
- return T_REGEX;
-}
- YY_BREAK
-case YY_STATE_EOF(regex_flags):
-#line 162 "ssl_expr_scan.l"
+#line 183 "util_expr_scan.l"
{
- yylval->cpVal = apr_pstrdup(yyextra->pool, caRegex);
- BEGIN(INITIAL);
- return T_REGEX;
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
+ return T_ID;
}
YY_BREAK
-/*
- * Operators
- */
case 19:
YY_RULE_SETUP
-#line 171 "ssl_expr_scan.l"
-{ return T_OP_EQ; }
+#line 188 "util_expr_scan.l"
+{
+ yy_pop_state(yyscanner);
+ return T_VAR_END;
+}
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 172 "ssl_expr_scan.l"
-{ return T_OP_EQ; }
+#line 193 "util_expr_scan.l"
+{
+ BEGIN(vararg);
+ return yytext[0];
+}
YY_BREAK
case 21:
+/* rule 21 can match eol */
YY_RULE_SETUP
-#line 173 "ssl_expr_scan.l"
-{ return T_OP_NE; }
+#line 198 "util_expr_scan.l"
+{
+ char c[2] = { yytext[0], '\0' };
+ char *msg = apr_psprintf(yyextra->pool,
+ "Invalid character in variable name '%s'", c);
+ PERROR(msg);
+}
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 174 "ssl_expr_scan.l"
-{ return T_OP_NE; }
+#line 205 "util_expr_scan.l"
+{
+ if (str_ptr != str_buf) {
+ /* return what we have so far and scan '}' again */
+ *str_ptr = '\0';
+ yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
+ str_ptr = str_buf;
+ yyless(0);
+ return T_STRING;
+ }
+ else {
+ yy_pop_state(yyscanner);
+ return T_VAR_END;
+ }
+}
YY_BREAK
+/*
+ * Regular Expression
+ */
case 23:
YY_RULE_SETUP
-#line 175 "ssl_expr_scan.l"
-{ return T_OP_LT; }
+#line 223 "util_expr_scan.l"
+{
+ regex_del = yytext[1];
+ regex_ptr = regex_buf;
+ BEGIN(regex);
+}
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 176 "ssl_expr_scan.l"
-{ return T_OP_LT; }
+#line 228 "util_expr_scan.l"
+{
+ regex_del = yytext[0];
+ regex_ptr = regex_buf;
+ BEGIN(regex);
+}
YY_BREAK
case 25:
+/* rule 25 can match eol */
YY_RULE_SETUP
-#line 177 "ssl_expr_scan.l"
-{ return T_OP_LE; }
+#line 233 "util_expr_scan.l"
+{
+ if (yytext[0] == regex_del) {
+ *regex_ptr = '\0';
+ BEGIN(regex_flags);
+ }
+ else {
+ *regex_ptr++ = yytext[0];
+ }
+}
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 178 "ssl_expr_scan.l"
-{ return T_OP_LE; }
+#line 242 "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 */
YY_RULE_SETUP
-#line 179 "ssl_expr_scan.l"
-{ return T_OP_GT; }
+#line 247 "util_expr_scan.l"
+{
+ yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
+ yyless(0);
+ BEGIN(INITIAL);
+ return T_REGEX;
+}
YY_BREAK
+case YY_STATE_EOF(regex_flags):
+#line 253 "util_expr_scan.l"
+{
+ yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
+ BEGIN(INITIAL);
+ return T_REGEX;
+}
+ YY_BREAK
+/*
+ * Operators
+ */
case 28:
YY_RULE_SETUP
-#line 180 "ssl_expr_scan.l"
-{ return T_OP_GT; }
+#line 262 "util_expr_scan.l"
+{ return T_OP_STR_EQ; }
YY_BREAK
case 29:
YY_RULE_SETUP
-#line 181 "ssl_expr_scan.l"
-{ return T_OP_GE; }
+#line 263 "util_expr_scan.l"
+{ return T_OP_STR_NE; }
YY_BREAK
case 30:
YY_RULE_SETUP
-#line 182 "ssl_expr_scan.l"
-{ return T_OP_GE; }
+#line 264 "util_expr_scan.l"
+{ return T_OP_STR_LT; }
YY_BREAK
case 31:
YY_RULE_SETUP
-#line 183 "ssl_expr_scan.l"
-{ return T_OP_REG; }
+#line 265 "util_expr_scan.l"
+{ return T_OP_STR_LE; }
YY_BREAK
case 32:
YY_RULE_SETUP
-#line 184 "ssl_expr_scan.l"
-{ return T_OP_NRE; }
+#line 266 "util_expr_scan.l"
+{ return T_OP_STR_GT; }
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 185 "ssl_expr_scan.l"
-{ return T_OP_AND; }
+#line 267 "util_expr_scan.l"
+{ return T_OP_STR_GE; }
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 186 "ssl_expr_scan.l"
-{ return T_OP_AND; }
+#line 268 "util_expr_scan.l"
+{ return T_OP_REG; }
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 187 "ssl_expr_scan.l"
-{ return T_OP_OR; }
+#line 269 "util_expr_scan.l"
+{ return T_OP_NRE; }
YY_BREAK
case 36:
YY_RULE_SETUP
-#line 188 "ssl_expr_scan.l"
-{ return T_OP_OR; }
+#line 270 "util_expr_scan.l"
+{ return T_OP_AND; }
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 189 "ssl_expr_scan.l"
-{ return T_OP_NOT; }
+#line 271 "util_expr_scan.l"
+{ return T_OP_AND; }
YY_BREAK
case 38:
YY_RULE_SETUP
-#line 190 "ssl_expr_scan.l"
-{ return T_OP_NOT; }
+#line 272 "util_expr_scan.l"
+{ return T_OP_OR; }
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 191 "ssl_expr_scan.l"
-{ return T_OP_IN; }
+#line 273 "util_expr_scan.l"
+{ return T_OP_OR; }
YY_BREAK
case 40:
YY_RULE_SETUP
-#line 192 "ssl_expr_scan.l"
-{ return T_OP_PEEREXTLIST; }
+#line 274 "util_expr_scan.l"
+{ return T_OP_NOT; }
YY_BREAK
-/*
- * Functions
- */
case 41:
YY_RULE_SETUP
-#line 197 "ssl_expr_scan.l"
-{ return T_FUNC_FILE; }
+#line 275 "util_expr_scan.l"
+{ return T_OP_NOT; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 276 "util_expr_scan.l"
+{ return T_OP_CONCAT; }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 277 "util_expr_scan.l"
+{ return T_OP_IN; }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 278 "util_expr_scan.l"
+{ return T_OP_EQ; }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 279 "util_expr_scan.l"
+{ return T_OP_NE; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 280 "util_expr_scan.l"
+{ return T_OP_GE; }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 281 "util_expr_scan.l"
+{ return T_OP_LE; }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 282 "util_expr_scan.l"
+{ return T_OP_GT; }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 283 "util_expr_scan.l"
+{ return T_OP_LT; }
+ YY_BREAK
+/* for compatibility with ssl_expr */
+case 50:
+YY_RULE_SETUP
+#line 286 "util_expr_scan.l"
+{ return T_OP_LT; }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 287 "util_expr_scan.l"
+{ return T_OP_LE; }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 288 "util_expr_scan.l"
+{ return T_OP_GT; }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 289 "util_expr_scan.l"
+{ return T_OP_GE; }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 290 "util_expr_scan.l"
+{ return T_OP_NE; }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 291 "util_expr_scan.l"
+{ return T_OP_EQ; }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 292 "util_expr_scan.l"
+{ return T_OP_IN; }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 294 "util_expr_scan.l"
+{
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
+ return T_OP_UNARY;
+}
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 299 "util_expr_scan.l"
+{
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
+ return T_OP_BINARY;
+}
YY_BREAK
/*
* Specials
*/
-case 42:
+case 59:
YY_RULE_SETUP
-#line 202 "ssl_expr_scan.l"
+#line 307 "util_expr_scan.l"
{ return T_TRUE; }
YY_BREAK
-case 43:
+case 60:
YY_RULE_SETUP
-#line 203 "ssl_expr_scan.l"
+#line 308 "util_expr_scan.l"
{ return T_FALSE; }
YY_BREAK
/*
* Digits
*/
-case 44:
+case 61:
YY_RULE_SETUP
-#line 208 "ssl_expr_scan.l"
+#line 313 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_DIGIT;
/*
* Identifiers
*/
-case 45:
+case 62:
YY_RULE_SETUP
-#line 216 "ssl_expr_scan.l"
+#line 321 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_ID;
}
YY_BREAK
/*
- * Anything else is returned as is...
+ * These are parts of the grammar and are returned as is
*/
-case 46:
-/* rule 46 can match eol */
+case 63:
YY_RULE_SETUP
-#line 224 "ssl_expr_scan.l"
-{
+#line 329 "util_expr_scan.l"
+{
return yytext[0];
}
YY_BREAK
-case 47:
+/*
+ * Anything else is an error
+ */
+case 64:
+/* rule 64 can match eol */
YY_RULE_SETUP
-#line 228 "ssl_expr_scan.l"
+#line 336 "util_expr_scan.l"
+{
+ char c[2] = { yytext[0], '\0' };
+ char *msg = apr_psprintf(yyextra->pool, "Parse error near '%s'", c);
+ PERROR(msg);
+}
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 342 "util_expr_scan.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1244 "ssl_expr_scan.c"
+#line 1457 "util_expr_scan.c"
case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(str):
case YY_STATE_EOF(regex):
yyterminate();
/* We're scanning a new file or input source. It's
* possible that this happened because the user
* just pointed yyin at a new source and called
- * ssl_expr_yylex(). If so, then we have to assure
+ * ap_expr_yylex(). If so, then we have to assure
* consistency between YY_CURRENT_BUFFER and our
* globals. Here is the right place to do so, because
* this is the first action (other than possibly a
{
yyg->yy_did_buffer_switch_on_eof = 0;
- if ( ssl_expr_yywrap(yyscanner ) )
+ if ( ap_expr_yywrap(yyscanner ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
-} /* end of ssl_expr_yylex */
+} /* end of ap_expr_yylex */
/* yy_get_next_buffer - try to read in a new buffer
*
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
- ssl_expr_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ ap_expr_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
}
else
/* Can't grow it, we don't own it. */
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- ssl_expr_yyrestart(yyin ,yyscanner);
+ ap_expr_yyrestart(yyin ,yyscanner);
}
else
if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ssl_expr_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ap_expr_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
}
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 >= 97 )
+ if ( yy_current_state >= 119 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
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 >= 97 )
+ if ( yy_current_state >= 119 )
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 == 96);
+ yy_is_jam = (yy_current_state == 118);
return yy_is_jam ? 0 : yy_current_state;
}
*/
/* Reset buffer status. */
- ssl_expr_yyrestart(yyin ,yyscanner);
+ ap_expr_yyrestart(yyin ,yyscanner);
/*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( ssl_expr_yywrap(yyscanner ) )
+ if ( ap_expr_yywrap(yyscanner ) )
return EOF;
if ( ! yyg->yy_did_buffer_switch_on_eof )
* @param yyscanner The scanner object.
* @note This function does not reset the start condition to @c INITIAL .
*/
- void ssl_expr_yyrestart (FILE * input_file , yyscan_t yyscanner)
+ void ap_expr_yyrestart (FILE * input_file , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( ! YY_CURRENT_BUFFER ){
- ssl_expr_yyensure_buffer_stack (yyscanner);
+ ap_expr_yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- ssl_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ ap_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
}
- ssl_expr_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- ssl_expr_yy_load_buffer_state(yyscanner );
+ ap_expr_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ ap_expr_yy_load_buffer_state(yyscanner );
}
/** Switch to a different input buffer.
* @param new_buffer The new input buffer.
* @param yyscanner The scanner object.
*/
- void ssl_expr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+ void ap_expr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* TODO. We should be able to replace this entire function body
* with
- * ssl_expr_yypop_buffer_state();
- * ssl_expr_yypush_buffer_state(new_buffer);
+ * ap_expr_yypop_buffer_state();
+ * ap_expr_yypush_buffer_state(new_buffer);
*/
- ssl_expr_yyensure_buffer_stack (yyscanner);
+ ap_expr_yyensure_buffer_stack (yyscanner);
if ( YY_CURRENT_BUFFER == new_buffer )
return;
}
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- ssl_expr_yy_load_buffer_state(yyscanner );
+ ap_expr_yy_load_buffer_state(yyscanner );
/* We don't actually know whether we did this switch during
- * EOF (ssl_expr_yywrap()) processing, but the only time this flag
- * is looked at is after ssl_expr_yywrap() is called, so it's safe
+ * EOF (ap_expr_yywrap()) processing, but the only time this flag
+ * is looked at is after ap_expr_yywrap() is called, so it's safe
* to go ahead and always set it.
*/
yyg->yy_did_buffer_switch_on_eof = 1;
}
-static void ssl_expr_yy_load_buffer_state (yyscan_t yyscanner)
+static void ap_expr_yy_load_buffer_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
* @param yyscanner The scanner object.
* @return the allocated buffer state.
*/
- YY_BUFFER_STATE ssl_expr_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+ YY_BUFFER_STATE ap_expr_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
- b = (YY_BUFFER_STATE) ssl_expr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) ap_expr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in ssl_expr_yy_create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yy_create_buffer()" );
b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) ssl_expr_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ b->yy_ch_buf = (char *) ap_expr_yyalloc(b->yy_buf_size + 2 ,yyscanner );
if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in ssl_expr_yy_create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- ssl_expr_yy_init_buffer(b,file ,yyscanner);
+ ap_expr_yy_init_buffer(b,file ,yyscanner);
return b;
}
/** Destroy the buffer.
- * @param b a buffer created with ssl_expr_yy_create_buffer()
+ * @param b a buffer created with ap_expr_yy_create_buffer()
* @param yyscanner The scanner object.
*/
- void ssl_expr_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void ap_expr_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- ssl_expr_yyfree((void *) b->yy_ch_buf ,yyscanner );
+ ap_expr_yyfree((void *) b->yy_ch_buf ,yyscanner );
- ssl_expr_yyfree((void *) b ,yyscanner );
+ ap_expr_yyfree((void *) b ,yyscanner );
}
/* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer,
- * such as during a ssl_expr_yyrestart() or at EOF.
+ * such as during a ap_expr_yyrestart() or at EOF.
*/
- static void ssl_expr_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+ static void ap_expr_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
{
int oerrno = errno;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- ssl_expr_yy_flush_buffer(b ,yyscanner);
+ ap_expr_yy_flush_buffer(b ,yyscanner);
b->yy_input_file = file;
b->yy_fill_buffer = 1;
- /* If b is the current buffer, then ssl_expr_yy_init_buffer was _probably_
- * called from ssl_expr_yyrestart() or through yy_get_next_buffer.
+ /* If b is the current buffer, then ap_expr_yy_init_buffer was _probably_
+ * called from ap_expr_yyrestart() or through yy_get_next_buffer.
* In that case, we don't want to reset the lineno or column.
*/
if (b != YY_CURRENT_BUFFER){
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
* @param yyscanner The scanner object.
*/
- void ssl_expr_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void ap_expr_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( ! b )
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == YY_CURRENT_BUFFER )
- ssl_expr_yy_load_buffer_state(yyscanner );
+ ap_expr_yy_load_buffer_state(yyscanner );
}
/** Pushes the new state onto the stack. The new state becomes
* @param new_buffer The new state.
* @param yyscanner The scanner object.
*/
-void ssl_expr_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+void ap_expr_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (new_buffer == NULL)
return;
- ssl_expr_yyensure_buffer_stack(yyscanner);
+ ap_expr_yyensure_buffer_stack(yyscanner);
- /* This block is copied from ssl_expr_yy_switch_to_buffer. */
+ /* This block is copied from ap_expr_yy_switch_to_buffer. */
if ( YY_CURRENT_BUFFER )
{
/* Flush out information for old buffer. */
yyg->yy_buffer_stack_top++;
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- /* copied from ssl_expr_yy_switch_to_buffer. */
- ssl_expr_yy_load_buffer_state(yyscanner );
+ /* copied from ap_expr_yy_switch_to_buffer. */
+ ap_expr_yy_load_buffer_state(yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
* The next element becomes the new top.
* @param yyscanner The scanner object.
*/
-void ssl_expr_yypop_buffer_state (yyscan_t yyscanner)
+void ap_expr_yypop_buffer_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (!YY_CURRENT_BUFFER)
return;
- ssl_expr_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ ap_expr_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
YY_CURRENT_BUFFER_LVALUE = NULL;
if (yyg->yy_buffer_stack_top > 0)
--yyg->yy_buffer_stack_top;
if (YY_CURRENT_BUFFER) {
- ssl_expr_yy_load_buffer_state(yyscanner );
+ ap_expr_yy_load_buffer_state(yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
}
/* Allocates the stack if it does not exist.
* Guarantees space for at least one push.
*/
-static void ssl_expr_yyensure_buffer_stack (yyscan_t yyscanner)
+static void ap_expr_yyensure_buffer_stack (yyscan_t yyscanner)
{
int num_to_alloc;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
* immediate realloc on the next call.
*/
num_to_alloc = 1;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)ssl_expr_yyalloc
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)ap_expr_yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in ssl_expr_yyensure_buffer_stack()" );
+ YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yyensure_buffer_stack()" );
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
int grow_size = 8 /* arbitrary grow size */;
num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)ssl_expr_yyrealloc
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)ap_expr_yyrealloc
(yyg->yy_buffer_stack,
num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in ssl_expr_yyensure_buffer_stack()" );
+ YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yyensure_buffer_stack()" );
/* zero only the new slots.*/
memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE ssl_expr_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+YY_BUFFER_STATE ap_expr_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
/* They forgot to leave room for the EOB's. */
return 0;
- b = (YY_BUFFER_STATE) ssl_expr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) ap_expr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in ssl_expr_yy_scan_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yy_scan_buffer()" );
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- ssl_expr_yy_switch_to_buffer(b ,yyscanner );
+ ap_expr_yy_switch_to_buffer(b ,yyscanner );
return b;
}
-/** Setup the input buffer state to scan a string. The next call to ssl_expr_yylex() will
+/** Setup the input buffer state to scan a string. The next call to ap_expr_yylex() will
* scan from a @e copy of @a str.
* @param yystr a NUL-terminated string to scan
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
- * ssl_expr_yy_scan_bytes() instead.
+ * ap_expr_yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE ssl_expr_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE ap_expr_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
{
- return ssl_expr_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return ap_expr_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
}
-/** Setup the input buffer state to scan the given bytes. The next call to ssl_expr_yylex() will
+/** Setup the input buffer state to scan the given bytes. The next call to ap_expr_yylex() will
* scan from a @e copy of @a bytes.
* @param yybytes the byte buffer to scan
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE ssl_expr_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE ap_expr_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
- buf = (char *) ssl_expr_yyalloc(n ,yyscanner );
+ buf = (char *) ap_expr_yyalloc(n ,yyscanner );
if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in ssl_expr_yy_scan_bytes()" );
+ YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yy_scan_bytes()" );
for ( i = 0; i < _yybytes_len; ++i )
buf[i] = yybytes[i];
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = ssl_expr_yy_scan_buffer(buf,n ,yyscanner);
+ b = ap_expr_yy_scan_buffer(buf,n ,yyscanner);
if ( ! b )
- YY_FATAL_ERROR( "bad buffer in ssl_expr_yy_scan_bytes()" );
+ YY_FATAL_ERROR( "bad buffer in ap_expr_yy_scan_bytes()" );
/* It's okay to grow etc. this buffer, and we should throw it
* away when we're done.
return b;
}
+ static void yy_push_state (int new_state , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yyg->yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yyg->yy_start_stack_depth * sizeof( int );
+
+ if ( ! yyg->yy_start_stack )
+ yyg->yy_start_stack = (int *) ap_expr_yyalloc(new_size ,yyscanner );
+
+ else
+ yyg->yy_start_stack = (int *) ap_expr_yyrealloc((void *) yyg->yy_start_stack,new_size ,yyscanner );
+
+ if ( ! yyg->yy_start_stack )
+ YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+ }
+
+ yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+}
+
+ static void yy_pop_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( --yyg->yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]);
+}
+
+ static int yy_top_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1];
+}
+
#ifndef YY_EXIT_FAILURE
#define YY_EXIT_FAILURE 2
#endif
/** Get the user-defined data for this scanner.
* @param yyscanner The scanner object.
*/
-YY_EXTRA_TYPE ssl_expr_yyget_extra (yyscan_t yyscanner)
+YY_EXTRA_TYPE ap_expr_yyget_extra (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyextra;
/** Get the current line number.
* @param yyscanner The scanner object.
*/
-int ssl_expr_yyget_lineno (yyscan_t yyscanner)
+int ap_expr_yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/** Get the current column number.
* @param yyscanner The scanner object.
*/
-int ssl_expr_yyget_column (yyscan_t yyscanner)
+int ap_expr_yyget_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/** Get the input stream.
* @param yyscanner The scanner object.
*/
-FILE *ssl_expr_yyget_in (yyscan_t yyscanner)
+FILE *ap_expr_yyget_in (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyin;
/** Get the output stream.
* @param yyscanner The scanner object.
*/
-FILE *ssl_expr_yyget_out (yyscan_t yyscanner)
+FILE *ap_expr_yyget_out (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyout;
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-int ssl_expr_yyget_leng (yyscan_t yyscanner)
+int ap_expr_yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
* @param yyscanner The scanner object.
*/
-char *ssl_expr_yyget_text (yyscan_t yyscanner)
+char *ap_expr_yyget_text (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yytext;
* @param user_defined The data to be associated with this scanner.
* @param yyscanner The scanner object.
*/
-void ssl_expr_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+void ap_expr_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyextra = user_defined ;
* @param line_number
* @param yyscanner The scanner object.
*/
-void ssl_expr_yyset_lineno (int line_number , yyscan_t yyscanner)
+void ap_expr_yyset_lineno (int line_number , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "ssl_expr_yyset_lineno called with no buffer" , yyscanner);
+ yy_fatal_error( "ap_expr_yyset_lineno called with no buffer" , yyscanner);
yylineno = line_number;
}
* @param line_number
* @param yyscanner The scanner object.
*/
-void ssl_expr_yyset_column (int column_no , yyscan_t yyscanner)
+void ap_expr_yyset_column (int column_no , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "ssl_expr_yyset_column called with no buffer" , yyscanner);
+ yy_fatal_error( "ap_expr_yyset_column called with no buffer" , yyscanner);
yycolumn = column_no;
}
* input buffer.
* @param in_str A readable stream.
* @param yyscanner The scanner object.
- * @see ssl_expr_yy_switch_to_buffer
+ * @see ap_expr_yy_switch_to_buffer
*/
-void ssl_expr_yyset_in (FILE * in_str , yyscan_t yyscanner)
+void ap_expr_yyset_in (FILE * in_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyin = in_str ;
}
-void ssl_expr_yyset_out (FILE * out_str , yyscan_t yyscanner)
+void ap_expr_yyset_out (FILE * out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyout = out_str ;
}
-int ssl_expr_yyget_debug (yyscan_t yyscanner)
+int ap_expr_yyget_debug (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yy_flex_debug;
}
-void ssl_expr_yyset_debug (int bdebug , yyscan_t yyscanner)
+void ap_expr_yyset_debug (int bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_flex_debug = bdebug ;
/* Accessor methods for yylval and yylloc */
-YYSTYPE * ssl_expr_yyget_lval (yyscan_t yyscanner)
+YYSTYPE * ap_expr_yyget_lval (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yylval;
}
-void ssl_expr_yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+void ap_expr_yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylval = yylval_param;
/* User-visible API */
-/* ssl_expr_yylex_init is special because it creates the scanner itself, so it is
+/* ap_expr_yylex_init is special because it creates the scanner itself, so it is
* the ONLY reentrant function that doesn't take the scanner as the last argument.
* That's why we explicitly handle the declaration, instead of using our macros.
*/
-int ssl_expr_yylex_init(yyscan_t* ptr_yy_globals)
+int ap_expr_yylex_init(yyscan_t* ptr_yy_globals)
{
if (ptr_yy_globals == NULL){
return 1;
}
- *ptr_yy_globals = (yyscan_t) ssl_expr_yyalloc ( sizeof( struct yyguts_t ), NULL );
+ *ptr_yy_globals = (yyscan_t) ap_expr_yyalloc ( sizeof( struct yyguts_t ), NULL );
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return yy_init_globals ( *ptr_yy_globals );
}
-/* ssl_expr_yylex_init_extra has the same functionality as ssl_expr_yylex_init, but follows the
+/* ap_expr_yylex_init_extra has the same functionality as ap_expr_yylex_init, but follows the
* convention of taking the scanner as the last argument. Note however, that
* this is a *pointer* to a scanner, as it will be allocated by this call (and
* is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to ssl_expr_yyalloc in
+ * The user defined value in the first argument will be available to ap_expr_yyalloc in
* the yyextra field.
*/
-int ssl_expr_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+int ap_expr_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
{
struct yyguts_t dummy_yyguts;
- ssl_expr_yyset_extra (yy_user_defined, &dummy_yyguts);
+ ap_expr_yyset_extra (yy_user_defined, &dummy_yyguts);
if (ptr_yy_globals == NULL){
errno = EINVAL;
return 1;
}
- *ptr_yy_globals = (yyscan_t) ssl_expr_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+ *ptr_yy_globals = (yyscan_t) ap_expr_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
- ssl_expr_yyset_extra (yy_user_defined, *ptr_yy_globals);
+ ap_expr_yyset_extra (yy_user_defined, *ptr_yy_globals);
return yy_init_globals ( *ptr_yy_globals );
}
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Initialization is the same as for the non-reentrant scanner.
- * This function is called from ssl_expr_yylex_destroy(), so don't allocate here.
+ * This function is called from ap_expr_yylex_destroy(), so don't allocate here.
*/
yyg->yy_buffer_stack = 0;
#endif
/* For future reference: Set errno on error, since we are called by
- * ssl_expr_yylex_init()
+ * ap_expr_yylex_init()
*/
return 0;
}
-/* ssl_expr_yylex_destroy is for both reentrant and non-reentrant scanners. */
-int ssl_expr_yylex_destroy (yyscan_t yyscanner)
+/* ap_expr_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int ap_expr_yylex_destroy (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
- ssl_expr_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ ap_expr_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
YY_CURRENT_BUFFER_LVALUE = NULL;
- ssl_expr_yypop_buffer_state(yyscanner);
+ ap_expr_yypop_buffer_state(yyscanner);
}
/* Destroy the stack itself. */
- ssl_expr_yyfree(yyg->yy_buffer_stack ,yyscanner);
+ ap_expr_yyfree(yyg->yy_buffer_stack ,yyscanner);
yyg->yy_buffer_stack = NULL;
/* Destroy the start condition stack. */
- ssl_expr_yyfree(yyg->yy_start_stack ,yyscanner );
+ ap_expr_yyfree(yyg->yy_start_stack ,yyscanner );
yyg->yy_start_stack = NULL;
/* Reset the globals. This is important in a non-reentrant scanner so the next time
- * ssl_expr_yylex() is called, initialization will occur. */
+ * ap_expr_yylex() is called, initialization will occur. */
yy_init_globals( yyscanner);
/* Destroy the main struct (reentrant only). */
- ssl_expr_yyfree ( yyscanner , yyscanner );
+ ap_expr_yyfree ( yyscanner , yyscanner );
yyscanner = NULL;
return 0;
}
}
#endif
-void *ssl_expr_yyalloc (yy_size_t size , yyscan_t yyscanner)
+void *ap_expr_yyalloc (yy_size_t size , yyscan_t yyscanner)
{
return (void *) malloc( size );
}
-void *ssl_expr_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+void *ap_expr_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
{
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
return (void *) realloc( (char *) ptr, size );
}
-void ssl_expr_yyfree (void * ptr , yyscan_t yyscanner)
+void ap_expr_yyfree (void * ptr , yyscan_t yyscanner)
{
- free( (char *) ptr ); /* see ssl_expr_yyrealloc() for (char *) cast */
+ free( (char *) ptr ); /* see ap_expr_yyrealloc() for (char *) cast */
}
#define YYTABLES_NAME "yytables"
-#line 228 "ssl_expr_scan.l"
+#line 342 "util_expr_scan.l"
--- /dev/null
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * ap_expr_scan.l, based on ssl_expr_scan.l from mod_ssl
+ */
+
+/* _________________________________________________________________
+**
+** Expression Scanner
+** _________________________________________________________________
+*/
+
+%pointer
+%option batch
+%option never-interactive
+%option nodefault
+%option noyywrap
+%option reentrant
+%option bison-bridge
+%option warn
+%option noinput nounput
+%option stack
+%x str
+%x var
+%x vararg
+%x regex regex_flags
+
+%{
+#include "util_expr_private.h"
+#include "util_expr_parse.h"
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+{ \
+ if ((result = MIN(max_size, yyextra->inputbuf \
+ + yyextra->inputlen \
+ - yyextra->inputptr)) <= 0) \
+ { \
+ result = YY_NULL; \
+ } \
+ else { \
+ memcpy(buf, yyextra->inputptr, result); \
+ yyextra->inputptr += result; \
+ } \
+}
+
+#define YY_EXTRA_TYPE ap_expr_parse_ctx*
+
+#define PERROR(msg) yyextra->error2 = msg ; return ERROR;
+
+#define str_ptr (yyextra->scan_ptr)
+#define str_buf (yyextra->scan_buf)
+#define str_del (yyextra->scan_del)
+
+%}
+
+
+%%
+
+ char regex_buf[MAX_STRING_LEN];
+ char *regex_ptr = NULL;
+ char regex_del = '\0';
+
+ /*
+ * Whitespaces
+ */
+[ \t\n]+ {
+ /* NOP */
+}
+
+ /*
+ * strings ("..." and '...')
+ */
+["'] {
+ str_ptr = str_buf;
+ str_del = yytext[0];
+ BEGIN(str);
+ return T_STR_BEGIN;
+}
+<str>["'] {
+ if (yytext[0] == str_del) {
+ if (YY_START == var) {
+ PERROR("Unterminated variable in string");
+ }
+ else if (str_ptr == str_buf) {
+ BEGIN(INITIAL);
+ return T_STR_END;
+ }
+ else {
+ /* return what we have so far and scan delimiter again */
+ *str_ptr = '\0';
+ yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
+ yyless(0);
+ str_ptr = str_buf;
+ return T_STRING;
+ }
+ }
+ else {
+ *str_ptr++ = yytext[0];
+ }
+}
+<str,var,vararg>\n {
+ PERROR("Unterminated string or variable");
+}
+<str,var,vararg><<EOF>> {
+ PERROR("Unterminated string or variable");
+}
+<str,vararg>\\[0-7]{1,3} {
+ int result;
+
+ (void)sscanf(yytext+1, "%o", &result);
+ if (result > 0xff) {
+ PERROR("Escape sequence out of bound");
+ }
+ else {
+ *str_ptr++ = result;
+ }
+}
+<str,vararg>\\[0-9]+ {
+ PERROR("Bad escape sequence");
+}
+<str,vararg>\\n { *str_ptr++ = '\n'; }
+<str,vararg>\\r { *str_ptr++ = '\r'; }
+<str,vararg>\\t { *str_ptr++ = '\t'; }
+<str,vararg>\\b { *str_ptr++ = '\b'; }
+<str,vararg>\\f { *str_ptr++ = '\f'; }
+<str,vararg>\\(.|\n) {
+ *str_ptr++ = yytext[1];
+}
+
+<str,vararg>[^\\\n"'%}]+ {
+ char *cp = yytext;
+ while (*cp != '\0')
+ *str_ptr++ = *cp++;
+}
+
+ /* variable inside string */
+<str>%\{ {
+ if (str_ptr != str_buf) {
+ /* return what we have so far and scan '%{' again */
+ *str_ptr = '\0';
+ yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
+ yyless(0);
+ str_ptr = str_buf;
+ return T_STRING;
+ }
+ else {
+ yy_push_state(var, yyscanner);
+ return T_VAR_BEGIN;
+ }
+}
+
+<vararg>% {
+ *str_ptr++ = yytext[0];
+}
+
+<str>[%}] {
+ *str_ptr++ = yytext[0];
+}
+
+%\{ {
+ yy_push_state(var, yyscanner);
+ return T_VAR_BEGIN;
+}
+
+ /*
+ * fixed name variable expansion %{XXX} and function call in %{func:arg} syntax
+ */
+<var>[a-zA-Z][a-zA-Z0-9_]* {
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
+ return T_ID;
+}
+
+<var>\} {
+ yy_pop_state(yyscanner);
+ return T_VAR_END;
+}
+
+<var>: {
+ BEGIN(vararg);
+ return yytext[0];
+}
+
+<var>.|\n {
+ char c[2] = { yytext[0], '\0' };
+ char *msg = apr_psprintf(yyextra->pool,
+ "Invalid character in variable name '%s'", c);
+ PERROR(msg);
+}
+
+<vararg>\} {
+ if (str_ptr != str_buf) {
+ /* return what we have so far and scan '}' again */
+ *str_ptr = '\0';
+ yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
+ str_ptr = str_buf;
+ yyless(0);
+ return T_STRING;
+ }
+ else {
+ yy_pop_state(yyscanner);
+ return T_VAR_END;
+ }
+}
+
+ /*
+ * Regular Expression
+ */
+"m"[/#$%^,;:_\?\|\^\-\!\.\'\"] {
+ regex_del = yytext[1];
+ regex_ptr = regex_buf;
+ BEGIN(regex);
+}
+"/" {
+ regex_del = yytext[0];
+ regex_ptr = regex_buf;
+ BEGIN(regex);
+}
+<regex>.|\n {
+ if (yytext[0] == regex_del) {
+ *regex_ptr = '\0';
+ BEGIN(regex_flags);
+ }
+ else {
+ *regex_ptr++ = yytext[0];
+ }
+}
+<regex_flags>i {
+ yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
+ BEGIN(INITIAL);
+ return T_REGEX_I;
+}
+<regex_flags>.|\n {
+ yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
+ yyless(0);
+ BEGIN(INITIAL);
+ return T_REGEX;
+}
+<regex_flags><<EOF>> {
+ yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
+ BEGIN(INITIAL);
+ return T_REGEX;
+}
+
+ /*
+ * Operators
+ */
+==? { return T_OP_STR_EQ; }
+"!=" { return T_OP_STR_NE; }
+"<" { return T_OP_STR_LT; }
+"<=" { return T_OP_STR_LE; }
+">" { return T_OP_STR_GT; }
+">=" { return T_OP_STR_GE; }
+"=~" { return T_OP_REG; }
+"!~" { return T_OP_NRE; }
+"and" { return T_OP_AND; }
+"&&" { return T_OP_AND; }
+"or" { return T_OP_OR; }
+"||" { return T_OP_OR; }
+"not" { return T_OP_NOT; }
+"!" { return T_OP_NOT; }
+"." { return T_OP_CONCAT; }
+"-in" { return T_OP_IN; }
+"-eq" { return T_OP_EQ; }
+"-ne" { return T_OP_NE; }
+"-ge" { return T_OP_GE; }
+"-le" { return T_OP_LE; }
+"-gt" { return T_OP_GT; }
+"-lt" { return T_OP_LT; }
+
+ /* for compatibility with ssl_expr */
+"lt" { return T_OP_LT; }
+"le" { return T_OP_LE; }
+"gt" { return T_OP_GT; }
+"ge" { return T_OP_GE; }
+"ne" { return T_OP_NE; }
+"eq" { return T_OP_EQ; }
+"in" { return T_OP_IN; }
+
+"-"[a-zA-Z_] {
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
+ return T_OP_UNARY;
+}
+
+"-"[a-zA-Z_][a-zA-Z_0-9] {
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
+ return T_OP_BINARY;
+}
+
+ /*
+ * Specials
+ */
+"true" { return T_TRUE; }
+"false" { return T_FALSE; }
+
+ /*
+ * Digits
+ */
+-?[0-9]+ {
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
+ return T_DIGIT;
+}
+
+ /*
+ * Identifiers
+ */
+[a-zA-Z][a-zA-Z0-9_]* {
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
+ return T_ID;
+}
+
+ /*
+ * These are parts of the grammar and are returned as is
+ */
+[(){},:] {
+ return yytext[0];
+}
+
+ /*
+ * Anything else is an error
+ */
+.|\n {
+ char c[2] = { yytext[0], '\0' };
+ char *msg = apr_psprintf(yyextra->pool, "Parse error near '%s'", c);
+ PERROR(msg);
+}
+
+%%
+
+