util_expr_eval.c revision c5ddb84603794117165e49e54e97a8a9e12ce0af
6ec499054450c5e0fd69d78961deef46985ba363Brian Wellington/* Licensed to the Apache Software Foundation (ASF) under one or more
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * contributor license agreements. See the NOTICE file distributed with
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * this work for additional information regarding copyright ownership.
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * The ASF licenses this file to You under the Apache License, Version 2.0
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * (the "License"); you may not use this file except in compliance with
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * the License. You may obtain a copy of the License at
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * http://www.apache.org/licenses/LICENSE-2.0
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * Unless required by applicable law or agreed to in writing, software
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * distributed under the License is distributed on an "AS IS" BASIS,
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * See the License for the specific language governing permissions and
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * limitations under the License.
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson * ap_expr_eval.c, based on ssl_expr_eval.c from mod_ssl
#include "util_varbuf.h"
#include "util_expr_private.h"
#include "util_md5.h"
#include "apr_lib.h"
#include "apr_fnmatch.h"
#include "apr_base64.h"
#include "apr_sha1.h"
#include "apr_version.h"
#include "apr_strings.h"
#include "apr_strmatch.h"
#include "apr_escape.h"
const void *data);
#ifdef AP_EXPR_DEBUG
return result;
case op_Digit:
case op_String:
case op_Var:
case op_Concat:
if (!*s1)
else if (!*s2)
case op_StringFuncCall: {
case op_RegexBackref: {
if (!result)
return result;
const void *data)
int len;
if (len == 0)
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: {
int result;
return result;
return !result;
for (i = 0; i < n1; i++) {
case op_EQ:
case op_STR_EQ:
case op_NE:
case op_STR_NE:
case op_LT:
case op_STR_LT:
case op_LE:
case op_STR_LE:
case op_GT:
case op_STR_GT:
case op_GE:
case op_STR_GE:
int rc;
#ifdef AP_EXPR_DEBUG
return NULL;
const char *expr,
unsigned int flags,
const char **err,
int module_index)
if (*err)
return NULL;
return info;
return node;
if (arg) {
case op_String:
case op_ListElement:
return NULL;
return info;
if (!info)
return NULL;
if (!info)
return NULL;
if (!info)
return NULL;
arg2);
if (!info)
return NULL;
if (!node)
return NULL;
return node;
#ifdef AP_EXPR_DEBUG
switch (e->node_op) {
case op_NOP:
case op_True:
case op_False:
char *name;
switch (e->node_op) {
ap_assert(0);
case op_UnaryOpCall:
case op_BinaryOpCall:
case op_BinaryOpArgs:
char *name;
switch (e->node_op) {
ap_assert(0);
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) {
ap_assert(0);
case op_Digit:
case op_String:
char *name;
switch (e->node_op) {
ap_assert(0);
case op_Var:
case op_StringFuncInfo:
case op_UnaryOpInfo:
case op_BinaryOpInfo:
case op_ListFuncInfo:
char *name;
switch (e->node_op) {
ap_assert(0);
case op_Regex:
case op_RegexBackref:
return result;
case op_True:
goto out;
case op_False:
goto out;
case op_Not:
case op_Or:
goto out;
goto out;
case op_And:
goto out;
goto out;
case op_UnaryOpCall:
goto out;
case op_BinaryOpCall:
goto out;
case op_Comp:
goto out;
goto out;
out:
return result;
const char **err)
int rc;
return rc;
ctx.r = r;
if (!pmatch) {
const char **source,
const char **err)
const char *result;
ctx.r = r;
if (!pmatch) {
if (rc > 0)
return result;
else if (rc < 0)
return NULL;
ap_assert(0);
return NULL;
const char **err)
NULL);
const char *arg)
apr_table_t *t;
if (!ctx->r)
const char *arg)
const char *res;
if (ctx->r) {
return res;
return res;
const char *arg)
const char *arg)
return result;
const char *arg)
return result;
const char *arg)
const char *arg)
const char *arg)
const char *arg)
char *out;
return out;
const char *arg)
const char *arg)
return !OK;
return OK;
const char *repl;
char *arg)
char *buf;
if (len == 0) {
offset = 0;
return buf;
char *arg)
char *arg)
const char *arg)
return result;
return FALSE;
switch (name[0]) {
return TRUE;
ap_assert(0);
return FALSE;
#if !defined(OS2)
return TRUE;
return FALSE;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return rc;
return FALSE;
return rc;
static const char *conn_var_names[] = {
switch (index) {
#if APR_HAVE_IPV6
return c->log_id;
return c->client_ip;
ap_assert(0);
return NULL;
static const char *request_var_names[] = {
switch (index) {
return r->method;
return ap_http_scheme(r);
return r->uri;
return r->filename;
return ap_get_remote_logname(r);
return r->user;
return ap_get_server_name_for_url(r);
return r->protocol;
return r->filename;
return r->path_info;
return r->args;
return ap_document_root(r);
return r->ap_auth_type;
return r->the_request;
return r->content_type;
return r->handler;
return r->log_id;
return result;
return result;
return r->uri;
return ap_context_prefix(r);
return ap_context_document_root(r);
return r->useragent_ip;
switch (r->proto_num) {
ap_assert(0);
return NULL;
static const char *req_header_var_names[] = {
static const char *req_header_header_names[] = {
const char *name;
if (!ctx->r)
static const char *misc_var_names[] = {
switch (index) {
return ap_get_server_banner();
ap_assert(0);
return NULL;
const char *mask;
return !OK;
if (mask) {
mask++;
return !OK;
return OK;
const char *arg2)
return FALSE;
if (!ctx->r)
return FALSE;
switch (arg[0]) {
return FALSE;
return TRUE;
struct expr_provider_single {
const void *func;
const char *name;
int restricted;
struct expr_provider_multi {
const void *func;
const char **names;
case AP_EXPR_FUNC_VAR: {
while (*name) {
return OK;
name++;
prov++;
case AP_EXPR_FUNC_STRING:
case AP_EXPR_FUNC_OP_UNARY:
case AP_EXPR_FUNC_OP_BINARY: {
case AP_EXPR_FUNC_STRING:
case AP_EXPR_FUNC_OP_UNARY:
case AP_EXPR_FUNC_OP_BINARY:
ap_assert(0);
int match;
if (match) {
return !OK;
return OK;
prov++;
return DECLINED;
const char *type;
case AP_EXPR_FUNC_VAR:
case AP_EXPR_FUNC_STRING:
case AP_EXPR_FUNC_LIST:
case AP_EXPR_FUNC_OP_UNARY:
case AP_EXPR_FUNC_OP_BINARY:
return !OK;
return !OK;
return OK;