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