1{* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 *} 16 17(** 18 * @file ap_expr.h 19 * @brief Expression parser 20 * 21 * @defgroup AP_EXPR Expression parser 22 * @ingroup APACHE_CORE 23 * @{ 24 *) 25 26//#ifndef AP_EXPR_H 27//#define AP_EXPR_H 28 29//#include "httpd.h" 30//#include "http_config.h" 31//#include "ap_regex.h" 32 33 34//** A node in the expression parse tree */ 35//typedef struct ap_expr_node ap_expr_t; 36type 37 ap_expr_node_op_e = ( 38 op_NOP, 39 op_True, op_False, 40 op_Not, op_Or, op_And, 41 op_Comp, 42 op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE, op_IN, 43 op_REG, op_NRE, 44 op_STR_EQ, op_STR_NE, op_STR_LT, op_STR_LE, op_STR_GT, op_STR_GE, 45 op_Concat, 46 op_Digit, op_String, op_Regex, op_RegexBackref, 47 op_Var, 48 op_ListElement, 49 {* 50 * call external functions/operators. 51 * The info node contains the function pointer and some function specific 52 * info. 53 * For Binary operators, the Call node links to the Info node and the 54 * Args node, which in turn links to the left and right operand. 55 * For all other variants, the Call node links to the Info node and the 56 * argument. 57 *} 58 op_UnaryOpCall, op_UnaryOpInfo, 59 op_BinaryOpCall, op_BinaryOpInfo, op_BinaryOpArgs, 60 op_StringFuncCall, op_StringFuncInfo, 61 op_ListFuncCall, op_ListFuncInfo 62 ); 63 64 ap_expr_node = record {fpc -> from httpd-X-X-X/server/util_expr_private.h} 65 node_op: ap_expr_node_op_e; 66 node_arg1: Pointer; 67 node_arg2: Pointer; 68 end; 69 ap_expr_t = ap_expr_node; 70 Pap_expr_t = ^ap_expr_t; 71 72//** Struct describing a parsed expression */ 73 Pap_expr_info_t = ^ap_expr_info_t; 74 ap_expr_info_t = record 75 //** The root of the actual expression parse tree */ 76 root_node: Pap_expr_t; 77 {** The filename where the expression has been defined (for logging). 78 * May be NULL 79 *} 80 filename: PChar; 81 //** The line number where the expression has been defined (for logging). */ 82 line_number: cuint; 83 //** Flags relevant for the expression, see AP_EXPR_FLAG_* */ 84 flags: cuint; 85 //** The module that is used for loglevel configuration */ 86 module_index: Integer; 87 end; {ap_expr_info_t} 88 89{** Use ssl_expr compatibility mode (changes the meaning of the comparison 90 * operators) 91 *} 92const 93 AP_EXPR_FLAG_SSL_EXPR_COMPAT = 1; 94//** Don't add siginificant request headers to the Vary response header */ 95 AP_EXPR_FLAG_DONT_VARY = 2; 96{** Don't allow functions/vars that bypass the current request's access 97 * restrictions or would otherwise leak confidential information. 98 * Used by e.g. mod_include. 99 *} 100 AP_EXPR_FLAG_RESTRICTED = 4; 101//** Expression evaluates to a string, not to a bool */ 102 AP_EXPR_FLAG_STRING_RESULT = 8; 103 104 105{** 106 * Evaluate a parse tree, simple interface 107 * @param r The current request 108 * @param expr The expression to be evaluated 109 * @param err Where an error message should be stored 110 * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error 111 * @note err will be set to NULL on success, or to an error message on error 112 * @note request headers used during evaluation will be added to the Vary: 113 * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set. 114 *} 115//AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *expr, 116// const char **err); 117function ap_expr_exec(r: Prequest_rec; const expr: Pap_expr_info_t; err: PPChar): Integer; 118 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF} 119 external LibHTTPD name LibNamePrefix + 'ap_expr_exec' + LibSuff12; 120 121{** 122 * Evaluate a parse tree, with access to regexp backreference 123 * @param r The current request 124 * @param expr The expression to be evaluated 125 * @param nmatch size of the regex match vector pmatch 126 * @param pmatch information about regex matches 127 * @param source the string that pmatch applies to 128 * @param err Where an error message should be stored 129 * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error 130 * @note err will be set to NULL on success, or to an error message on error 131 * @note nmatch/pmatch/source can be used both to make previous matches 132 * available to ap_expr_exec_re and to use ap_expr_exec_re's matches 133 * later on. 134 * @note request headers used during evaluation will be added to the Vary: 135 * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set. 136 *} 137//AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *expr, 138// apr_size_t nmatch, ap_regmatch_t *pmatch, 139// const char **source, const char **err); 140function ap_expr_exec_re(r: Prequest_rec; const expr: Pap_expr_info_t; 141 nmatch: apr_size_t; pmatch: Pap_regmatch_t; 142 const source: PPChar; const err: PPChar): Integer; 143 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF} 144 external LibHTTPD name LibNamePrefix + 'ap_expr_exec_re' + LibSuff24; 145 146//** Context used during evaluation of a parse tree, created by ap_expr_exec */ 147type 148 Pap_expr_eval_ctx_t = ^ap_expr_eval_ctx_t; 149 ap_expr_eval_ctx_t = record 150 //** the current request */ 151 r : Prequest_rec; 152 //** the current connection */ 153 c : Pconn_rec; 154 //** the current connection */ 155 s : Pserver_rec; 156 //** the pool to use */ 157 p : Papr_pool_t; 158 //** where to store the error string */ 159 err : PPchar; 160 //** ap_expr_info_t for the expression */ 161 info : Pap_expr_info_t; 162 //** regex match information for back references */ 163 re_pmatch : Pap_regmatch_t; 164 //** size of the vector pointed to by re_pmatch */ 165 re_nmatch : apr_size_t; 166 //** the string corresponding to the re_pmatch */ 167 re_source : PPchar; 168 {** A string where the comma separated names of headers are stored 169 * to be later added to the Vary: header. If NULL, the caller is not 170 * interested in this information. 171 *} 172 vary_this : PPchar; 173 //** where to store the result string */ 174 result_string : PPchar; 175 //** Arbitrary context data provided by the caller for custom functions */ 176 data : pointer; 177 //** The current recursion level */ 178 reclvl : Integer; 179 end; {ap_expr_eval_ctx_t} 180 181{** 182 * Evaluate a parse tree, full featured version 183 * @param ctx The evaluation context with all data filled in 184 * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error 185 * @note *ctx->err will be set to NULL on success, or to an error message on 186 * error 187 * @note request headers used during evaluation will be added to the Vary: 188 * response header if ctx->vary_this is set. 189 *} 190//AP_DECLARE(int) ap_expr_exec_ctx(ap_expr_eval_ctx_t *ctx); 191function ap_expr_exec_ctx(ctx: Pap_expr_eval_ctx_t): Integer; 192 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF} 193 external LibHTTPD name LibNamePrefix + 'ap_expr_exec_ctx' + LibSuff4; 194 195{** 196 * Evaluate a parse tree of a string valued expression 197 * @param r The current request 198 * @param expr The expression to be evaluated 199 * @param err Where an error message should be stored 200 * @return The result string, NULL on error 201 * @note err will be set to NULL on success, or to an error message on error 202 * @note request headers used during evaluation will be added to the Vary: 203 * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set. 204 *} 205//AP_DECLARE(const char *) ap_expr_str_exec(request_rec *r, 206// const ap_expr_info_t *expr, 207// const char **err); 208function ap_expr_str_exec(r: Prequest_rec; 209 const expr: Pap_expr_info_t; 210 const err: PPChar): PChar; 211 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF} 212 external LibHTTPD name LibNamePrefix + 'ap_expr_str_exec' + LibSuff12; 213 214{** 215 * Evaluate a parse tree of a string valued expression 216 * @param r The current request 217 * @param expr The expression to be evaluated 218 * @param nmatch size of the regex match vector pmatch 219 * @param pmatch information about regex matches 220 * @param source the string that pmatch applies to 221 * @param err Where an error message should be stored 222 * @return The result string, NULL on error 223 * @note err will be set to NULL on success, or to an error message on error 224 * @note nmatch/pmatch/source can be used both to make previous matches 225 * available to ap_expr_exec_re and to use ap_expr_exec_re's matches 226 * later on. 227 * @note request headers used during evaluation will be added to the Vary: 228 * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set. 229 *} 230//AP_DECLARE(const char *) ap_expr_str_exec_re(request_rec *r, 231// const ap_expr_info_t *expr, 232// apr_size_t nmatch, 233// ap_regmatch_t *pmatch, 234// const char **source, 235// const char **err); 236function ap_expr_str_exec_re(r: Prequest_rec; 237 const expr: Pap_expr_info_t; 238 nmatch: apr_size_t; 239 pmatch: Pap_regmatch_t; 240 const source: PPChar; 241 const err: PPChar): PChar; 242 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF} 243 external LibHTTPD name LibNamePrefix + 'ap_expr_str_exec_re' + LibSuff24; 244 245 246{** 247 * The parser can be extended with variable lookup, functions, and 248 * and operators. 249 * 250 * During parsing, the parser calls the lookup function to resolve a 251 * name into a function pointer and an opaque context for the function. 252 * If the argument to a function or operator is constant, the lookup function 253 * may also parse that argument and store the parsed data in the context. 254 * 255 * The default lookup function is the hook ::ap_expr_lookup_default which just 256 * calls ap_run_expr_lookup. Modules can use it to make functions and 257 * variables generally available. 258 * 259 * An ap_expr consumer can also provide its own custom lookup function to 260 * modify the set of variables and functions that are available. The custom 261 * lookup function can in turn call 'ap_run_expr_lookup'. 262 *} 263 264{** Unary operator, takes one string argument and returns a bool value. 265 * The name must have the form '-z' (one letter only). 266 * @param ctx The evaluation context 267 * @param data An opaque context provided by the lookup hook function 268 * @param arg The (right) operand 269 * @return 0 or 1 270 *} 271//typedef int ap_expr_op_unary_t(ap_expr_eval_ctx_t *ctx, const void *data, 272// const char *arg); 273type 274 ap_expr_op_unary_t = function(ctx: Pap_expr_eval_ctx_t; const data: Pointer; 275 const arg: PChar): Integer; cdecl; 276 277{** Binary operator, takes two string arguments and returns a bool value. 278 * The name must have the form '-cmp' (at least two letters). 279 * @param ctx The evaluation context 280 * @param data An opaque context provided by the lookup hook function 281 * @param arg1 The left operand 282 * @param arg2 The right operand 283 * @return 0 or 1 284 *} 285//typedef int ap_expr_op_binary_t(ap_expr_eval_ctx_t *ctx, const void *data, 286// const char *arg1, const char *arg2); 287 ap_expr_op_binary_t = function(ctx: Pap_expr_eval_ctx_t; const data: Pointer; 288 const arg1: PChar; const arg2: PChar): Integer; cdecl; 289 290{** String valued function, takes a string argument and returns a string 291 * @param ctx The evaluation context 292 * @param data An opaque context provided by the lookup hook function 293 * @param arg The argument 294 * @return The functions result string, may be NULL for 'empty string' 295 *} 296//typedef const char *(ap_expr_string_func_t)(ap_expr_eval_ctx_t *ctx, 297// const void *data, 298// const char *arg); 299 ap_expr_string_func_t = function(ctx: Pap_expr_eval_ctx_t; 300 const data: Pointer; 301 const arg: PChar): PChar; cdecl; 302 303{** List valued function, takes a string argument and returns a list of strings 304 * Can currently only be called following the builtin '-in' operator. 305 * @param ctx The evaluation context 306 * @param data An opaque context provided by the lookup hook function 307 * @param arg The argument 308 * @return The functions result list of strings, may be NULL for 'empty array' 309 *} 310//typedef apr_array_header_t *(ap_expr_list_func_t)(ap_expr_eval_ctx_t *ctx, 311// const void *data, 312// const char *arg); 313 ap_expr_list_func_t = function(ctx: Pap_expr_eval_ctx_t; 314 const data: Pointer; 315 const arg: PChar): Papr_array_header_t; 316 317{** Variable lookup function, takes no argument and returns a string 318 * @param ctx The evaluation context 319 * @param data An opaque context provided by the lookup hook function 320 * @return The expanded variable 321 *} 322//typedef const char *(ap_expr_var_func_t)(ap_expr_eval_ctx_t *ctx, 323// const void *data); 324 ap_expr_var_func_t = function(ctx: Pap_expr_eval_ctx_t; 325 const data: Pointer): PChar; cdecl; 326 327const 328 AP_EXPR_FUNC_VAR = 0; 329 AP_EXPR_FUNC_STRING = 1; 330 AP_EXPR_FUNC_LIST = 2; 331 AP_EXPR_FUNC_OP_UNARY = 3; 332 AP_EXPR_FUNC_OP_BINARY = 4; 333 334//** parameter struct passed to the lookup hook functions */ 335type 336 Pap_expr_lookup_parms = ^ap_expr_lookup_parms; 337 ap_expr_lookup_parms = record 338 //** type of the looked up object */ 339 type_: Integer; 340//#define AP_EXPR_FUNC_VAR 0 {fpc -> consts are moved up} 341//#define AP_EXPR_FUNC_STRING 1 342//#define AP_EXPR_FUNC_LIST 2 343//#define AP_EXPR_FUNC_OP_UNARY 3 344//#define AP_EXPR_FUNC_OP_BINARY 4 345 //** name of the looked up object */ 346 name: PChar; 347 348 flags: Integer; 349 350 pool: Papr_pool_t; 351 ptemp: Papr_pool_t; 352 353 //** where to store the function pointer */ 354 func: PPointer; 355 //** where to store the function's context */ 356 data: PPointer; 357 //** where to store the error message (if any) */ 358 err: PPChar; 359 360 {** arg for pre-parsing (only if a simple string). 361 * For binary ops, this is the right argument. *} 362 arg: PChar; 363 end; {ap_expr_lookup_parms} 364 365{** Function for looking up the provider function for a variable, operator 366 * or function in an expression. 367 * @param parms The parameter struct, also determins where the result is 368 * stored. 369 * @return OK on success, 370 * !OK on failure, 371 * DECLINED if the requested name is not handled by this function 372 *} 373//typedef int (ap_expr_lookup_fn_t)(ap_expr_lookup_parms *parms); 374type 375 ap_expr_lookup_fn_t = function(parms: ap_expr_lookup_parms): Integer; cdecl; 376 377{** Default lookup function which just calls ap_run_expr_lookup(). 378 * ap_run_expr_lookup cannot be used directly because it has the wrong 379 * calling convention under Windows. 380 *} 381//AP_DECLARE_NONSTD(int) ap_expr_lookup_default(ap_expr_lookup_parms *parms); 382function ap_expr_lookup_default(parms: Pap_expr_lookup_parms): Integer; cdecl; 383 external LibHTTPD name LibNamePrefix + 'ap_expr_lookup_default'; 384 385//AP_DECLARE_HOOK(int, expr_lookup, (ap_expr_lookup_parms *parms)) 386{macro ignored for now} 387 388{** 389 * Parse an expression into a parse tree 390 * @param pool Pool 391 * @param ptemp temp pool 392 * @param info The ap_expr_info_t struct (with values filled in) 393 * @param expr The expression string to parse 394 * @param lookup_fn The lookup function to use, NULL for default 395 * @return NULL on success, error message on error. 396 * A pointer to the resulting parse tree will be stored in 397 * info->root_node. 398 *} 399//AP_DECLARE(const char *) ap_expr_parse(apr_pool_t *pool, apr_pool_t *ptemp, 400// ap_expr_info_t *info, const char *expr, 401// ap_expr_lookup_fn_t *lookup_fn); 402function ap_expr_parse(pool, ptemp: Papr_pool_t; 403 info: Pap_expr_info_t; 404 const expr: PChar; 405 lookup_fn: ap_expr_lookup_fn_t): PChar; 406 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF} 407 external LibHTTPD name LibNamePrefix + 'ap_expr_parse' + LibSuff20; 408 409{** 410 * High level interface to ap_expr_parse that also creates ap_expr_info_t and 411 * uses info from cmd_parms to fill in most of it. 412 * @param cmd The cmd_parms struct 413 * @param expr The expression string to parse 414 * @param flags The flags to use, see AP_EXPR_FLAG_* 415 * @param err Set to NULL on success, error message on error 416 * @param lookup_fn The lookup function used to lookup vars, functions, and 417 * operators 418 * @param module_index The module_index to set for the expression 419 * @return The parsed expression 420 * @note Usually ap_expr_parse_cmd() should be used 421 *} 422//AP_DECLARE(ap_expr_info_t *) ap_expr_parse_cmd_mi(const cmd_parms *cmd, 423// const char *expr, 424// unsigned int flags, 425// const char **err, 426// ap_expr_lookup_fn_t *lookup_fn, 427// int module_index); 428function ap_expr_parse_cmd_mi(cmd: Pcmd_parms; 429 const expr: PChar; 430 flags: cuint; 431 const err: PPChar; 432 lookup_fn: ap_expr_lookup_fn_t; 433 module_index: Integer): PChar; 434 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF} 435 external LibHTTPD name LibNamePrefix + 'ap_expr_parse_cmd_mi' + LibSuff24; 436 437{** 438 * Convenience wrapper for ap_expr_parse_cmd_mi() that sets 439 * module_index = APLOG_MODULE_INDEX 440 *} 441//#define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn) \ 442// ap_expr_parse_cmd_mi(cmd, expr, flags, err, lookup_fn, APLOG_MODULE_INDEX) 443 444 {** 445 * Internal initialisation of ap_expr (for httpd internal use) 446 *} 447//void ap_expr_init(apr_pool_t *pool); 448 449//#endif /* AP_EXPR_H */ 450//** @} */ 451