You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2010/11/06 15:31:17 UTC
svn commit: r1032073 [1/3] - in /httpd/httpd/trunk: ./ include/ modules/aaa/
modules/filters/ modules/metadata/ modules/ssl/ server/
Author: sf
Date: Sat Nov 6 14:31:16 2010
New Revision: 1032073
URL: http://svn.apache.org/viewvc?rev=1032073&view=rev
Log:
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.
The Netware and Windows build files still need to be adjusted
Added:
httpd/httpd/trunk/server/util_expr_eval.c
- copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
httpd/httpd/trunk/server/util_expr_parse.c
- copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.c
httpd/httpd/trunk/server/util_expr_parse.h
- copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.h
httpd/httpd/trunk/server/util_expr_parse.y
- copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
httpd/httpd/trunk/server/util_expr_private.h
- copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr.h
httpd/httpd/trunk/server/util_expr_scan.c
- copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_scan.c
httpd/httpd/trunk/server/util_expr_scan.l
- copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
Removed:
httpd/httpd/trunk/modules/ssl/ssl_expr.c
httpd/httpd/trunk/modules/ssl/ssl_expr.h
httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
httpd/httpd/trunk/modules/ssl/ssl_expr_parse.c
httpd/httpd/trunk/modules/ssl/ssl_expr_parse.h
httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
httpd/httpd/trunk/modules/ssl/ssl_expr_scan.c
httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
httpd/httpd/trunk/server/util_expr.c
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/buildconf
httpd/httpd/trunk/include/ap_expr.h
httpd/httpd/trunk/include/ap_mmn.h
httpd/httpd/trunk/include/http_core.h
httpd/httpd/trunk/modules/aaa/mod_authz_core.c
httpd/httpd/trunk/modules/filters/mod_filter.c
httpd/httpd/trunk/modules/metadata/mod_headers.c
httpd/httpd/trunk/modules/ssl/Makefile.in
httpd/httpd/trunk/modules/ssl/config.m4
httpd/httpd/trunk/modules/ssl/mod_ssl.c
httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c
httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c
httpd/httpd/trunk/modules/ssl/ssl_private.h
httpd/httpd/trunk/server/Makefile.in
httpd/httpd/trunk/server/core.c
httpd/httpd/trunk/server/main.c
httpd/httpd/trunk/server/request.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sat Nov 6 14:31:16 2010
@@ -6,6 +6,12 @@ Changes with Apache 2.3.9
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]
Modified: httpd/httpd/trunk/buildconf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/buildconf?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/buildconf (original)
+++ httpd/httpd/trunk/buildconf Sat Nov 6 14:31:16 2010
@@ -226,15 +226,15 @@ if [ -f `which cut` ]; then
> 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
Modified: httpd/httpd/trunk/include/ap_expr.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_expr.h?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_expr.h (original)
+++ httpd/httpd/trunk/include/ap_expr.h Sat Nov 6 14:31:16 2010
@@ -23,128 +23,193 @@
#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;
+ /** 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 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;
+/**
+ * Evaluate a parse tree
+ * @param r The current request
+ * @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_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 {
- const char *source;
- const char *rexp;
- apr_size_t nsub;
- ap_regmatch_t match[AP_MAX_REG_MATCH];
- int have_match;
-} backref_t;
+ /** 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;
-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
+ * 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'.
*/
-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
- */
-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);
-/**
- * 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
- */
-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);
+
+/** 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'
+ */
+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
}
Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Sat Nov 6 14:31:16 2010
@@ -277,12 +277,16 @@
* 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 */
Modified: httpd/httpd/trunk/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_core.h?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_core.h (original)
+++ httpd/httpd/trunk/include/http_core.h Sat Nov 6 14:31:16 2010
@@ -534,7 +534,7 @@ typedef struct {
#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;
Modified: httpd/httpd/trunk/modules/aaa/mod_authz_core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_authz_core.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/aaa/mod_authz_core.c (original)
+++ httpd/httpd/trunk/modules/aaa/mod_authz_core.c Sat Nov 6 14:31:16 2010
@@ -988,20 +988,22 @@ static authz_status expr_check_authoriza
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";
Modified: httpd/httpd/trunk/modules/filters/mod_filter.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_filter.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_filter.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_filter.c Sat Nov 6 14:31:16 2010
@@ -36,7 +36,7 @@ module AP_MODULE_DECLARE_DATA filter_mod
* (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;
@@ -134,7 +134,7 @@ static int filter_lookup(ap_filter_t *f,
{
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;
@@ -146,11 +146,12 @@ static int filter_lookup(ap_filter_t *f,
/* 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) {
@@ -402,8 +403,8 @@ static const char *filter_provider(cmd_p
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);
@@ -426,9 +427,11 @@ static const char *filter_provider(cmd_p
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));
@@ -545,7 +548,7 @@ static const char *filter_bytype1(cmd_pa
*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);
Modified: httpd/httpd/trunk/modules/metadata/mod_headers.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/metadata/mod_headers.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/metadata/mod_headers.c (original)
+++ httpd/httpd/trunk/modules/metadata/mod_headers.c Sat Nov 6 14:31:16 2010
@@ -130,7 +130,7 @@ typedef struct {
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*/
@@ -398,7 +398,7 @@ static APR_INLINE const char *header_ino
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)
@@ -491,10 +491,12 @@ static APR_INLINE const char *header_ino
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);
}
}
}
@@ -645,12 +647,12 @@ static void do_headers_fixup(request_rec
}
/* 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;
Modified: httpd/httpd/trunk/modules/ssl/Makefile.in
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/Makefile.in?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/Makefile.in (original)
+++ httpd/httpd/trunk/modules/ssl/Makefile.in Sat Nov 6 14:31:16 2010
@@ -18,20 +18,3 @@
#
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
Modified: httpd/httpd/trunk/modules/ssl/config.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/config.m4?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/config.m4 (original)
+++ httpd/httpd/trunk/modules/ssl/config.m4 Sat Nov 6 14:31:16 2010
@@ -35,10 +35,6 @@ ssl_engine_mutex.lo dnl
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
Modified: httpd/httpd/trunk/modules/ssl/mod_ssl.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/mod_ssl.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/mod_ssl.c (original)
+++ httpd/httpd/trunk/modules/ssl/mod_ssl.c Sat Nov 6 14:31:16 2010
@@ -565,11 +565,6 @@ static void ssl_register_hooks(apr_pool_
&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 = {
Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_config.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_config.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_config.c Sat Nov 6 14:31:16 2010
@@ -1147,17 +1147,21 @@ const char *ssl_cmd_SSLRequire(cmd_parms
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;
}
Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c Sat Nov 6 14:31:16 2010
@@ -302,7 +302,6 @@ int ssl_hook_Access(request_rec *r)
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;
@@ -900,17 +899,13 @@ int ssl_hook_Access(request_rec *r)
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");
@@ -1282,54 +1277,6 @@ const authz_provider ssl_authz_provider_
};
-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,
-};
-
/* _________________________________________________________________
**
Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c Sat Nov 6 14:31:16 2010
@@ -29,6 +29,7 @@
-- Unknown */
#include "ssl_private.h"
#include "mod_ssl.h"
+#include "ap_expr.h"
#include "apr_time.h"
@@ -62,6 +63,45 @@ static const char var_interface[] = "mod
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;
@@ -84,6 +124,8 @@ void ssl_var_register(apr_pool_t *p)
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. */
@@ -984,3 +1026,4 @@ static const char *ssl_var_log_handler_x
return result;
}
+
Modified: httpd/httpd/trunk/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_private.h?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_private.h Sat Nov 6 14:31:16 2010
@@ -55,9 +55,38 @@
#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
@@ -272,8 +301,8 @@ typedef enum {
* Define the SSL requirement structure
*/
typedef struct {
- char *cpExpr;
- ssl_expr *mpExpr;
+ char *cpExpr;
+ ap_expr_info_t *mpExpr;
} ssl_require_t;
/**
@@ -617,7 +646,6 @@ void ssl_hook_ConfigTest(apr_poo
/** 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);
Modified: httpd/httpd/trunk/server/Makefile.in
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/Makefile.in?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/server/Makefile.in (original)
+++ httpd/httpd/trunk/server/Makefile.in Sat Nov 6 14:31:16 2010
@@ -12,9 +12,10 @@ LTLIBRARY_SOURCES = \
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
@@ -83,3 +84,19 @@ httpd.exp: exports.c export_vars.h
@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
+
Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Sat Nov 6 14:31:16 2010
@@ -1986,7 +1986,7 @@ static const char *ifsection(cmd_parms *
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;
@@ -2012,9 +2012,9 @@ static const char *ifsection(cmd_parms *
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);
@@ -4133,6 +4133,7 @@ static void register_hooks(apr_pool_t *p
{
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
Modified: httpd/httpd/trunk/server/main.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/main.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/server/main.c (original)
+++ httpd/httpd/trunk/server/main.c Sat Nov 6 14:31:16 2010
@@ -39,7 +39,6 @@
#include "apr_uri.h"
#include "util_ebcdic.h"
#include "ap_mpm.h"
-#include "ap_expr.h"
#if APR_HAVE_UNISTD_H
#include <unistd.h>
@@ -472,9 +471,6 @@ int main(int argc, const char * const ar
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");
Modified: httpd/httpd/trunk/server/request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/request.c?rev=1032073&r1=1032072&r2=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/server/request.c (original)
+++ httpd/httpd/trunk/server/request.c Sat Nov 6 14:31:16 2010
@@ -1529,13 +1529,13 @@ AP_DECLARE(int) ap_file_walk(request_rec
* 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;
}
}
Copied: httpd/httpd/trunk/server/util_expr_eval.c (from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c)
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util_expr_eval.c?p2=httpd/httpd/trunk/server/util_expr_eval.c&p1=httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c&r1=1032057&r2=1032073&rev=1032073&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c (original)
+++ httpd/httpd/trunk/server/util_expr_eval.c Sat Nov 6 14:31:16 2010
@@ -15,276 +15,1010 @@
*/
/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_expr_eval.c
- * Expression Evaluation
+ * ap_expr_eval.c, based on ssl_expr_eval.c from mod_ssl
*/
- /* ``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)
+#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_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;
+ 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 BOOL ssl_expr_eval_comp(request_rec *r, ssl_expr *node, const char **err)
+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: {
- 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);
+ 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: {
- 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);
+ 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: {
- 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);
+ 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: {
- 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);
+ 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: {
- 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);
+ 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: {
- 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);
+ 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: {
- 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;
+ 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;
}
- } while (e2 != NULL);
- return found;
+ }
+ return 0;
}
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);
+ 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: {
- 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);
+ 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: {
- *err = "Internal evaluation error: Unknown expression node";
- return FALSE;
+ *ctx->err = "Internal evaluation error: Unknown expression node";
+ return -1;
}
}
}
-static char *ssl_expr_eval_word(request_rec *r, ssl_expr *node, const char **err)
+/* 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_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 "";
+ 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: {
- *err = "Internal evaluation error: Unknown expression node";
+ *ctx->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)
+
+AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *info, 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;
- }
+ 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 char *ssl_expr_eval_func_file(request_rec *r, char *filename, const char **err)
+static const char *unescape_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg)
{
- 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";
+ 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;
}
- 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);
+}
+
+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;
}
- 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 "";
+ 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++;
}
- buf[len] = NUL;
+ break;
}
- apr_file_close(fp);
- return buf;
+ default:
+ break;
+ }
+ return DECLINED;
}
-/* 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)
+static int expr_lookup_not_found(ap_expr_lookup_parms *parms)
{
- int i, n1, n2;
+ const char *type;
- 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;
+ 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;
}
- return 0;
+ *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);
}
+
Re: svn commit: r1032073 [1/3] - in /httpd/httpd/trunk: ./ include/ modules/aaa/ modules/filters/ modules/metadata/ modules/ssl/ server/
Posted by Stefan Fritsch <sf...@sfritsch.de>.
On Monday 08 November 2010, Ruediger Pluem wrote:
> On 11/06/2010 03:31 PM, sf@apache.org wrote:
> > Author: sf
> > Date: Sat Nov 6 14:31:16 2010
> > New Revision: 1032073
> >
> > URL: http://svn.apache.org/viewvc?rev=1032073&view=rev
> > Log:
> > 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.
> > - ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl-
require",
> > - AUTHZ_PROVIDER_VERSION,
> > - &ssl_authz_provider_sslrequire,
> > - AP_AUTH_INTERNAL_PER_CONF);
> > -
>
> What is the substitute for ssl-require?
The expr provider in mod_authz_core. Since the syntax of ap_expr is
now nearly the same as the syntax of ssl_expr, I don't think we need a
separate ssl_expr authz provider. Of course, if anyone thinks it would
be useful, it's easy to add again.
Re: svn commit: r1032073 [1/3] - in /httpd/httpd/trunk: ./ include/
modules/aaa/ modules/filters/ modules/metadata/ modules/ssl/ server/
Posted by Ruediger Pluem <rp...@apache.org>.
On 11/06/2010 03:31 PM, sf@apache.org wrote:
> Author: sf
> Date: Sat Nov 6 14:31:16 2010
> New Revision: 1032073
>
> URL: http://svn.apache.org/viewvc?rev=1032073&view=rev
> Log:
> 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.
>
> The Netware and Windows build files still need to be adjusted
>
> Added:
> httpd/httpd/trunk/server/util_expr_eval.c
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
> httpd/httpd/trunk/server/util_expr_parse.c
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.c
> httpd/httpd/trunk/server/util_expr_parse.h
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.h
> httpd/httpd/trunk/server/util_expr_parse.y
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
> httpd/httpd/trunk/server/util_expr_private.h
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr.h
> httpd/httpd/trunk/server/util_expr_scan.c
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_scan.c
> httpd/httpd/trunk/server/util_expr_scan.l
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
> Removed:
> httpd/httpd/trunk/modules/ssl/ssl_expr.c
> httpd/httpd/trunk/modules/ssl/ssl_expr.h
> httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
> httpd/httpd/trunk/modules/ssl/ssl_expr_parse.c
> httpd/httpd/trunk/modules/ssl/ssl_expr_parse.h
> httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
> httpd/httpd/trunk/modules/ssl/ssl_expr_scan.c
> httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
> httpd/httpd/trunk/server/util_expr.c
> Modified:
> httpd/httpd/trunk/CHANGES
> httpd/httpd/trunk/buildconf
> httpd/httpd/trunk/include/ap_expr.h
> httpd/httpd/trunk/include/ap_mmn.h
> httpd/httpd/trunk/include/http_core.h
> httpd/httpd/trunk/modules/aaa/mod_authz_core.c
> httpd/httpd/trunk/modules/filters/mod_filter.c
> httpd/httpd/trunk/modules/metadata/mod_headers.c
> httpd/httpd/trunk/modules/ssl/Makefile.in
> httpd/httpd/trunk/modules/ssl/config.m4
> httpd/httpd/trunk/modules/ssl/mod_ssl.c
> httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
> httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c
> httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c
> httpd/httpd/trunk/modules/ssl/ssl_private.h
> httpd/httpd/trunk/server/Makefile.in
> httpd/httpd/trunk/server/core.c
> httpd/httpd/trunk/server/main.c
> httpd/httpd/trunk/server/request.c
>
> Modified: httpd/httpd/trunk/modules/ssl/mod_ssl.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/mod_ssl.c?rev=1032073&r1=1032072&r2=1032073&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/ssl/mod_ssl.c (original)
> +++ httpd/httpd/trunk/modules/ssl/mod_ssl.c Sat Nov 6 14:31:16 2010
> @@ -565,11 +565,6 @@ static void ssl_register_hooks(apr_pool_
> &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);
> -
What is the substitute for ssl-require?
> }
>
> module AP_MODULE_DECLARE_DATA ssl_module = {
>
Regards
RĂ¼diger
Re: svn commit: r1032073 [1/3] - in /httpd/httpd/trunk: ./ include/
modules/aaa/ modules/filters/ modules/metadata/ modules/ssl/ server/
Posted by Ruediger Pluem <rp...@apache.org>.
On 11/06/2010 03:31 PM, sf@apache.org wrote:
> Author: sf
> Date: Sat Nov 6 14:31:16 2010
> New Revision: 1032073
>
> URL: http://svn.apache.org/viewvc?rev=1032073&view=rev
> Log:
> 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.
>
> The Netware and Windows build files still need to be adjusted
>
> Added:
> httpd/httpd/trunk/server/util_expr_eval.c
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
> httpd/httpd/trunk/server/util_expr_parse.c
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.c
> httpd/httpd/trunk/server/util_expr_parse.h
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.h
> httpd/httpd/trunk/server/util_expr_parse.y
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
> httpd/httpd/trunk/server/util_expr_private.h
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr.h
> httpd/httpd/trunk/server/util_expr_scan.c
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_scan.c
> httpd/httpd/trunk/server/util_expr_scan.l
> - copied, changed from r1032057, httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
> Removed:
> httpd/httpd/trunk/modules/ssl/ssl_expr.c
> httpd/httpd/trunk/modules/ssl/ssl_expr.h
> httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
> httpd/httpd/trunk/modules/ssl/ssl_expr_parse.c
> httpd/httpd/trunk/modules/ssl/ssl_expr_parse.h
> httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
> httpd/httpd/trunk/modules/ssl/ssl_expr_scan.c
> httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
> httpd/httpd/trunk/server/util_expr.c
> Modified:
> httpd/httpd/trunk/CHANGES
> httpd/httpd/trunk/buildconf
> httpd/httpd/trunk/include/ap_expr.h
> httpd/httpd/trunk/include/ap_mmn.h
> httpd/httpd/trunk/include/http_core.h
> httpd/httpd/trunk/modules/aaa/mod_authz_core.c
> httpd/httpd/trunk/modules/filters/mod_filter.c
> httpd/httpd/trunk/modules/metadata/mod_headers.c
> httpd/httpd/trunk/modules/ssl/Makefile.in
> httpd/httpd/trunk/modules/ssl/config.m4
> httpd/httpd/trunk/modules/ssl/mod_ssl.c
> httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
> httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c
> httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c
> httpd/httpd/trunk/modules/ssl/ssl_private.h
> httpd/httpd/trunk/server/Makefile.in
> httpd/httpd/trunk/server/core.c
> httpd/httpd/trunk/server/main.c
> httpd/httpd/trunk/server/request.c
>
The following warning is created:
util_expr_scan.c:2258: warning: 'yy_top_state' defined but not used
Regards
RĂ¼diger