Coverage Report

Created: 2024-02-25 06:34

/src/kamailio/src/core/rvalue.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2008 iptelorg GmbH
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
 */
16
17
/**
18
 * @file
19
 * @brief Kamailio core :: rvalue expressions
20
 * @ingroup core
21
 * Module: \ref core
22
 */
23
24
/** special defines:
25
 *
26
 *  UNDEF_EQ_* - how to behave when undef is on the right side of a generic
27
 *               compare operator
28
 *  UNDEF_EQ_ALWAYS_FALSE:  undef  == something  is always false
29
 *  UNDEF_EQ_UNDEF_TRUE  :  undef == something false except for undef==undef
30
 *                          which is true
31
 *  no UNDEF_EQ* define  :  undef == expr => convert undef to typeof(expr)
32
 *                          and perform normal ==. undef == undef will be
33
 *                          converted to string and it will be true
34
 *                          ("" == "")
35
 * NOTE: expr == undef, with defined(expr) is always evaluated this way:
36
 *       expr == (type_of(expr))undef
37
 *  RV_STR2INT_VERBOSE_ERR - if a string conversion to int fails, log (L_WARN)
38
 *                           the string that caused it (only the string, not
39
 *                           the expression position).
40
 *  RV_STR2INT_ERR         - if a string conversion to int fails, don't ignore
41
 *                           the error (return error).
42
 *  RVAL_GET_INT_ERR_WARN  - if a conversion to int fails, log a warning with
43
 *                           the expression position.
44
 *                           Depends on RV_STR2INT_ERR.
45
 *  RVAL_GET_INT_ERR_IGN   - if a conversion to int fails, ignore the error
46
 *                           (the result will be 0). Can be combined with
47
 *                           RVAL_GET_INT_ERR_WARN.
48
 *                           Depends on RV_STR2INT_ERR.
49
 */
50
51
52
#include "rvalue.h"
53
54
#include <stdlib.h> /* abort() */
55
56
/* if defined warn when str2int conversions fail */
57
#define RV_STR2INT_VERBOSE_ERR
58
59
/* if defined rval_get_int will fail if str2int conversion fail
60
 * (else convert to 0) */
61
#define RV_STR2INT_ERR
62
63
/* if a rval_get_int fails (conversion to int), warn
64
 * Depends on RV_STR2INT_ERR.
65
 */
66
#define RVAL_GET_INT_ERR_WARN
67
68
/* if a rval_get_int fails, ignore it (expression evaluation will not fail,
69
 * the int conversion will result in 0).
70
 * Can be combined with RVAL_GET_INT_ERR_WARN.
71
 * Depends on RV_STR2INT_ERR.
72
 */
73
#define RVAL_GET_INT_ERR_IGN
74
75
/* minimum size alloc'ed for STR RVs (to accommodate
76
 * strops without reallocs) */
77
0
#define RV_STR_EXTRA 80
78
79
0
#define rv_ref(rv) ((rv)->refcnt++)
80
81
/** unref rv and returns true if 0 */
82
0
#define rv_unref(rv) ((--(rv)->refcnt) == 0)
83
84
85
/* control return code evaluation mode */
86
int ksr_return_mode = 0;
87
88
inline static void rval_force_clean(struct rvalue *rv)
89
0
{
90
0
  if(rv->flags & RV_CNT_ALLOCED_F) {
91
0
    switch(rv->type) {
92
0
      case RV_STR:
93
0
        pkg_free(rv->v.s.s);
94
0
        rv->v.s.s = 0;
95
0
        rv->v.s.len = 0;
96
0
        break;
97
0
      default:
98
0
        LM_BUG("RV_CNT_ALLOCED_F not supported for type %d\n",
99
0
            rv->type);
100
0
    }
101
0
    rv->flags &= ~RV_CNT_ALLOCED_F;
102
0
  }
103
0
  if(rv->flags & RV_RE_ALLOCED_F) {
104
0
    if(rv->v.re.regex) {
105
0
      if(unlikely(rv->type != RV_STR || !(rv->flags & RV_RE_F))) {
106
0
        LM_BUG("RV_RE_ALLOCED_F not supported for type %d or "
107
0
             "bad flags %x\n",
108
0
            rv->type, rv->flags);
109
0
      }
110
0
      regfree(rv->v.re.regex);
111
0
      pkg_free(rv->v.re.regex);
112
0
      rv->v.re.regex = 0;
113
0
    }
114
0
    rv->flags &= ~(RV_RE_ALLOCED_F | RV_RE_F);
115
0
  }
116
0
}
117
118
119
static inline void rval_destroy_helper(struct rvalue *rv, int allocated)
120
0
{
121
0
  if(rv && rv_unref(rv)) {
122
0
    rval_force_clean(rv);
123
    /* still an un-regfreed RE ? */
124
0
    if((rv->flags & RV_RE_F) && rv->v.re.regex) {
125
0
      if(unlikely(rv->type != RV_STR))
126
0
        LM_BUG("RV_RE_F not supported for type %d\n", rv->type);
127
0
      regfree(rv->v.re.regex);
128
0
    }
129
0
    if(rv->flags & RV_RV_ALLOCED_F) {
130
0
      if(likely(allocated)) {
131
0
        pkg_free(rv);
132
0
      } else {
133
        /* not expected to be allocated */
134
0
        abort(); /* abort, otherwise is lost - find bugs quicker */
135
0
      }
136
0
    }
137
0
  }
138
0
}
139
140
141
/** frees a rval returned by rval_new(), rval_convert() or rval_expr_eval().
142
 *   Note: it will be freed only when refcnt reaches 0
143
 */
144
void rval_destroy(struct rvalue *rv)
145
0
{
146
0
  rval_destroy_helper(rv, 1);
147
0
}
148
149
150
/** frees content of rval which is not allocated, otherwise aborts.
151
 *   Note: it will be freed only when refcnt reaches 0
152
 */
153
void rval_destroy_content(struct rvalue *rv)
154
0
{
155
0
  rval_destroy_helper(rv, 0);
156
0
}
157
158
159
void rval_clean(struct rvalue *rv)
160
0
{
161
0
  if(rv_unref(rv))
162
0
    rval_force_clean(rv);
163
0
}
164
165
166
void rve_destroy(struct rval_expr *rve)
167
0
{
168
0
  if(rve) {
169
0
    if(rve->op == RVE_RVAL_OP) {
170
0
      if(rve->left.rval.refcnt) {
171
0
        if(rve->left.rval.refcnt == 1)
172
0
          rval_destroy(&rve->left.rval);
173
0
        else
174
0
          LM_BUG("rval expr rval with invalid refcnt: %d "
175
0
               "(%d,%d-%d,%d)"
176
0
               "\n",
177
0
              rve->left.rval.refcnt, rve->fpos.s_line,
178
0
              rve->fpos.s_col, rve->fpos.e_line, rve->fpos.e_col);
179
0
      }
180
0
      if(rve->right.rval.refcnt) {
181
0
        if(rve->right.rval.refcnt == 1)
182
0
          rval_destroy(&rve->right.rval);
183
0
        else
184
0
          LM_BUG("rval expr rval with invalid refcnt: %d "
185
0
               "(%d,%d-%d,%d)"
186
0
               "\n",
187
0
              rve->right.rval.refcnt, rve->fpos.s_line,
188
0
              rve->fpos.s_col, rve->fpos.e_line, rve->fpos.e_col);
189
0
      }
190
0
    } else {
191
0
      if(rve->left.rve)
192
0
        rve_destroy(rve->left.rve);
193
0
      if(rve->right.rve)
194
0
        rve_destroy(rve->right.rve);
195
0
    }
196
0
    pkg_free(rve);
197
0
  }
198
0
}
199
200
201
void rval_cache_clean(struct rval_cache *rvc)
202
0
{
203
0
  if((rvc->cache_type == RV_CACHE_PVAR) && (rvc->val_type != RV_NONE)) {
204
0
    pv_value_destroy(&rvc->c.pval);
205
0
  }
206
0
  rvc->cache_type = RV_CACHE_EMPTY;
207
0
  rvc->val_type = RV_NONE;
208
0
}
209
210
211
0
#define rv_chg_in_place(rv) ((rv)->refcnt == 1)
212
213
214
/** init a rvalue structure.
215
 * Note: not needed if the structure is allocate with one of the
216
 * rval_new* functions
217
 */
218
void rval_init(
219
    struct rvalue *rv, enum rval_type t, union rval_val *v, int flags)
220
0
{
221
0
  rv->flags = flags;
222
0
  rv->refcnt = 1;
223
0
  rv->type = t;
224
0
  if(v) {
225
0
    rv->v = *v;
226
0
  } else {
227
0
    memset(&rv->v, 0, sizeof(rv->v));
228
0
  }
229
0
}
230
231
232
/** create a new pk_malloc'ed empty rvalue.
233
 *
234
 * @param extra_size - extra space to allocate
235
 *                    (e.g.: so that future string operation can reuse
236
 *                     the space)
237
 * @return new rv or 0 on error
238
 */
239
struct rvalue *rval_new_empty(int extra_size)
240
0
{
241
0
  struct rvalue *rv;
242
0
  int size; /* extra size at the end */
243
244
0
  size = ROUND_LONG(
245
0
      sizeof(*rv) - sizeof(rv->buf) + extra_size); /* round up */
246
0
  rv = pkg_malloc(size);
247
0
  if(likely(rv)) {
248
0
    rv->bsize = size - sizeof(*rv)
249
0
          - sizeof(rv->buf); /* remaining size->buffer*/
250
0
    rv->flags = RV_RV_ALLOCED_F;
251
0
    rv->refcnt = 1;
252
0
    rv->type = RV_NONE;
253
0
  } else {
254
0
    PKG_MEM_ERROR;
255
0
    return 0;
256
0
  }
257
0
  return rv;
258
0
}
259
260
261
/** create a new pk_malloc'ed rv from a str.
262
 *
263
 * @param s - pointer to str, must be non-null
264
 * @param extra_size - extra space to allocate
265
 *                    (so that future string operation can reuse
266
 *                     the space)
267
 * @return new rv or 0 on error
268
 */
269
struct rvalue *rval_new_str(str *s, int extra_size)
270
0
{
271
0
  struct rvalue *rv;
272
273
0
  rv = rval_new_empty(extra_size + s->len + 1 /* 0 term */);
274
0
  if(likely(rv)) {
275
0
    rv->type = RV_STR;
276
0
    rv->v.s.s = &rv->buf[0];
277
0
    rv->v.s.len = s->len;
278
0
    memcpy(rv->v.s.s, s->s, s->len);
279
0
    rv->v.s.s[s->len] = 0;
280
0
  }
281
0
  return rv;
282
0
}
283
284
285
/** create a new pk_malloc'ed RE rv from a str re.
286
 * It acts as rval_new_str, but also compiles a RE from the str
287
 * and sets v->re.regex.
288
 * @param s - pointer to str, must be non-null, zero-term'ed and a valid RE.
289
 * @return new rv or 0 on error
290
 */
291
struct rvalue *rval_new_re(str *s)
292
0
{
293
0
  struct rvalue *rv;
294
0
  long offs;
295
296
0
  offs = (long)&((struct rvalue *)0)->buf[0]; /* offset of the buf. member */
297
  /* make sure we reserve enough space so that we can satisfy any regex_t
298
   * alignment requirement (pointer) */
299
0
  rv = rval_new_empty(ROUND_POINTER(offs) - offs + sizeof(*rv->v.re.regex)
300
0
            + s->len + 1 /* 0 */);
301
0
  if(likely(rv)) {
302
0
    rv->type = RV_STR;
303
    /* make sure regex points to a properly aligned address
304
     * (use max./pointer alignment to be sure ) */
305
0
    rv->v.re.regex =
306
0
        (regex_t *)((char *)&rv->buf[0] + ROUND_POINTER(offs) - offs);
307
0
    rv->v.s.s = (char *)rv->v.re.regex + sizeof(*rv->v.re.regex);
308
0
    rv->v.s.len = s->len;
309
0
    memcpy(rv->v.s.s, s->s, s->len);
310
0
    rv->v.s.s[s->len] = 0;
311
    /* compile the regex */
312
    /* same flags as for expr. =~ (fix_expr()) */
313
0
    if(unlikely(regcomp(rv->v.re.regex, s->s,
314
0
           REG_EXTENDED | REG_NOSUB | REG_ICASE))) {
315
      /* error */
316
0
      pkg_free(rv);
317
0
      rv = 0;
318
0
    } else /* success */
319
0
      rv->flags |= RV_RE_F;
320
0
  }
321
0
  return rv;
322
0
}
323
324
325
/** get string name for a type.
326
 *
327
 * @return - null terminated name of the type
328
 */
329
char *rval_type_name(enum rval_type type)
330
0
{
331
0
  switch(type) {
332
0
    case RV_NONE:
333
0
      return "none";
334
0
    case RV_LONG:
335
0
      return "int";
336
0
    case RV_STR:
337
0
      return "str";
338
0
    case RV_BEXPR:
339
0
      return "bexpr_t";
340
0
    case RV_ACTION_ST:
341
0
      return "action_t";
342
0
    case RV_PVAR:
343
0
      return "pvar";
344
0
    case RV_AVP:
345
0
      return "avp";
346
0
      break;
347
0
    case RV_SEL:
348
0
      return "select";
349
0
  }
350
0
  return "error_unknown_type";
351
0
}
352
353
354
/**
355
 * @brief create a new pk_malloc'ed rvalue from a rval_val union
356
 * @param t rvalue type
357
 * @param v rvalue value
358
 * @param extra_size extra space to allocate
359
 * (so that future string operation can reuse the space)
360
 * @return new rv or 0 on error
361
 */
362
struct rvalue *rval_new(enum rval_type t, union rval_val *v, int extra_size)
363
0
{
364
0
  struct rvalue *rv;
365
366
0
  if(t == RV_STR && v && v->s.s)
367
0
    return rval_new_str(&v->s, extra_size);
368
0
  rv = rval_new_empty(extra_size);
369
0
  if(likely(rv)) {
370
0
    rv->type = t;
371
0
    if(likely(v && t != RV_STR)) {
372
0
      rv->v = *v;
373
0
    } else if(t == RV_STR) {
374
0
      rv->v.s.s = &rv->buf[0];
375
0
      rv->v.s.len = 0;
376
0
      if(likely(extra_size))
377
0
        rv->v.s.s[0] = 0;
378
0
    } else
379
0
      memset(&rv->v, 0, sizeof(rv->v));
380
0
  }
381
0
  return rv;
382
0
}
383
384
385
/**
386
 * @brief get rvalue basic type (RV_LONG or RV_STR)
387
 *
388
 * Given a rvalue it tries to determine its basic type.
389
 * Fills val_cache if non-null and empty (can be used in other rval*
390
 * function calls, to avoid re-resolving avps or pvars). It must be
391
 * rval_cache_clean()'en when no longer needed.
392
 *
393
 * @param h run action context
394
 * @param msg SIP message
395
 * @param rv target rvalue
396
 * @param val_cache write-only value cache, might be filled if non-null,
397
 * it _must_ be rval_cache_clean()'en when done.
398
 * @return basic type or RV_NONE on error
399
 */
400
inline static enum rval_type rval_get_btype(struct run_act_ctx *h,
401
    struct sip_msg *msg, struct rvalue *rv, struct rval_cache *val_cache)
402
0
{
403
0
  avp_t *r_avp;
404
0
  int_str tmp_avp_val;
405
0
  int_str *avpv;
406
0
  pv_value_t tmp_pval;
407
0
  pv_value_t *pv;
408
0
  enum rval_type tmp;
409
0
  enum rval_type *ptype;
410
411
0
  switch(rv->type) {
412
0
    case RV_LONG:
413
0
    case RV_STR:
414
0
      return rv->type;
415
0
    case RV_BEXPR:
416
0
    case RV_ACTION_ST:
417
0
      return RV_LONG;
418
0
    case RV_PVAR:
419
0
      if(likely(val_cache && val_cache->cache_type == RV_CACHE_EMPTY)) {
420
0
        pv = &val_cache->c.pval;
421
0
        val_cache->cache_type = RV_CACHE_PVAR;
422
0
      } else {
423
0
        val_cache = 0;
424
0
        pv = &tmp_pval;
425
0
      }
426
0
      memset(pv, 0, sizeof(tmp_pval));
427
0
      if(likely(pv_get_spec_value(msg, &rv->v.pvs, pv) == 0)) {
428
0
        if(pv->flags & PV_TYPE_INT) {
429
0
          if(likely(val_cache != 0))
430
0
            val_cache->val_type = RV_LONG;
431
0
          else
432
0
            pv_value_destroy(pv);
433
0
          return RV_LONG;
434
0
        } else if(pv->flags & PV_VAL_STR) {
435
0
          if(likely(val_cache != 0))
436
0
            val_cache->val_type = RV_STR;
437
0
          else
438
0
            pv_value_destroy(pv);
439
0
          return RV_STR;
440
0
        } else {
441
0
          pv_value_destroy(pv);
442
0
          if(likely(val_cache != 0))
443
0
            val_cache->val_type = RV_NONE; /* undefined */
444
0
          goto error;
445
0
        }
446
0
      } else {
447
0
        if(likely(val_cache != 0))
448
0
          val_cache->val_type = RV_NONE; /* undefined */
449
0
        goto error;
450
0
      }
451
0
      break;
452
0
    case RV_AVP:
453
0
      if(likely(val_cache && val_cache->cache_type == RV_CACHE_EMPTY)) {
454
0
        ptype = &val_cache->val_type;
455
0
        avpv = &val_cache->c.avp_val;
456
0
        val_cache->cache_type = RV_CACHE_AVP;
457
0
      } else {
458
0
        ptype = &tmp;
459
0
        avpv = &tmp_avp_val;
460
0
      }
461
0
      r_avp = search_avp_by_index(
462
0
          rv->v.avps.type, rv->v.avps.name, avpv, rv->v.avps.index);
463
0
      if(likely(r_avp)) {
464
0
        if(r_avp->flags & AVP_VAL_STR) {
465
0
          *ptype = RV_STR;
466
0
          return RV_STR;
467
0
        } else {
468
0
          *ptype = RV_LONG;
469
0
          return RV_LONG;
470
0
        }
471
0
      } else {
472
0
        *ptype = RV_NONE;
473
0
        goto error;
474
0
      }
475
0
      break;
476
0
    case RV_SEL:
477
0
      return RV_STR;
478
0
    default:
479
0
      LM_BUG("rv type %d not handled\n", rv->type);
480
0
  }
481
0
error:
482
0
  return RV_NONE;
483
0
}
484
485
486
/** guess the type of an expression.
487
 * @return RV_LONG, RV_STR or RV_NONE (when type could not be found,
488
 * e.g. avp or pvar)
489
 */
490
enum rval_type rve_guess_type(struct rval_expr *rve)
491
0
{
492
0
  switch(rve->op) {
493
0
    case RVE_RVAL_OP:
494
0
      switch(rve->left.rval.type) {
495
0
        case RV_STR:
496
0
        case RV_SEL:
497
0
          return RV_STR;
498
0
        case RV_LONG:
499
0
        case RV_BEXPR:
500
0
        case RV_ACTION_ST:
501
0
          return RV_LONG;
502
0
        case RV_PVAR:
503
0
        case RV_AVP:
504
0
        case RV_NONE:
505
0
          return RV_NONE;
506
0
      }
507
0
      break;
508
0
    case RVE_UMINUS_OP:
509
0
    case RVE_BOOL_OP:
510
0
    case RVE_LNOT_OP:
511
0
    case RVE_BNOT_OP:
512
0
    case RVE_MINUS_OP:
513
0
    case RVE_MUL_OP:
514
0
    case RVE_DIV_OP:
515
0
    case RVE_MOD_OP:
516
0
    case RVE_BOR_OP:
517
0
    case RVE_BAND_OP:
518
0
    case RVE_BXOR_OP:
519
0
    case RVE_BLSHIFT_OP:
520
0
    case RVE_BRSHIFT_OP:
521
0
    case RVE_LAND_OP:
522
0
    case RVE_LOR_OP:
523
0
    case RVE_GT_OP:
524
0
    case RVE_GTE_OP:
525
0
    case RVE_LT_OP:
526
0
    case RVE_LTE_OP:
527
0
    case RVE_EQ_OP:
528
0
    case RVE_DIFF_OP:
529
0
    case RVE_IEQ_OP:
530
0
    case RVE_IDIFF_OP:
531
0
    case RVE_STREQ_OP:
532
0
    case RVE_STRDIFF_OP:
533
0
    case RVE_MATCH_OP:
534
0
    case RVE_IPLUS_OP:
535
0
    case RVE_STRLEN_OP:
536
0
    case RVE_STREMPTY_OP:
537
0
    case RVE_DEFINED_OP:
538
0
    case RVE_NOTDEFINED_OP:
539
0
    case RVE_LONG_OP:
540
0
      return RV_LONG;
541
0
    case RVE_PLUS_OP:
542
      /* '+' evaluates to the type of the left operand */
543
0
      return rve_guess_type(rve->left.rve);
544
0
    case RVE_CONCAT_OP:
545
0
    case RVE_STR_OP:
546
0
      return RV_STR;
547
0
    case RVE_SELVALEXP_OP:
548
0
      break;
549
0
    case RVE_SELVALOPT_OP:
550
0
      return rve_guess_type(rve->left.rve);
551
0
    case RVE_NONE_OP:
552
0
      break;
553
0
  }
554
0
  return RV_NONE;
555
0
}
556
557
558
/** returns true if expression is constant.
559
 * @return 0 or 1 on
560
 *  non constant type
561
 */
562
int rve_is_constant(struct rval_expr *rve)
563
0
{
564
0
  switch(rve->op) {
565
0
    case RVE_RVAL_OP:
566
0
      switch(rve->left.rval.type) {
567
0
        case RV_STR:
568
0
          return 1;
569
0
        case RV_LONG:
570
0
          return 1;
571
0
        case RV_SEL:
572
0
        case RV_BEXPR:
573
0
        case RV_ACTION_ST:
574
0
        case RV_PVAR:
575
0
        case RV_AVP:
576
0
        case RV_NONE:
577
0
          return 0;
578
0
      }
579
0
      break;
580
0
    case RVE_UMINUS_OP:
581
0
    case RVE_BOOL_OP:
582
0
    case RVE_LNOT_OP:
583
0
    case RVE_BNOT_OP:
584
0
    case RVE_STRLEN_OP:
585
0
    case RVE_STREMPTY_OP:
586
0
    case RVE_DEFINED_OP:
587
0
    case RVE_NOTDEFINED_OP:
588
0
    case RVE_LONG_OP:
589
0
    case RVE_STR_OP:
590
0
      return rve_is_constant(rve->left.rve);
591
0
    case RVE_MINUS_OP:
592
0
    case RVE_MUL_OP:
593
0
    case RVE_DIV_OP:
594
0
    case RVE_MOD_OP:
595
0
    case RVE_BOR_OP:
596
0
    case RVE_BAND_OP:
597
0
    case RVE_BXOR_OP:
598
0
    case RVE_BLSHIFT_OP:
599
0
    case RVE_BRSHIFT_OP:
600
0
    case RVE_LAND_OP:
601
0
    case RVE_LOR_OP:
602
0
    case RVE_GT_OP:
603
0
    case RVE_GTE_OP:
604
0
    case RVE_LT_OP:
605
0
    case RVE_LTE_OP:
606
0
    case RVE_EQ_OP:
607
0
    case RVE_DIFF_OP:
608
0
    case RVE_IEQ_OP:
609
0
    case RVE_IDIFF_OP:
610
0
    case RVE_STREQ_OP:
611
0
    case RVE_STRDIFF_OP:
612
0
    case RVE_MATCH_OP:
613
0
    case RVE_PLUS_OP:
614
0
    case RVE_IPLUS_OP:
615
0
    case RVE_CONCAT_OP:
616
0
    case RVE_SELVALEXP_OP:
617
0
    case RVE_SELVALOPT_OP:
618
0
      return rve_is_constant(rve->left.rve)
619
0
           && rve_is_constant(rve->right.rve);
620
0
    case RVE_NONE_OP:
621
0
      break;
622
0
  }
623
0
  return 0;
624
0
}
625
626
627
/** returns true if the expression has side-effects.
628
 * @return  1 for possible side-effects, 0 for no side-effects
629
 * TODO: add better checks
630
 */
631
int rve_has_side_effects(struct rval_expr *rve)
632
0
{
633
0
  return !rve_is_constant(rve);
634
0
}
635
636
637
/** returns true if operator is unary (takes only 1 arg).
638
 * @return 0 or 1 on
639
 */
640
static int rve_op_unary(enum rval_expr_op op)
641
0
{
642
0
  switch(op) {
643
0
    case RVE_RVAL_OP: /* not really an operator */
644
0
      return -1;
645
0
    case RVE_UMINUS_OP:
646
0
    case RVE_BOOL_OP:
647
0
    case RVE_LNOT_OP:
648
0
    case RVE_BNOT_OP:
649
0
    case RVE_STRLEN_OP:
650
0
    case RVE_STREMPTY_OP:
651
0
    case RVE_DEFINED_OP:
652
0
    case RVE_NOTDEFINED_OP:
653
0
    case RVE_LONG_OP:
654
0
    case RVE_STR_OP:
655
0
      return 1;
656
0
    case RVE_MINUS_OP:
657
0
    case RVE_MUL_OP:
658
0
    case RVE_DIV_OP:
659
0
    case RVE_MOD_OP:
660
0
    case RVE_BOR_OP:
661
0
    case RVE_BAND_OP:
662
0
    case RVE_BXOR_OP:
663
0
    case RVE_BLSHIFT_OP:
664
0
    case RVE_BRSHIFT_OP:
665
0
    case RVE_LAND_OP:
666
0
    case RVE_LOR_OP:
667
0
    case RVE_GT_OP:
668
0
    case RVE_GTE_OP:
669
0
    case RVE_LT_OP:
670
0
    case RVE_LTE_OP:
671
0
    case RVE_EQ_OP:
672
0
    case RVE_DIFF_OP:
673
0
    case RVE_IEQ_OP:
674
0
    case RVE_IDIFF_OP:
675
0
    case RVE_STREQ_OP:
676
0
    case RVE_STRDIFF_OP:
677
0
    case RVE_MATCH_OP:
678
0
    case RVE_PLUS_OP:
679
0
    case RVE_IPLUS_OP:
680
0
    case RVE_CONCAT_OP:
681
0
    case RVE_SELVALEXP_OP:
682
0
    case RVE_SELVALOPT_OP:
683
0
      return 0;
684
0
    case RVE_NONE_OP:
685
0
      return -1;
686
0
      break;
687
0
  }
688
0
  return 0;
689
0
}
690
691
692
/**
693
 * @brief Returns 1 if expression is valid (type-wise)
694
 * @param type filled with the type of the expression (RV_LONG, RV_STR or
695
 *                RV_NONE if it's dynamic)
696
 * @param rve  checked expression
697
 * @param bad_rve set on failure to the subexpression for which the
698
 * type check failed
699
 * @param bad_t set on failure to the type of the bad subexpression
700
 * @param exp_t set on failure to the expected type for the bad
701
 * subexpression
702
 * @return 0 or 1 and sets *type to the resulting type
703
 * (RV_LONG, RV_STR or RV_NONE if it can be found only at runtime)
704
 */
705
int rve_check_type(enum rval_type *type, struct rval_expr *rve,
706
    struct rval_expr **bad_rve, enum rval_type *bad_t,
707
    enum rval_type *exp_t)
708
0
{
709
0
  enum rval_type type1, type2;
710
711
0
  switch(rve->op) {
712
0
    case RVE_RVAL_OP:
713
0
      *type = rve_guess_type(rve);
714
0
      return 1;
715
0
    case RVE_SELVALEXP_OP:
716
0
    case RVE_SELVALOPT_OP:
717
0
      *type = rve_guess_type(rve);
718
0
      return 1;
719
0
    case RVE_UMINUS_OP:
720
0
    case RVE_BOOL_OP:
721
0
    case RVE_LNOT_OP:
722
0
    case RVE_BNOT_OP:
723
0
      *type = RV_LONG;
724
0
      if(rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)) {
725
0
        if(type1 == RV_STR) {
726
0
          if(bad_rve)
727
0
            *bad_rve = rve->left.rve;
728
0
          if(bad_t)
729
0
            *bad_t = type1;
730
0
          if(exp_t)
731
0
            *exp_t = RV_LONG;
732
0
          return 0;
733
0
        }
734
0
        return 1;
735
0
      }
736
0
      return 0;
737
0
      break;
738
0
    case RVE_MINUS_OP:
739
0
    case RVE_MUL_OP:
740
0
    case RVE_DIV_OP:
741
0
    case RVE_MOD_OP:
742
0
    case RVE_BOR_OP:
743
0
    case RVE_BAND_OP:
744
0
    case RVE_BXOR_OP:
745
0
    case RVE_BLSHIFT_OP:
746
0
    case RVE_BRSHIFT_OP:
747
0
    case RVE_LAND_OP:
748
0
    case RVE_LOR_OP:
749
0
    case RVE_GT_OP:
750
0
    case RVE_GTE_OP:
751
0
    case RVE_LT_OP:
752
0
    case RVE_LTE_OP:
753
0
    case RVE_IEQ_OP:
754
0
    case RVE_IDIFF_OP:
755
0
    case RVE_IPLUS_OP:
756
0
      *type = RV_LONG;
757
0
      if(rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)) {
758
0
        if(type1 == RV_STR) {
759
0
          if(bad_rve)
760
0
            *bad_rve = rve->left.rve;
761
0
          if(bad_t)
762
0
            *bad_t = type1;
763
0
          if(exp_t)
764
0
            *exp_t = RV_LONG;
765
0
          return 0;
766
0
        }
767
0
        if(rve_check_type(
768
0
               &type2, rve->right.rve, bad_rve, bad_t, exp_t)) {
769
0
          if(type2 == RV_STR) {
770
0
            if(bad_rve)
771
0
              *bad_rve = rve->right.rve;
772
0
            if(bad_t)
773
0
              *bad_t = type2;
774
0
            if(exp_t)
775
0
              *exp_t = RV_LONG;
776
0
            return 0;
777
0
          }
778
0
          return 1;
779
0
        }
780
0
      }
781
0
      return 0;
782
0
    case RVE_EQ_OP:
783
0
    case RVE_DIFF_OP:
784
0
      *type = RV_LONG;
785
0
      if(rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)) {
786
0
        if(rve_check_type(
787
0
               &type2, rve->right.rve, bad_rve, bad_t, exp_t)) {
788
0
          if((type2 != type1) && (type1 != RV_NONE)
789
0
              && (type2 != RV_NONE)
790
0
              && !(type1 == RV_STR && type2 == RV_LONG)) {
791
0
            if(bad_rve)
792
0
              *bad_rve = rve->right.rve;
793
0
            if(bad_t)
794
0
              *bad_t = type2;
795
0
            if(exp_t)
796
0
              *exp_t = type1;
797
0
            return 0;
798
0
          }
799
0
          return 1;
800
0
        }
801
0
      }
802
0
      return 0;
803
0
    case RVE_PLUS_OP:
804
0
      *type = RV_NONE;
805
0
      if(rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)) {
806
0
        if(rve_check_type(
807
0
               &type2, rve->right.rve, bad_rve, bad_t, exp_t)) {
808
0
          if((type2 != type1) && (type1 != RV_NONE)
809
0
              && (type2 != RV_NONE)
810
0
              && !(type1 == RV_STR && type2 == RV_LONG)) {
811
0
            if(bad_rve)
812
0
              *bad_rve = rve->right.rve;
813
0
            if(bad_t)
814
0
              *bad_t = type2;
815
0
            if(exp_t)
816
0
              *exp_t = type1;
817
0
            return 0;
818
0
          }
819
0
          *type = type1;
820
0
          return 1;
821
0
        }
822
0
      }
823
0
      break;
824
0
    case RVE_CONCAT_OP:
825
0
      *type = RV_STR;
826
0
      if(rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)) {
827
0
        if(rve_check_type(
828
0
               &type2, rve->right.rve, bad_rve, bad_t, exp_t)) {
829
0
          if((type2 != type1) && (type1 != RV_NONE)
830
0
              && (type2 != RV_NONE)
831
0
              && !(type1 == RV_STR && type2 == RV_LONG)) {
832
0
            if(bad_rve)
833
0
              *bad_rve = rve->right.rve;
834
0
            if(bad_t)
835
0
              *bad_t = type2;
836
0
            if(exp_t)
837
0
              *exp_t = type1;
838
0
            return 0;
839
0
          }
840
0
          if(type1 == RV_LONG) {
841
0
            if(bad_rve)
842
0
              *bad_rve = rve->left.rve;
843
0
            if(bad_t)
844
0
              *bad_t = type1;
845
0
            if(exp_t)
846
0
              *exp_t = RV_STR;
847
0
            return 0;
848
0
          }
849
0
          return 1;
850
0
        }
851
0
      }
852
0
      break;
853
0
    case RVE_STREQ_OP:
854
0
    case RVE_STRDIFF_OP:
855
0
    case RVE_MATCH_OP:
856
0
      *type = RV_LONG;
857
0
      if(rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)) {
858
0
        if(rve_check_type(
859
0
               &type2, rve->right.rve, bad_rve, bad_t, exp_t)) {
860
0
          if((type2 != type1) && (type1 != RV_NONE)
861
0
              && (type2 != RV_NONE)
862
0
              && !(type1 == RV_STR && type2 == RV_LONG)) {
863
0
            if(bad_rve)
864
0
              *bad_rve = rve->right.rve;
865
0
            if(bad_t)
866
0
              *bad_t = type2;
867
0
            if(exp_t)
868
0
              *exp_t = type1;
869
0
            return 0;
870
0
          }
871
0
          if(type1 == RV_LONG) {
872
0
            if(bad_rve)
873
0
              *bad_rve = rve->left.rve;
874
0
            if(bad_t)
875
0
              *bad_t = type1;
876
0
            if(exp_t)
877
0
              *exp_t = RV_STR;
878
0
            return 0;
879
0
          }
880
0
          return 1;
881
0
        }
882
0
      }
883
0
      break;
884
0
    case RVE_STRLEN_OP:
885
0
    case RVE_STREMPTY_OP:
886
0
    case RVE_DEFINED_OP:
887
0
    case RVE_NOTDEFINED_OP:
888
0
      *type = RV_LONG;
889
0
      if(rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)) {
890
0
        if(type1 == RV_LONG) {
891
0
          if(bad_rve)
892
0
            *bad_rve = rve->left.rve;
893
0
          if(bad_t)
894
0
            *bad_t = type1;
895
0
          if(exp_t)
896
0
            *exp_t = RV_STR;
897
0
          return 0;
898
0
        }
899
0
        return 1;
900
0
      }
901
0
      break;
902
0
    case RVE_LONG_OP:
903
0
      *type = RV_LONG;
904
0
      return 1;
905
0
      break;
906
0
    case RVE_STR_OP:
907
0
      *type = RV_STR;
908
0
      return 1;
909
0
      break;
910
0
    case RVE_NONE_OP:
911
0
    default:
912
0
      LM_BUG("unexpected rve op %d (%d,%d-%d,%d)\n", rve->op,
913
0
          rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
914
0
          rve->fpos.e_col);
915
0
      if(bad_rve)
916
0
        *bad_rve = rve;
917
0
      if(bad_t)
918
0
        *bad_t = RV_NONE;
919
0
      if(exp_t)
920
0
        *exp_t = RV_STR;
921
0
      break;
922
0
  }
923
0
  return 0;
924
0
}
925
926
927
/** get the long int value of an rvalue.
928
 * *i=(long int)rv
929
 * if rv == undefined select, avp or pvar, return 0.
930
 * if an error occurs while evaluating a select, avp or pvar, behave as
931
 * for the undefined case (and return success).
932
 * @param h - script context handle
933
 * @param msg - sip msg
934
 * @param i   - pointer to int, where the conversion result will be stored
935
 * @param rv   - rvalue to be converted
936
 * @param cache - cached rv value (read-only), can be 0
937
 *
938
 * @return 0 on success, \<0 on error and EXPR_DROP on drop
939
 */
940
long rval_get_long(struct run_act_ctx *h, struct sip_msg *msg, long *i,
941
    struct rvalue *rv, struct rval_cache *cache)
942
0
{
943
0
  avp_t *r_avp;
944
0
  int_str avp_val;
945
0
  pv_value_t pval;
946
0
  str tmp;
947
0
  str *s;
948
0
  int r, ret;
949
0
  int destroy_pval;
950
951
0
  destroy_pval = 0;
952
0
  s = 0;
953
0
  ret = 0;
954
0
  switch(rv->type) {
955
0
    case RV_LONG:
956
0
      *i = rv->v.l;
957
0
      break;
958
0
    case RV_STR:
959
0
      s = &rv->v.s;
960
0
      goto rv_str;
961
0
    case RV_BEXPR:
962
0
      *i = eval_expr(h, rv->v.bexpr, msg);
963
0
      if(*i == EXPR_DROP) {
964
0
        *i = 0; /* false */
965
0
        return EXPR_DROP;
966
0
      }
967
0
      break;
968
0
    case RV_ACTION_ST:
969
0
      if(rv->v.action) {
970
0
        if(unlikely(ksr_return_mode == 1)) {
971
0
          *i = run_actions_safe(h, rv->v.action, msg);
972
0
        } else {
973
0
          *i = (run_actions_safe(h, rv->v.action, msg) > 0);
974
0
        }
975
0
        h->run_flags &= ~(RETURN_R_F | BREAK_R_F);
976
        /* catch return & break in expr*/
977
0
      } else
978
0
        *i = 0;
979
0
      break;
980
0
    case RV_SEL:
981
0
      r = run_select(&tmp, &rv->v.sel, msg);
982
0
      if(unlikely(r != 0)) {
983
0
        if(r < 0)
984
0
          goto eval_error;
985
0
        else /* i>0  => undefined */
986
0
          goto undef;
987
0
      }
988
0
      s = &tmp;
989
0
      goto rv_str;
990
0
    case RV_AVP:
991
0
      if(unlikely(cache && cache->cache_type == RV_CACHE_AVP)) {
992
0
        if(likely(cache->val_type == RV_LONG)) {
993
0
          *i = cache->c.avp_val.n;
994
0
        } else if(cache->val_type == RV_STR) {
995
0
          s = &cache->c.avp_val.s;
996
0
          goto rv_str;
997
0
        } else if(cache->val_type == RV_NONE)
998
0
          goto undef;
999
0
        else
1000
0
          goto error_cache;
1001
0
      } else {
1002
0
        r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
1003
0
            &avp_val, rv->v.avps.index);
1004
0
        if(likely(r_avp)) {
1005
0
          if(unlikely(r_avp->flags & AVP_VAL_STR)) {
1006
0
            s = &avp_val.s;
1007
0
            goto rv_str;
1008
0
          } else {
1009
0
            *i = avp_val.n;
1010
0
          }
1011
0
        } else {
1012
0
          goto undef;
1013
0
        }
1014
0
      }
1015
0
      break;
1016
0
    case RV_PVAR:
1017
0
      if(unlikely(cache && cache->cache_type == RV_CACHE_PVAR)) {
1018
0
        if(likely((cache->val_type == RV_LONG)
1019
0
               || (cache->c.pval.flags & PV_VAL_INT))) {
1020
0
          *i = cache->c.pval.ri;
1021
0
        } else if(cache->val_type == RV_STR) {
1022
0
          s = &cache->c.pval.rs;
1023
0
          goto rv_str;
1024
0
        } else if(cache->val_type == RV_NONE)
1025
0
          goto undef;
1026
0
        else
1027
0
          goto error_cache;
1028
0
      } else {
1029
0
        memset(&pval, 0, sizeof(pval));
1030
0
        if(likely(pv_get_spec_value(msg, &rv->v.pvs, &pval) == 0)) {
1031
0
          if(likely(pval.flags & PV_VAL_INT)) {
1032
0
            *i = pval.ri;
1033
0
            pv_value_destroy(&pval);
1034
0
          } else if(likely(pval.flags & PV_VAL_STR)) {
1035
0
            destroy_pval = 1; /* we must pv_value_destroy() later*/
1036
0
            s = &pval.rs;
1037
0
            goto rv_str;
1038
0
          } else {
1039
            /* no PV_VAL_STR and no PV_VAL_INT => undef
1040
             * (PV_VAL_NULL) */
1041
0
            pv_value_destroy(&pval);
1042
0
            goto undef;
1043
0
          }
1044
0
        } else {
1045
0
          goto eval_error;
1046
0
        }
1047
0
      }
1048
0
      break;
1049
0
    default:
1050
0
      LM_BUG("rv type %d not handled\n", rv->type);
1051
0
      goto error;
1052
0
  }
1053
0
  return ret;
1054
0
undef:
1055
0
eval_error: /* same as undefined */
1056
  /* handle undefined => result 0, return success */
1057
0
  *i = 0;
1058
0
  return 0;
1059
0
rv_str:
1060
  /* rv is of string type => try to convert it to int */
1061
  /* if "" => 0 (most likely case) */
1062
0
  if(likely(s->len == 0))
1063
0
    *i = 0;
1064
0
  else if(unlikely(str2slong(s, i) != 0)) {
1065
    /* dec to int failed, try hex to int */
1066
0
    if(!(s->len > 2 && s->s[0] == '0' && (s->s[1] == 'x' || s->s[1] == 'X')
1067
0
           && (hexstr2int(s->s + 2, s->len - 2, (unsigned int *)i)
1068
0
               == 0))) {
1069
      /* error converting to int => non numeric => 0 */
1070
0
      *i = 0;
1071
0
#ifdef RV_STR2INT_VERBOSE_ERR
1072
0
      LM_WARN("automatic string to int conversion for \"%.*s\" failed\n",
1073
0
          s->len, ZSW(s->s));
1074
      /* return an error code */
1075
0
#endif
1076
0
#ifdef RV_STR2INT_ERR
1077
0
      ret = -1;
1078
0
#endif
1079
0
    }
1080
0
  }
1081
0
  if(destroy_pval)
1082
0
    pv_value_destroy(&pval);
1083
0
  return ret;
1084
0
error_cache:
1085
0
  LM_BUG("invalid cached value:cache type %d, value type %d\n",
1086
0
      cache ? cache->cache_type : 0, cache ? cache->val_type : 0);
1087
0
error:
1088
0
  if(destroy_pval)
1089
0
    pv_value_destroy(&pval);
1090
0
  *i = 0;
1091
0
  return -1;
1092
0
}
1093
1094
1095
/** log a message, appending rve position and a '\n'.*/
1096
#define RVE_LOG(lev, rve, txt)                                              \
1097
  LOG((lev), txt " (%d,%d-%d,%d)\n", (rve)->fpos.s_line, rve->fpos.s_col, \
1098
      (rve)->fpos.e_line, rve->fpos.e_col)
1099
1100
1101
/** macro for checking and handling rval_get_long() retcode.
1102
 * check if the return code is an rval_get_long error and if so
1103
 * handle the error (e.g. print a log message, ignore the error by
1104
 * setting ret to 0 a.s.o.)
1105
 * @param ret - retcode as returned by rval_get_long() (might be changed)
1106
 * @param txt - warning message txt (no pointer allowed)
1107
 * @param rve - rval_expr, used to access the config. pos
1108
 */
1109
#if defined RVAL_GET_LONG_ERR_WARN && defined RVAL_GET_LONG_ERR_IGN
1110
#define rval_get_LONG_handle_ret(ret, txt, rve) \
1111
  do {                                        \
1112
    if(unlikely((ret) < 0)) {               \
1113
      RVE_LOG(L_WARN, rve, txt);          \
1114
      (ret) = 0;                          \
1115
    }                                       \
1116
  } while(0)
1117
#elif defined RVAL_GET_LONG_ERR_WARN
1118
#define rval_get_long_handle_ret(ret, txt, rve) \
1119
  do {                                        \
1120
    if(unlikely((ret) < 0))                 \
1121
      RVE_LOG(L_WARN, rve, txt);          \
1122
  } while(0)
1123
#elif defined RVAL_GET_LONG_ERR_IGN
1124
#define rval_get_long_handle_ret(ret, txt, rve) \
1125
  do {                                        \
1126
    if(unlikely((ret) < 0))                 \
1127
      (ret) = 0;                          \
1128
  } while(0)
1129
#else
1130
#define rval_get_long_handle_ret(ret, txt, rve) /* do nothing */
1131
#endif
1132
1133
1134
/** get the string value of an rv in a tmp variable
1135
 * *s=(str)rv
1136
 * if rv == undefined select, avp or pvar, return "".
1137
 * if an error occurs while evaluating a select, avp or pvar, behave as
1138
 * for the undefined case (and return success).
1139
 * The result points either inside the passed rv, inside
1140
 * new_cache or inside an avp. new_cache must be non zero,
1141
 * initialized previously and it _must_ be rval_cache_clean(...)'ed when
1142
 * done.
1143
 * WARNING: it's not intended for general use. It might return a pointer
1144
 * inside rv so the result _must_ be treated as read-only. rv and new_cache
1145
 * must not be released/freed until the result is no longer needed.
1146
 * For general use see  rval_get_str().
1147
 * @param h - script context handle
1148
 * @param msg - sip msg
1149
 * @param tmpv - str return value (pointer to a str struct that will be
1150
 *               be filled with the conversion result)
1151
 * @param rv   - rvalue to be converted
1152
 * @param cache - cached rv value (read-only), can be 0
1153
 * @param tmp_cache - used for temporary storage (so that tmpv will not
1154
 *                 point to possible freed data), it must be non-null,
1155
 *                 initialized and cleaned afterwards.
1156
 * @return 0 on success, <0 on error and EXPR_DROP on drop
1157
 */
1158
int rval_get_tmp_str(struct run_act_ctx *h, struct sip_msg *msg, str *tmpv,
1159
    struct rvalue *rv, struct rval_cache *cache,
1160
    struct rval_cache *tmp_cache)
1161
0
{
1162
0
  avp_t *r_avp;
1163
0
  int i;
1164
1165
0
  if(rv == NULL) {
1166
0
    return -1;
1167
0
  }
1168
1169
0
  switch(rv->type) {
1170
0
    case RV_LONG:
1171
0
      tmpv->s = sint2strbuf(rv->v.l, tmp_cache->i2s,
1172
0
          sizeof(tmp_cache->i2s), &tmpv->len);
1173
0
      tmp_cache->cache_type = RV_CACHE_INT2STR;
1174
0
      break;
1175
0
    case RV_STR:
1176
0
      *tmpv = rv->v.s;
1177
0
      break;
1178
0
    case RV_ACTION_ST:
1179
0
      if(rv->v.action) {
1180
0
        i = (run_actions_safe(h, rv->v.action, msg) > 0);
1181
0
        h->run_flags &= ~(RETURN_R_F | BREAK_R_F);
1182
        /* catch return & break in expr*/
1183
0
      } else
1184
0
        i = 0;
1185
0
      tmpv->s = sint2strbuf(
1186
0
          i, tmp_cache->i2s, sizeof(tmp_cache->i2s), &tmpv->len);
1187
0
      tmp_cache->cache_type = RV_CACHE_INT2STR;
1188
0
      break;
1189
0
    case RV_BEXPR:
1190
0
      i = eval_expr(h, rv->v.bexpr, msg);
1191
0
      if(i == EXPR_DROP) {
1192
0
        i = 0; /* false */
1193
0
        tmpv->s = sint2strbuf(
1194
0
            i, tmp_cache->i2s, sizeof(tmp_cache->i2s), &tmpv->len);
1195
0
        tmp_cache->cache_type = RV_CACHE_INT2STR;
1196
0
        return EXPR_DROP;
1197
0
      }
1198
0
      tmpv->s = sint2strbuf(
1199
0
          i, tmp_cache->i2s, sizeof(tmp_cache->i2s), &tmpv->len);
1200
0
      tmp_cache->cache_type = RV_CACHE_INT2STR;
1201
0
      break;
1202
0
    case RV_SEL:
1203
0
      i = run_select(tmpv, &rv->v.sel, msg);
1204
0
      if(unlikely(i != 0)) {
1205
0
        if(i < 0) {
1206
0
          goto eval_error;
1207
0
        } else { /* i>0  => undefined */
1208
0
          goto undef;
1209
0
        }
1210
0
      }
1211
0
      break;
1212
0
    case RV_AVP:
1213
0
      if(likely(cache && cache->cache_type == RV_CACHE_AVP)) {
1214
0
        if(likely(cache->val_type == RV_STR)) {
1215
0
          *tmpv = cache->c.avp_val.s;
1216
0
        } else if(cache->val_type == RV_LONG) {
1217
0
          i = cache->c.avp_val.n;
1218
0
          tmpv->s = sint2strbuf(i, tmp_cache->i2s,
1219
0
              sizeof(tmp_cache->i2s), &tmpv->len);
1220
0
          tmp_cache->cache_type = RV_CACHE_INT2STR;
1221
0
        } else if(cache->val_type == RV_NONE) {
1222
0
          goto undef;
1223
0
        } else
1224
0
          goto error_cache;
1225
0
      } else {
1226
0
        r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
1227
0
            &tmp_cache->c.avp_val, rv->v.avps.index);
1228
0
        if(likely(r_avp)) {
1229
0
          if(likely(r_avp->flags & AVP_VAL_STR)) {
1230
0
            tmp_cache->cache_type = RV_CACHE_AVP;
1231
0
            tmp_cache->val_type = RV_STR;
1232
0
            *tmpv = tmp_cache->c.avp_val.s;
1233
0
          } else {
1234
0
            i = tmp_cache->c.avp_val.n;
1235
0
            tmpv->s = sint2strbuf(i, tmp_cache->i2s,
1236
0
                sizeof(tmp_cache->i2s), &tmpv->len);
1237
0
            tmp_cache->cache_type = RV_CACHE_INT2STR;
1238
0
          }
1239
0
        } else
1240
0
          goto undef;
1241
0
      }
1242
0
      break;
1243
0
    case RV_PVAR:
1244
0
      if(likely(cache && cache->cache_type == RV_CACHE_PVAR)) {
1245
0
        if(likely(cache->val_type == RV_STR)) {
1246
0
          *tmpv = cache->c.pval.rs;
1247
0
        } else if(cache->val_type == RV_LONG) {
1248
0
          i = cache->c.pval.ri;
1249
0
          tmpv->s = sint2strbuf(i, tmp_cache->i2s,
1250
0
              sizeof(tmp_cache->i2s), &tmpv->len);
1251
0
          tmp_cache->cache_type = RV_CACHE_INT2STR;
1252
0
        } else if(cache->val_type == RV_NONE) {
1253
0
          goto undef;
1254
0
        } else
1255
0
          goto error_cache;
1256
0
      } else {
1257
0
        memset(&tmp_cache->c.pval, 0, sizeof(tmp_cache->c.pval));
1258
0
        if(likely(pv_get_spec_value(msg, &rv->v.pvs, &tmp_cache->c.pval)
1259
0
               == 0)) {
1260
0
          if(likely(tmp_cache->c.pval.flags & PV_VAL_STR)) {
1261
            /*  the value is not destroyed, but saved instead
1262
              in tmp_cache so that it can be destroyed later
1263
              when no longer needed */
1264
0
            tmp_cache->cache_type = RV_CACHE_PVAR;
1265
0
            tmp_cache->val_type = RV_STR;
1266
0
            *tmpv = tmp_cache->c.pval.rs;
1267
0
          } else if(likely(tmp_cache->c.pval.flags & PV_VAL_INT)) {
1268
0
            i = tmp_cache->c.pval.ri;
1269
0
            pv_value_destroy(&tmp_cache->c.pval);
1270
0
            tmpv->s = sint2strbuf(i, tmp_cache->i2s,
1271
0
                sizeof(tmp_cache->i2s), &tmpv->len);
1272
0
            tmp_cache->cache_type = RV_CACHE_INT2STR;
1273
0
          } else {
1274
            /* no PV_VAL_STR and no PV_VAL_INT => undef
1275
             * (PV_VAL_NULL) */
1276
0
            pv_value_destroy(&tmp_cache->c.pval);
1277
0
            goto undef;
1278
0
          }
1279
0
        } else {
1280
0
          goto eval_error;
1281
0
        }
1282
0
      }
1283
0
      break;
1284
0
    default:
1285
0
      LM_BUG("rv type %d not handled\n", rv->type);
1286
0
      goto error;
1287
0
  }
1288
0
  return 0;
1289
0
undef:
1290
0
eval_error: /* same as undefined */
1291
  /* handle undefined => result "", return success */
1292
0
  tmpv->s = "";
1293
0
  tmpv->len = 0;
1294
0
  return 0;
1295
0
error_cache:
1296
0
  LM_BUG("invalid cached value:cache type %d, value type %d\n",
1297
0
      cache ? cache->cache_type : 0, cache ? cache->val_type : 0);
1298
0
error:
1299
0
  tmpv->s = "";
1300
0
  tmpv->len = 0;
1301
0
  return -1;
1302
0
}
1303
1304
1305
/** get the string value of an rv.
1306
 * *s=(str)rv
1307
 * The result is pkg malloc'ed (so it should be pkg_free()'ed when finished.
1308
 * @return 0 on success, <0 on error and EXPR_DROP on drop
1309
 */
1310
int rval_get_str(struct run_act_ctx *h, struct sip_msg *msg, str *s,
1311
    struct rvalue *rv, struct rval_cache *cache)
1312
0
{
1313
0
  str tmp;
1314
0
  struct rval_cache tmp_cache;
1315
1316
0
  rval_cache_init(&tmp_cache);
1317
0
  if(unlikely(rval_get_tmp_str(h, msg, &tmp, rv, cache, &tmp_cache) < 0))
1318
0
    goto error;
1319
0
  s->s = pkg_malloc(tmp.len + 1 /* 0 term */);
1320
0
  if(unlikely(s->s == 0)) {
1321
0
    PKG_MEM_ERROR;
1322
0
    goto error;
1323
0
  }
1324
0
  s->len = tmp.len;
1325
0
  memcpy(s->s, tmp.s, tmp.len);
1326
0
  s->s[tmp.len] = 0; /* 0 term */
1327
0
  rval_cache_clean(&tmp_cache);
1328
0
  return 0;
1329
0
error:
1330
0
  rval_cache_clean(&tmp_cache);
1331
0
  return -1;
1332
0
}
1333
1334
1335
/**
1336
 * @brief Convert a rvalue to another rvalue, of a specific type
1337
 *
1338
 * Convert a rvalue to another rvalue, of a specific type.
1339
 * The result is read-only in most cases (can be a reference
1340
 * to another rvalue, can be checked by using rv_chg_in_place()) and
1341
 * _must_ be rval_destroy()'ed.
1342
 *
1343
 * @param h run action context
1344
 * @param msg SIP mesasge
1345
 * @param type - type to convert to
1346
 * @param v - rvalue to convert
1347
 * @param c - rval_cache (cached v value if known/filled by another
1348
 *            function), can be 0 (unknown/not needed)
1349
 * @return pointer to a rvalue (reference to an existing one or a new
1350
 * one, @see rv_chg_in_place() and the above comment), or 0 on error.
1351
 */
1352
struct rvalue *rval_convert(struct run_act_ctx *h, struct sip_msg *msg,
1353
    enum rval_type type, struct rvalue *v, struct rval_cache *c)
1354
0
{
1355
0
  long i;
1356
0
  struct rval_cache tmp_cache;
1357
0
  str tmp;
1358
0
  struct rvalue *ret;
1359
0
  union rval_val val;
1360
1361
0
  if(v->type == type) {
1362
0
    rv_ref(v);
1363
0
    return v;
1364
0
  }
1365
0
  switch(type) {
1366
0
    case RV_LONG:
1367
0
      if(unlikely(rval_get_long(h, msg, &i, v, c) < 0))
1368
0
        return 0;
1369
0
      val.l = i;
1370
0
      return rval_new(RV_LONG, &val, 0);
1371
0
    case RV_STR:
1372
0
      rval_cache_init(&tmp_cache);
1373
0
      if(unlikely(rval_get_tmp_str(h, msg, &tmp, v, c, &tmp_cache) < 0)) {
1374
0
        rval_cache_clean(&tmp_cache);
1375
0
        return 0;
1376
0
      }
1377
0
      ret = rval_new_str(&tmp, RV_STR_EXTRA);
1378
0
      rval_cache_clean(&tmp_cache);
1379
0
      return ret;
1380
0
    case RV_NONE:
1381
0
    default:
1382
0
      LM_BUG("unsupported conversion to type %d\n", type);
1383
0
      return 0;
1384
0
  }
1385
0
  return 0;
1386
0
}
1387
1388
1389
/** integer operation: *res= op v.
1390
 * @return 0 on success, \<0 on error
1391
 */
1392
inline static int long_longop1(long *res, enum rval_expr_op op, long v)
1393
0
{
1394
0
  switch(op) {
1395
0
    case RVE_UMINUS_OP:
1396
0
      *res = -v;
1397
0
      break;
1398
0
    case RVE_BOOL_OP:
1399
0
      *res = !!v;
1400
0
      break;
1401
0
    case RVE_LNOT_OP:
1402
0
      *res = !v;
1403
0
      break;
1404
0
    case RVE_BNOT_OP:
1405
0
      *res = ~v;
1406
0
      break;
1407
0
    default:
1408
0
      LM_BUG("rv unsupported intop1 %d\n", op);
1409
0
      return -1;
1410
0
  }
1411
0
  return 0;
1412
0
}
1413
1414
1415
/** integer operation: *res= v1 op v2
1416
 * @return 0 on success, \<0 on error
1417
 */
1418
inline static int long_longop2(
1419
    long *res, enum rval_expr_op op, long v1, long v2)
1420
0
{
1421
0
  switch(op) {
1422
0
    case RVE_PLUS_OP:
1423
0
    case RVE_IPLUS_OP:
1424
0
      *res = v1 + v2;
1425
0
      break;
1426
0
    case RVE_MINUS_OP:
1427
0
      *res = v1 - v2;
1428
0
      break;
1429
0
    case RVE_MUL_OP:
1430
0
      *res = v1 * v2;
1431
0
      break;
1432
0
    case RVE_DIV_OP:
1433
0
      if(unlikely(v2 == 0)) {
1434
0
        LM_ERR("rv div by 0\n");
1435
0
        return -1;
1436
0
      }
1437
0
      *res = v1 / v2;
1438
0
      break;
1439
0
    case RVE_MOD_OP:
1440
0
      if(unlikely(v2 == 0)) {
1441
0
        LM_ERR("rv mod by 0\n");
1442
0
        return -1;
1443
0
      }
1444
0
      *res = v1 % v2;
1445
0
      break;
1446
0
    case RVE_BOR_OP:
1447
0
      *res = v1 | v2;
1448
0
      break;
1449
0
    case RVE_BAND_OP:
1450
0
      *res = v1 & v2;
1451
0
      break;
1452
0
    case RVE_BXOR_OP:
1453
0
      *res = v1 ^ v2;
1454
0
      break;
1455
0
    case RVE_BLSHIFT_OP:
1456
0
      *res = v1 << v2;
1457
0
      break;
1458
0
    case RVE_BRSHIFT_OP:
1459
0
      *res = v1 >> v2;
1460
0
      break;
1461
0
    case RVE_LAND_OP:
1462
0
      *res = v1 && v2;
1463
0
      break;
1464
0
    case RVE_LOR_OP:
1465
0
      *res = v1 || v2;
1466
0
      break;
1467
0
    case RVE_GT_OP:
1468
0
      *res = v1 > v2;
1469
0
      break;
1470
0
    case RVE_GTE_OP:
1471
0
      *res = v1 >= v2;
1472
0
      break;
1473
0
    case RVE_LT_OP:
1474
0
      *res = v1 < v2;
1475
0
      break;
1476
0
    case RVE_LTE_OP:
1477
0
      *res = v1 <= v2;
1478
0
      break;
1479
0
    case RVE_EQ_OP:
1480
0
    case RVE_IEQ_OP:
1481
0
      *res = v1 == v2;
1482
0
      break;
1483
0
    case RVE_DIFF_OP:
1484
0
    case RVE_IDIFF_OP:
1485
0
      *res = v1 != v2;
1486
0
      break;
1487
0
    case RVE_CONCAT_OP:
1488
0
      *res = 0;
1489
      /* invalid operand for int */
1490
0
      return -1;
1491
0
    default:
1492
0
      LM_BUG("rv unsupported intop %d\n", op);
1493
0
      return -1;
1494
0
  }
1495
0
  return 0;
1496
0
}
1497
1498
1499
/** internal helper: compare 2 RV_STR RVs.
1500
 * Warning: rv1 & rv2 must be RV_STR
1501
 * @return 0 on success, -1 on error
1502
 */
1503
inline static int bool_rvstrop2(
1504
    enum rval_expr_op op, long *res, struct rvalue *rv1, struct rvalue *rv2)
1505
0
{
1506
0
  str *s1;
1507
0
  str *s2;
1508
0
  regex_t tmp_re;
1509
1510
0
  s1 = &rv1->v.s;
1511
0
  s2 = &rv2->v.s;
1512
0
  switch(op) {
1513
0
    case RVE_EQ_OP:
1514
0
    case RVE_STREQ_OP:
1515
0
      *res = (s1->len == s2->len) && (memcmp(s1->s, s2->s, s1->len) == 0);
1516
0
      break;
1517
0
    case RVE_DIFF_OP:
1518
0
    case RVE_STRDIFF_OP:
1519
0
      *res = (s1->len != s2->len) || (memcmp(s1->s, s2->s, s1->len) != 0);
1520
0
      break;
1521
0
    case RVE_MATCH_OP:
1522
0
      if(likely(rv2->flags & RV_RE_F)) {
1523
0
        *res = (regexec(rv2->v.re.regex, rv1->v.s.s, 0, 0, 0) == 0);
1524
0
      } else {
1525
        /* we need to compile the RE on the fly */
1526
0
        if(unlikely(regcomp(&tmp_re, s2->s,
1527
0
               REG_EXTENDED | REG_NOSUB | REG_ICASE))) {
1528
          /* error */
1529
0
          LM_ERR("Bad regular expression \"%s\"\n", s2->s);
1530
0
          goto error;
1531
0
        }
1532
0
        *res = (regexec(&tmp_re, s1->s, 0, 0, 0) == 0);
1533
0
        regfree(&tmp_re);
1534
0
      }
1535
0
      break;
1536
0
    default:
1537
0
      LM_BUG("rv unsupported intop %d\n", op);
1538
0
      goto error;
1539
0
  }
1540
0
  return 0;
1541
0
error:
1542
0
  *res = 0; /* false */
1543
0
  return -1;
1544
0
}
1545
1546
1547
/** integer returning operation on string: *res= op str (returns integer)
1548
 * @return 0 on success, \<0 on error
1549
 */
1550
inline static int long_strop1(long *res, enum rval_expr_op op, str *s1)
1551
0
{
1552
0
  switch(op) {
1553
0
    case RVE_STRLEN_OP:
1554
0
      *res = s1->len;
1555
0
      break;
1556
0
    case RVE_STREMPTY_OP:
1557
0
      *res = (s1->len == 0);
1558
0
      break;
1559
0
    default:
1560
0
      LM_BUG("rv unsupported int_strop1 %d\n", op);
1561
0
      *res = 0;
1562
0
      return -1;
1563
0
  }
1564
0
  return 0;
1565
0
}
1566
1567
1568
/** string add operation: ret= l . r (returns a rvalue).
1569
 * Can use cached rvalues (c1 & c2).
1570
 * @return rvalue on success, 0 on error
1571
 */
1572
inline static struct rvalue *rval_str_add2(struct run_act_ctx *h,
1573
    struct sip_msg *msg, struct rvalue *l, struct rval_cache *c1,
1574
    struct rvalue *r, struct rval_cache *c2)
1575
0
{
1576
0
  struct rvalue *rv1;
1577
0
  struct rvalue *rv2;
1578
0
  struct rvalue *ret;
1579
0
  str *s1;
1580
0
  str *s2;
1581
0
  str tmp;
1582
0
  short flags;
1583
0
  int len;
1584
1585
0
  rv2 = rv1 = 0;
1586
0
  ret = 0;
1587
0
  flags = 0;
1588
0
  s1 = 0;
1589
0
  s2 = 0;
1590
0
  if((rv1 = rval_convert(h, msg, RV_STR, l, c1)) == 0)
1591
0
    goto error;
1592
0
  if((rv2 = rval_convert(h, msg, RV_STR, r, c2)) == 0)
1593
0
    goto error;
1594
1595
0
  len = rv1->v.s.len + rv2->v.s.len + 1 /* 0 */;
1596
1597
0
  if(rv_chg_in_place(rv1) && (rv1->bsize >= len)) {
1598
    /* try reusing rv1 */
1599
0
    ret = rv1;
1600
0
    rv_ref(ret);
1601
0
    s2 = &rv2->v.s;
1602
0
    if(ret->v.s.s == &ret->buf[0])
1603
0
      s1 = 0;
1604
0
    else {
1605
0
      tmp = ret->v.s;
1606
0
      flags = ret->flags;
1607
0
      ret->flags &= ~RV_CNT_ALLOCED_F;
1608
0
      ret->v.s.s = &ret->buf[0];
1609
0
      ret->v.s.len = 0;
1610
0
      s1 = &tmp;
1611
0
    }
1612
0
  } else if(rv_chg_in_place(rv2) && (rv2->bsize >= len)) {
1613
    /* try reusing rv2 */
1614
0
    ret = rv2;
1615
0
    rv_ref(ret);
1616
0
    s1 = &rv1->v.s;
1617
0
    if(ret->v.s.s == &ret->buf[0])
1618
0
      s2 = &ret->v.s;
1619
0
    else {
1620
0
      tmp = ret->v.s;
1621
0
      flags = ret->flags;
1622
0
      ret->flags &= ~RV_CNT_ALLOCED_F;
1623
0
      ret->v.s.s = &ret->buf[0];
1624
0
      ret->v.s.len = 0;
1625
0
      s2 = &tmp;
1626
0
    }
1627
0
  } else if((l->type == RV_STR) && (rv_chg_in_place(l))
1628
0
        && (l->bsize >= len)) {
1629
0
    ret = l;
1630
0
    rv_ref(ret);
1631
0
    s2 = &rv2->v.s;
1632
0
    if(ret->v.s.s == &ret->buf[0])
1633
0
      s1 = 0;
1634
0
    else {
1635
0
      tmp = ret->v.s;
1636
0
      flags = ret->flags;
1637
0
      ret->flags &= ~RV_CNT_ALLOCED_F;
1638
0
      ret->v.s.s = &ret->buf[0];
1639
0
      ret->v.s.len = 0;
1640
0
      s1 = &tmp;
1641
0
    }
1642
0
  } else if((r->type == RV_STR)
1643
0
        && (rv_chg_in_place(r) && (r->bsize >= len))) {
1644
0
    ret = r;
1645
0
    rv_ref(ret);
1646
0
    s1 = &rv1->v.s;
1647
0
    if(ret->v.s.s == &ret->buf[0])
1648
0
      s2 = &ret->v.s;
1649
0
    else {
1650
0
      tmp = ret->v.s;
1651
0
      flags = ret->flags;
1652
0
      ret->flags &= ~RV_CNT_ALLOCED_F;
1653
0
      ret->v.s.s = &ret->buf[0];
1654
0
      ret->v.s.len = 0;
1655
0
      s2 = &tmp;
1656
0
    }
1657
0
  } else {
1658
0
    ret = rval_new(RV_STR, &rv1->v, len + RV_STR_EXTRA);
1659
0
    if(unlikely(ret == 0)) {
1660
0
      LM_ERR("rv eval out of memory\n");
1661
0
      goto error;
1662
0
    }
1663
0
    s1 = 0;
1664
0
    s2 = &rv2->v.s;
1665
0
  }
1666
  /* do the actual copy */
1667
0
  memmove(ret->buf + rv1->v.s.len, s2->s, s2->len);
1668
0
  if(s1) {
1669
0
    memcpy(ret->buf, s1->s, s1->len);
1670
0
  }
1671
0
  ret->v.s.len = rv1->v.s.len + s2->len;
1672
0
  ret->v.s.s[ret->v.s.len] = 0;
1673
  /* cleanup if needed */
1674
0
  if(flags & RV_CNT_ALLOCED_F)
1675
0
    pkg_free(tmp.s);
1676
0
  rval_destroy(rv1);
1677
0
  rval_destroy(rv2);
1678
0
  return ret;
1679
0
error:
1680
0
  rval_destroy(rv1);
1681
0
  rval_destroy(rv2);
1682
0
  return 0;
1683
0
}
1684
1685
1686
/** bool operation on rval evaluated as strings.
1687
 * Can use cached rvalues (c1 & c2).
1688
 * @return 0 success, -1 on error
1689
 */
1690
inline static int rval_str_lop2(struct run_act_ctx *h, struct sip_msg *msg,
1691
    long *res, enum rval_expr_op op, struct rvalue *l,
1692
    struct rval_cache *c1, struct rvalue *r, struct rval_cache *c2)
1693
0
{
1694
0
  struct rvalue *rv1;
1695
0
  struct rvalue *rv2;
1696
0
  int ret;
1697
1698
0
  rv2 = rv1 = 0;
1699
0
  ret = 0;
1700
0
  if((rv1 = rval_convert(h, msg, RV_STR, l, c1)) == 0)
1701
0
    goto error;
1702
0
  if((rv2 = rval_convert(h, msg, RV_STR, r, c2)) == 0)
1703
0
    goto error;
1704
0
  ret = bool_rvstrop2(op, res, rv1, rv2);
1705
0
  rval_destroy(rv1);
1706
0
  rval_destroy(rv2);
1707
0
  return ret;
1708
0
error:
1709
0
  rval_destroy(rv1);
1710
0
  rval_destroy(rv2);
1711
0
  return 0;
1712
0
}
1713
1714
1715
/**
1716
 * @brief Integer operation on rval evaluated as string
1717
 *
1718
 * Integer operation on rval evaluated as string, can use cached
1719
 * rvalues (c1 & c2).
1720
 * @param h run action context
1721
 * @param msg SIP message
1722
 * @param res will be set to the result
1723
 * @param op rvalue expression operation
1724
 * @param l rvalue
1725
 * @param c1 rvalue cache
1726
 * @return 0 success, -1 on error
1727
 */
1728
inline static int rval_long_strop1(struct run_act_ctx *h, struct sip_msg *msg,
1729
    long *res, enum rval_expr_op op, struct rvalue *l,
1730
    struct rval_cache *c1)
1731
0
{
1732
0
  struct rvalue *rv1;
1733
0
  int ret;
1734
1735
0
  rv1 = 0;
1736
0
  ret = 0;
1737
0
  if((rv1 = rval_convert(h, msg, RV_STR, l, c1)) == 0)
1738
0
    goto error;
1739
0
  ret = long_strop1(res, op, &rv1->v.s);
1740
0
  rval_destroy(rv1);
1741
0
  return ret;
1742
0
error:
1743
0
  *res = 0;
1744
0
  rval_destroy(rv1);
1745
0
  return -1;
1746
0
}
1747
1748
1749
/**
1750
 * @brief Checks if rv is defined
1751
 * @param h run action context
1752
 * @param msg SIP message
1753
 * @param res set to the result 1 is defined, 0 not defined
1754
 * @param rv rvalue
1755
 * @param cache rvalue cache
1756
 * @return 0 on success, -1 on error
1757
 * @note Can use cached rvalues (cache). A rv can be undefined if it's
1758
 * an undefined avp or pvar or select or if it's NONE
1759
 * @note An error in the avp, pvar or select search is equivalent to
1760
 * undefined (and it's not reported)
1761
 */
1762
inline static int rv_defined(struct run_act_ctx *h, struct sip_msg *msg,
1763
    long *res, struct rvalue *rv, struct rval_cache *cache)
1764
0
{
1765
0
  avp_t *r_avp;
1766
0
  int_str avp_val;
1767
0
  pv_value_t pval;
1768
0
  str tmp;
1769
1770
0
  *res = 1;
1771
0
  switch(rv->type) {
1772
0
    case RV_SEL:
1773
0
      if(unlikely(cache && cache->cache_type == RV_CACHE_SELECT)) {
1774
0
        *res = (cache->val_type != RV_NONE);
1775
0
      } else
1776
        /* run select returns 0 on success, -1 on error and >0 on
1777
         * undefined. error is considered undefined */
1778
0
        *res = (run_select(&tmp, &rv->v.sel, msg) == 0);
1779
0
      break;
1780
0
    case RV_AVP:
1781
0
      if(unlikely(cache && cache->cache_type == RV_CACHE_AVP)) {
1782
0
        *res = (cache->val_type != RV_NONE);
1783
0
      } else {
1784
0
        r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
1785
0
            &avp_val, rv->v.avps.index);
1786
0
        if(unlikely(r_avp == 0)) {
1787
0
          *res = 0;
1788
0
        }
1789
0
      }
1790
0
      break;
1791
0
    case RV_PVAR:
1792
      /* PV_VAL_NULL or pv_get_spec_value error => undef */
1793
0
      if(unlikely(cache && cache->cache_type == RV_CACHE_PVAR)) {
1794
0
        *res = (cache->val_type != RV_NONE);
1795
0
      } else {
1796
0
        memset(&pval, 0, sizeof(pval));
1797
0
        if(likely(pv_get_spec_value(msg, &rv->v.pvs, &pval) == 0)) {
1798
0
          if((pval.flags & PV_VAL_NULL)
1799
0
              && !(pval.flags & (PV_VAL_INT | PV_VAL_STR))) {
1800
0
            *res = 0;
1801
0
          }
1802
0
          pv_value_destroy(&pval);
1803
0
        } else {
1804
0
          *res = 0; /* in case of error, consider it undef */
1805
0
        }
1806
0
      }
1807
0
      break;
1808
0
    case RV_NONE:
1809
0
      *res = 0;
1810
0
      break;
1811
0
    default:
1812
0
      break;
1813
0
  }
1814
0
  return 0;
1815
0
}
1816
1817
1818
/**
1819
 * @brief Defined (integer) operation on rve
1820
 * @param h run action context
1821
 * @param msg SIP message
1822
 * @param res - set to  1 defined, 0 not defined
1823
 * @param rve rvalue expression
1824
 * @return 0 on success, -1 on error
1825
 */
1826
inline static int long_rve_defined(struct run_act_ctx *h, struct sip_msg *msg,
1827
    long *res, struct rval_expr *rve)
1828
0
{
1829
  /* only a rval can be undefined, any expression consisting on more
1830
   * then one rval => defined */
1831
0
  if(likely(rve->op == RVE_RVAL_OP))
1832
0
    return rv_defined(h, msg, res, &rve->left.rval, 0);
1833
0
  *res = 1;
1834
0
  return 0;
1835
0
}
1836
1837
1838
/** evals a long expr to a long.
1839
 *
1840
 *  *res=(int)eval(rve)
1841
 *  @return 0 on success, \<0 on error
1842
 */
1843
int rval_expr_eval_long(struct run_act_ctx *h, struct sip_msg *msg, long *res,
1844
    struct rval_expr *rve)
1845
0
{
1846
0
  long i1, i2, ret;
1847
0
  struct rval_cache c1, c2;
1848
0
  struct rvalue *rv1;
1849
0
  struct rvalue *rv2;
1850
1851
0
  ret = -1;
1852
0
  switch(rve->op) {
1853
0
    case RVE_RVAL_OP:
1854
0
      ret = rval_get_long(h, msg, res, &rve->left.rval, 0);
1855
0
      rval_get_long_handle_ret(ret,
1856
0
          "rval expression conversion to int"
1857
0
          " failed",
1858
0
          rve);
1859
0
      break;
1860
0
    case RVE_UMINUS_OP:
1861
0
    case RVE_BOOL_OP:
1862
0
    case RVE_LNOT_OP:
1863
0
    case RVE_BNOT_OP:
1864
0
      if(unlikely((ret = rval_expr_eval_long(h, msg, &i1, rve->left.rve))
1865
0
            < 0))
1866
0
        break;
1867
0
      ret = long_longop1(res, rve->op, i1);
1868
0
      break;
1869
0
    case RVE_LONG_OP:
1870
0
      ret = rval_expr_eval_long(h, msg, res, rve->left.rve);
1871
0
      break;
1872
0
    case RVE_MUL_OP:
1873
0
    case RVE_DIV_OP:
1874
0
    case RVE_MOD_OP:
1875
0
    case RVE_MINUS_OP:
1876
0
    case RVE_PLUS_OP:
1877
0
    case RVE_IPLUS_OP:
1878
0
    case RVE_BOR_OP:
1879
0
    case RVE_BAND_OP:
1880
0
    case RVE_BXOR_OP:
1881
0
    case RVE_BLSHIFT_OP:
1882
0
    case RVE_BRSHIFT_OP:
1883
0
    case RVE_GT_OP:
1884
0
    case RVE_GTE_OP:
1885
0
    case RVE_LT_OP:
1886
0
    case RVE_LTE_OP:
1887
0
    case RVE_IEQ_OP:
1888
0
    case RVE_IDIFF_OP:
1889
0
      if(unlikely((ret = rval_expr_eval_long(h, msg, &i1, rve->left.rve))
1890
0
            < 0))
1891
0
        break;
1892
0
      if(unlikely((ret = rval_expr_eval_long(h, msg, &i2, rve->right.rve))
1893
0
            < 0))
1894
0
        break;
1895
0
      ret = long_longop2(res, rve->op, i1, i2);
1896
0
      break;
1897
0
    case RVE_LAND_OP:
1898
0
      if(unlikely((ret = rval_expr_eval_long(h, msg, &i1, rve->left.rve))
1899
0
            < 0))
1900
0
        break;
1901
0
      if(i1 == 0) {
1902
0
        *res = 0;
1903
0
      } else {
1904
0
        if(unlikely((ret = rval_expr_eval_long(
1905
0
                   h, msg, &i2, rve->right.rve))
1906
0
              < 0))
1907
0
          break;
1908
0
        *res = i1 && i2;
1909
0
      }
1910
0
      ret = 0;
1911
0
      break;
1912
0
    case RVE_LOR_OP:
1913
0
      if(unlikely((ret = rval_expr_eval_long(h, msg, &i1, rve->left.rve))
1914
0
            < 0))
1915
0
        break;
1916
0
      if(i1) {
1917
0
        *res = 1;
1918
0
      } else {
1919
0
        if(unlikely((ret = rval_expr_eval_long(
1920
0
                   h, msg, &i2, rve->right.rve))
1921
0
              < 0))
1922
0
          break;
1923
0
        *res = i1 || i2;
1924
0
      }
1925
0
      ret = 0;
1926
0
      break;
1927
0
    case RVE_EQ_OP:
1928
0
    case RVE_DIFF_OP:
1929
      /* if left is string, eval left & right as string and
1930
       *   use string diff.
1931
       * if left is int eval as int using int diff
1932
       * if left is undef, look at right and convert to right type
1933
       */
1934
0
      rval_cache_init(&c1);
1935
0
      if(unlikely((ret = rval_expr_eval_rvlong(
1936
0
                 h, msg, &rv1, &i1, rve->left.rve, &c1))
1937
0
            < 0)) {
1938
        /* error */
1939
0
        rval_cache_clean(&c1);
1940
0
        break;
1941
0
      }
1942
0
      if(likely(rv1 == 0)) {
1943
        /* int */
1944
0
        rval_cache_clean(&c1);
1945
0
        if(unlikely((ret = rval_expr_eval_long(
1946
0
                   h, msg, &i2, rve->right.rve))
1947
0
              < 0))
1948
0
          break; /* error */
1949
0
        ret = long_longop2(res, rve->op, i1, i2);
1950
0
      } else {
1951
        /* not int => str or undef */
1952
        /* check for undefined left operand */
1953
0
        if(unlikely(c1.cache_type != RV_CACHE_EMPTY
1954
0
              && c1.val_type == RV_NONE)) {
1955
#ifdef UNDEF_EQ_ALWAYS_FALSE
1956
          /* undef == something  always false
1957
           * undef != something  always true*/
1958
          ret = (rve->op == RVE_DIFF_OP);
1959
#elif defined UNDEF_EQ_UNDEF_TRUE
1960
          /* undef == something defined always false
1961
           * undef == undef true */
1962
          if(int_rve_defined(h, msg, &i2, rve->right.rve) < 0) {
1963
            /* error */
1964
            rval_cache_clean(&c1);
1965
            rval_destroy(rv1);
1966
            break;
1967
          }
1968
          ret = (!i2) ^ (rve->op == RVE_DIFF_OP);
1969
#else  /* ! UNDEF_EQ_* */
1970
          /*  undef == val
1971
           *  => convert to (type_of(val)) (undef) == val */
1972
0
          rval_cache_init(&c2);
1973
0
          if(unlikely((ret = rval_expr_eval_rvlong(h, msg, &rv2, &i2,
1974
0
                     rve->right.rve, &c2))
1975
0
                < 0)) {
1976
            /* error */
1977
0
            rval_cache_clean(&c1);
1978
0
            rval_cache_clean(&c2);
1979
0
            rval_destroy(rv1);
1980
0
            break;
1981
0
          }
1982
0
          if(rv2 == 0) {
1983
            /* int */
1984
0
            ret = long_longop2(res, rve->op, 0 /* undef */, i2);
1985
0
          } else {
1986
            /* str or undef */
1987
0
            ret = rval_str_lop2(
1988
0
                h, msg, res, rve->op, rv1, &c1, rv2, &c2);
1989
0
            rval_cache_clean(&c2);
1990
0
            rval_destroy(rv2);
1991
0
          }
1992
0
#endif /* UNDEF_EQ_* */
1993
0
          rval_cache_clean(&c1);
1994
0
          rval_destroy(rv1);
1995
0
        } else {
1996
          /* left value == defined and != int => str
1997
           * => lval == (str) val */
1998
0
          if(unlikely((rv2 = rval_expr_eval(h, msg, rve->right.rve))
1999
0
                == 0)) {
2000
            /* error */
2001
0
            rval_destroy(rv1);
2002
0
            rval_cache_clean(&c1);
2003
0
            break;
2004
0
          }
2005
0
          ret = rval_str_lop2(h, msg, res, rve->op, rv1, &c1, rv2, 0);
2006
0
          rval_cache_clean(&c1);
2007
0
          rval_destroy(rv1);
2008
0
          rval_destroy(rv2);
2009
0
        }
2010
0
      }
2011
0
      break;
2012
0
    case RVE_CONCAT_OP:
2013
      /* eval expression => string */
2014
0
      if(unlikely((rv1 = rval_expr_eval(h, msg, rve)) == 0)) {
2015
0
        ret = -1;
2016
0
        break;
2017
0
      }
2018
      /* convert to int */
2019
0
      ret = rval_get_long(h, msg, res, rv1, 0); /* convert to int */
2020
0
      rval_get_long_handle_ret(ret,
2021
0
          "rval expression conversion to int"
2022
0
          " failed",
2023
0
          rve);
2024
0
      rval_destroy(rv1);
2025
0
      break;
2026
0
    case RVE_STR_OP:
2027
      /* (str)expr => eval expression */
2028
0
      rval_cache_init(&c1);
2029
0
      if(unlikely((ret = rval_expr_eval_rvlong(
2030
0
                 h, msg, &rv1, res, rve->left.rve, &c1))
2031
0
            < 0)) {
2032
        /* error */
2033
0
        rval_cache_clean(&c1);
2034
0
        break;
2035
0
      }
2036
0
      if(unlikely(rv1)) {
2037
        /* expr evaluated to string => (int)(str)v == (int)v */
2038
0
        ret = rval_get_long(h, msg, res, rv1, &c1); /* convert to int */
2039
0
        rval_get_long_handle_ret(ret,
2040
0
            "rval expression conversion"
2041
0
            " to int failed",
2042
0
            rve);
2043
0
        rval_destroy(rv1);
2044
0
        rval_cache_clean(&c1);
2045
0
      }
2046
0
      break;
2047
2048
0
    case RVE_DEFINED_OP:
2049
0
      ret = long_rve_defined(h, msg, res, rve->left.rve);
2050
0
      break;
2051
0
    case RVE_NOTDEFINED_OP:
2052
0
      ret = long_rve_defined(h, msg, res, rve->left.rve);
2053
0
      *res = !(*res);
2054
0
      break;
2055
0
    case RVE_STREQ_OP:
2056
0
    case RVE_STRDIFF_OP:
2057
0
    case RVE_MATCH_OP:
2058
0
      if(unlikely((rv1 = rval_expr_eval(h, msg, rve->left.rve)) == 0)) {
2059
0
        ret = -1;
2060
0
        break;
2061
0
      }
2062
0
      if(unlikely((rv2 = rval_expr_eval(h, msg, rve->right.rve)) == 0)) {
2063
0
        rval_destroy(rv1);
2064
0
        ret = -1;
2065
0
        break;
2066
0
      }
2067
0
      ret = rval_str_lop2(h, msg, res, rve->op, rv1, 0, rv2, 0);
2068
0
      rval_destroy(rv1);
2069
0
      rval_destroy(rv2);
2070
0
      break;
2071
0
    case RVE_STRLEN_OP:
2072
0
    case RVE_STREMPTY_OP:
2073
0
      if(unlikely((rv1 = rval_expr_eval(h, msg, rve->left.rve)) == 0)) {
2074
0
        ret = -1;
2075
0
        break;
2076
0
      }
2077
0
      ret = rval_long_strop1(h, msg, res, rve->op, rv1, 0);
2078
0
      rval_destroy(rv1);
2079
0
      break;
2080
0
    case RVE_SELVALEXP_OP:
2081
0
    case RVE_SELVALOPT_OP:
2082
0
      LM_BUG("invalid selval int expression operation %d (%d,%d-%d,%d)\n",
2083
0
          rve->op, rve->fpos.s_line, rve->fpos.s_col,
2084
0
          rve->fpos.e_line, rve->fpos.e_col);
2085
0
      ret = -1;
2086
0
      break;
2087
0
    case RVE_NONE_OP:
2088
      /*default:*/
2089
0
      LM_BUG("invalid rval int expression operation %d (%d,%d-%d,%d)\n",
2090
0
          rve->op, rve->fpos.s_line, rve->fpos.s_col,
2091
0
          rve->fpos.e_line, rve->fpos.e_col);
2092
0
      ret = -1;
2093
0
  };
2094
0
  return ret;
2095
0
}
2096
2097
2098
/**
2099
 * @brief Evals a rval expression into an int or another rv(str)
2100
 * @warning rv result (rv_res) must be rval_destroy()'ed if non-null
2101
 * (it might be a reference to another rval). The result can be
2102
 * modified only if rv_chg_in_place() returns true.
2103
 * @param h run action context
2104
 * @param msg SIP message
2105
 * @param res_rv pointer to rvalue result, if non-null it means the
2106
 * expression evaluated to a non-int (str), which will be stored here.
2107
 * @param res_i pointer to int result, if res_rv==0 and the function
2108
 * returns success => the result is an int which will be stored here.
2109
 * @param rve expression that will be evaluated.
2110
 * @param cache write-only value cache, it might be filled if non-null and
2111
 * empty (rval_cache_init()). If non-null, it _must_ be rval_cache_clean()'ed
2112
 * when done.
2113
 * @return 0 on success, -1 on error, sets *res_rv or *res_i.
2114
 */
2115
int rval_expr_eval_rvlong(struct run_act_ctx *h, struct sip_msg *msg,
2116
    struct rvalue **res_rv, long *res_i, struct rval_expr *rve,
2117
    struct rval_cache *cache)
2118
0
{
2119
0
  struct rvalue *rv1;
2120
0
  struct rvalue *rv2;
2121
0
  struct rval_cache c1; /* local cache */
2122
0
  int ret;
2123
0
  long r, i, j;
2124
0
  enum rval_type type;
2125
2126
0
  rv1 = 0;
2127
0
  rv2 = 0;
2128
0
  ret = -1;
2129
0
  switch(rve->op) {
2130
0
    case RVE_RVAL_OP:
2131
0
      rv1 = &rve->left.rval;
2132
0
      rv_ref(rv1);
2133
0
      type = rval_get_btype(h, msg, rv1, cache);
2134
0
      if(type == RV_LONG) {
2135
0
        r = rval_get_long(h, msg, res_i, rv1, cache);
2136
0
        rval_get_long_handle_ret(r,
2137
0
            "rval expression conversion"
2138
0
            " to int failed",
2139
0
            rve);
2140
0
        *res_rv = 0;
2141
0
        ret = r; /* equiv. to if (r<0) goto error */
2142
0
      } else {
2143
        /* RV_STR, RV_PVAR, RV_AVP a.s.o => return rv1 and the
2144
         * cached resolved value in cache*/
2145
0
        *res_rv = rv1;
2146
0
        rv_ref(rv1);
2147
0
        ret = 0;
2148
0
      }
2149
0
      break;
2150
0
    case RVE_UMINUS_OP:
2151
0
    case RVE_BOOL_OP:
2152
0
    case RVE_LNOT_OP:
2153
0
    case RVE_BNOT_OP:
2154
0
    case RVE_MINUS_OP:
2155
0
    case RVE_MUL_OP:
2156
0
    case RVE_DIV_OP:
2157
0
    case RVE_MOD_OP:
2158
0
    case RVE_BOR_OP:
2159
0
    case RVE_BAND_OP:
2160
0
    case RVE_BXOR_OP:
2161
0
    case RVE_BLSHIFT_OP:
2162
0
    case RVE_BRSHIFT_OP:
2163
0
    case RVE_LAND_OP:
2164
0
    case RVE_LOR_OP:
2165
0
    case RVE_GT_OP:
2166
0
    case RVE_GTE_OP:
2167
0
    case RVE_LT_OP:
2168
0
    case RVE_LTE_OP:
2169
0
    case RVE_EQ_OP:
2170
0
    case RVE_DIFF_OP:
2171
0
    case RVE_IEQ_OP:
2172
0
    case RVE_IDIFF_OP:
2173
0
    case RVE_IPLUS_OP:
2174
0
    case RVE_STREQ_OP:
2175
0
    case RVE_STRDIFF_OP:
2176
0
    case RVE_MATCH_OP:
2177
0
    case RVE_STRLEN_OP:
2178
0
    case RVE_STREMPTY_OP:
2179
0
    case RVE_DEFINED_OP:
2180
0
    case RVE_NOTDEFINED_OP:
2181
0
    case RVE_LONG_OP:
2182
      /* operator forces integer type */
2183
0
      ret = rval_expr_eval_long(h, msg, res_i, rve);
2184
0
      *res_rv = 0;
2185
0
      break;
2186
0
    case RVE_PLUS_OP:
2187
0
      rval_cache_init(&c1);
2188
0
      r = rval_expr_eval_rvlong(h, msg, &rv1, &i, rve->left.rve, &c1);
2189
0
      if(unlikely(r < 0)) {
2190
0
        LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2191
0
            rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2192
0
            rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
2193
0
        rval_cache_clean(&c1);
2194
0
        goto error;
2195
0
      }
2196
0
      if(rv1 == 0) {
2197
0
        if(unlikely(
2198
0
               (r = rval_expr_eval_long(h, msg, &j, rve->right.rve))
2199
0
               < 0)) {
2200
0
          LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)"
2201
0
               "\n",
2202
0
              rve->right.rve->fpos.s_line,
2203
0
              rve->right.rve->fpos.s_col,
2204
0
              rve->right.rve->fpos.e_line,
2205
0
              rve->right.rve->fpos.e_col);
2206
0
          rval_cache_clean(&c1);
2207
0
          goto error;
2208
0
        }
2209
0
        ret = long_longop2(res_i, rve->op, i, j);
2210
0
        *res_rv = 0;
2211
0
      } else {
2212
0
        rv2 = rval_expr_eval(h, msg, rve->right.rve);
2213
0
        if(unlikely(rv2 == 0)) {
2214
0
          LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2215
0
              rve->right.rve->fpos.s_line,
2216
0
              rve->right.rve->fpos.s_col,
2217
0
              rve->right.rve->fpos.e_line,
2218
0
              rve->right.rve->fpos.e_col);
2219
0
          rval_cache_clean(&c1);
2220
0
          goto error;
2221
0
        }
2222
0
        *res_rv = rval_str_add2(h, msg, rv1, &c1, rv2, 0);
2223
0
        ret = -(*res_rv == 0);
2224
0
      }
2225
0
      rval_cache_clean(&c1);
2226
0
      break;
2227
0
    case RVE_CONCAT_OP:
2228
0
    case RVE_STR_OP:
2229
0
      *res_rv = rval_expr_eval(h, msg, rve);
2230
0
      ret = -(*res_rv == 0);
2231
0
      break;
2232
0
    case RVE_SELVALEXP_OP:
2233
0
    case RVE_SELVALOPT_OP:
2234
0
      LM_BUG("invalid rval selval expression operation %d "
2235
0
           "(%d,%d-%d,%d)\n",
2236
0
          rve->op, rve->fpos.s_line, rve->fpos.s_col,
2237
0
          rve->fpos.e_line, rve->fpos.e_col);
2238
0
      goto error;
2239
0
    case RVE_NONE_OP:
2240
      /*default:*/
2241
0
      LM_BUG("invalid rval expression operation %d (%d,%d-%d,%d)\n",
2242
0
          rve->op, rve->fpos.s_line, rve->fpos.s_col,
2243
0
          rve->fpos.e_line, rve->fpos.e_col);
2244
0
      goto error;
2245
0
  };
2246
0
  rval_destroy(rv1);
2247
0
  rval_destroy(rv2);
2248
0
  return ret;
2249
0
error:
2250
0
  rval_destroy(rv1);
2251
0
  rval_destroy(rv2);
2252
0
  return -1;
2253
0
}
2254
2255
2256
/**
2257
 * @brief Evals a rval expression
2258
 * @warning result must be rval_destroy()'ed if non-null (it might be
2259
 * a reference to another rval). The result can be modified only
2260
 * if rv_chg_in_place() returns true.
2261
 * @param h run action context
2262
 * @param msg SIP message
2263
 * @param rve rvalue expression
2264
 * @return rvalue on success, 0 on error
2265
 */
2266
struct rvalue *rval_expr_eval(
2267
    struct run_act_ctx *h, struct sip_msg *msg, struct rval_expr *rve)
2268
0
{
2269
0
  struct rvalue *rv1;
2270
0
  struct rvalue *rv2;
2271
0
  struct rvalue *ret;
2272
0
  struct rval_cache c1;
2273
0
  union rval_val v;
2274
0
  long r, i, j;
2275
0
  enum rval_type type;
2276
2277
0
  rv1 = 0;
2278
0
  rv2 = 0;
2279
0
  ret = 0;
2280
0
  switch(rve->op) {
2281
0
    case RVE_RVAL_OP:
2282
0
      rv_ref(&rve->left.rval);
2283
0
      return &rve->left.rval;
2284
0
      break;
2285
0
    case RVE_UMINUS_OP:
2286
0
    case RVE_BOOL_OP:
2287
0
    case RVE_LNOT_OP:
2288
0
    case RVE_BNOT_OP:
2289
0
    case RVE_MINUS_OP:
2290
0
    case RVE_MUL_OP:
2291
0
    case RVE_DIV_OP:
2292
0
    case RVE_MOD_OP:
2293
0
    case RVE_BOR_OP:
2294
0
    case RVE_BAND_OP:
2295
0
    case RVE_BXOR_OP:
2296
0
    case RVE_BLSHIFT_OP:
2297
0
    case RVE_BRSHIFT_OP:
2298
0
    case RVE_LAND_OP:
2299
0
    case RVE_LOR_OP:
2300
0
    case RVE_GT_OP:
2301
0
    case RVE_GTE_OP:
2302
0
    case RVE_LT_OP:
2303
0
    case RVE_LTE_OP:
2304
0
    case RVE_EQ_OP:
2305
0
    case RVE_DIFF_OP:
2306
0
    case RVE_IEQ_OP:
2307
0
    case RVE_IDIFF_OP:
2308
0
    case RVE_IPLUS_OP:
2309
0
    case RVE_STREQ_OP:
2310
0
    case RVE_STRDIFF_OP:
2311
0
    case RVE_MATCH_OP:
2312
0
    case RVE_STRLEN_OP:
2313
0
    case RVE_STREMPTY_OP:
2314
0
    case RVE_DEFINED_OP:
2315
0
    case RVE_NOTDEFINED_OP:
2316
0
    case RVE_LONG_OP:
2317
      /* operator forces integer type */
2318
0
      r = rval_expr_eval_long(h, msg, &i, rve);
2319
0
      if(likely(r == 0)) {
2320
0
        v.l = i;
2321
0
        ret = rval_new(RV_LONG, &v, 0);
2322
0
        if(unlikely(ret == 0)) {
2323
0
          LM_ERR("rv eval int expression: out of memory\n");
2324
0
          goto error;
2325
0
        }
2326
0
        return ret;
2327
0
      } else {
2328
0
        LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2329
0
            rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
2330
0
            rve->fpos.e_col);
2331
0
        goto error;
2332
0
      }
2333
0
      break;
2334
0
    case RVE_PLUS_OP:
2335
0
      rv1 = rval_expr_eval(h, msg, rve->left.rve);
2336
0
      if(unlikely(rv1 == 0)) {
2337
0
        LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2338
0
            rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2339
0
            rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
2340
0
        goto error;
2341
0
      }
2342
0
      rval_cache_init(&c1);
2343
0
      type = rval_get_btype(h, msg, rv1, &c1);
2344
0
      switch(type) {
2345
0
        case RV_LONG:
2346
0
          r = rval_get_long(h, msg, &i, rv1, &c1);
2347
0
          rval_get_long_handle_ret(r,
2348
0
              "rval expression left side "
2349
0
              "conversion to int failed",
2350
0
              rve);
2351
0
          if(unlikely(r < 0)) {
2352
0
            rval_cache_clean(&c1);
2353
0
            goto error;
2354
0
          }
2355
0
          if(unlikely((r = rval_expr_eval_long(
2356
0
                     h, msg, &j, rve->right.rve))
2357
0
                < 0)) {
2358
0
            rval_cache_clean(&c1);
2359
0
            LM_ERR("rval expression evaluation failed "
2360
0
                 "(%d,%d-%d,%d):"
2361
0
                 " could not evaluate right side to int\n",
2362
0
                rve->fpos.s_line, rve->fpos.s_col,
2363
0
                rve->fpos.e_line, rve->fpos.e_col);
2364
0
            goto error;
2365
0
          }
2366
0
          long_longop2(&r, rve->op, i, j);
2367
0
          if(rv_chg_in_place(rv1)) {
2368
0
            rv1->v.l = r;
2369
0
            ret = rv1;
2370
0
            rv_ref(ret);
2371
0
          } else {
2372
0
            v.l = r;
2373
0
            ret = rval_new(RV_LONG, &v, 0);
2374
0
            if(unlikely(ret == 0)) {
2375
0
              rval_cache_clean(&c1);
2376
0
              LM_ERR("rv eval int expression: out of memory\n");
2377
0
              goto error;
2378
0
            }
2379
0
          }
2380
0
          break;
2381
0
        case RV_STR:
2382
0
        case RV_NONE:
2383
0
          rv2 = rval_expr_eval(h, msg, rve->right.rve);
2384
0
          if(unlikely(rv2 == 0)) {
2385
0
            LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)"
2386
0
                 "\n",
2387
0
                rve->right.rve->fpos.s_line,
2388
0
                rve->right.rve->fpos.s_col,
2389
0
                rve->right.rve->fpos.e_line,
2390
0
                rve->right.rve->fpos.e_col);
2391
0
            rval_cache_clean(&c1);
2392
0
            goto error;
2393
0
          }
2394
0
          ret = rval_str_add2(h, msg, rv1, &c1, rv2, 0);
2395
0
          break;
2396
0
        default:
2397
0
          LM_BUG("rv unsupported basic type %d (%d,%d-%d,%d)\n", type,
2398
0
              rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
2399
0
              rve->fpos.e_col);
2400
0
      }
2401
0
      rval_cache_clean(&c1);
2402
0
      break;
2403
0
    case RVE_CONCAT_OP:
2404
0
      rv1 = rval_expr_eval(h, msg, rve->left.rve);
2405
0
      if(unlikely(rv1 == 0)) {
2406
0
        LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2407
0
            rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2408
0
            rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
2409
0
        goto error;
2410
0
      }
2411
0
      rv2 = rval_expr_eval(h, msg, rve->right.rve);
2412
0
      if(unlikely(rv2 == 0)) {
2413
0
        LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2414
0
            rve->right.rve->fpos.s_line, rve->right.rve->fpos.s_col,
2415
0
            rve->right.rve->fpos.e_line,
2416
0
            rve->right.rve->fpos.e_col);
2417
0
        goto error;
2418
0
      }
2419
0
      ret = rval_str_add2(h, msg, rv1, 0, rv2, 0);
2420
0
      break;
2421
0
    case RVE_STR_OP:
2422
0
      rv1 = rval_expr_eval(h, msg, rve->left.rve);
2423
0
      if(unlikely(rv1 == 0)) {
2424
0
        LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2425
0
            rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2426
0
            rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
2427
0
        goto error;
2428
0
      }
2429
0
      ret = rval_convert(h, msg, RV_STR, rv1, 0);
2430
0
      break;
2431
0
    case RVE_SELVALEXP_OP:
2432
      /* operator forces integer type */
2433
0
      r = rval_expr_eval_long(h, msg, &i, rve->left.rve);
2434
0
      if(unlikely(r != 0)) {
2435
0
        LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2436
0
            rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
2437
0
            rve->fpos.e_col);
2438
0
        goto error;
2439
0
      }
2440
0
      if(i > 0) {
2441
0
        rv1 = rval_expr_eval(h, msg, rve->right.rve->left.rve);
2442
0
      } else {
2443
0
        rv1 = rval_expr_eval(h, msg, rve->right.rve->right.rve);
2444
0
      }
2445
0
      if(unlikely(rv1 == 0)) {
2446
0
        LM_ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2447
0
            rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2448
0
            rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
2449
0
        goto error;
2450
0
      }
2451
0
      rval_cache_init(&c1);
2452
0
      type = rval_get_btype(h, msg, rv1, &c1);
2453
0
      switch(type) {
2454
0
        case RV_LONG:
2455
0
          r = rval_get_long(h, msg, &i, rv1, &c1);
2456
0
          rval_get_long_handle_ret(r,
2457
0
              "rval expression left side "
2458
0
              "conversion to int failed",
2459
0
              rve);
2460
0
          if(unlikely(r < 0)) {
2461
0
            rval_cache_clean(&c1);
2462
0
            goto error;
2463
0
          }
2464
0
          v.l = i;
2465
0
          ret = rval_new(RV_LONG, &v, 0);
2466
0
          if(unlikely(ret == 0)) {
2467
0
            rval_cache_clean(&c1);
2468
0
            LM_ERR("rv eval int expression: out of memory\n");
2469
0
            goto error;
2470
0
          }
2471
0
          break;
2472
0
        case RV_STR:
2473
0
        case RV_NONE:
2474
0
          ret = rval_convert(h, msg, RV_STR, rv1, 0);
2475
0
          break;
2476
0
        default:
2477
0
          LM_BUG("rv unsupported basic type %d (%d,%d-%d,%d)\n", type,
2478
0
              rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
2479
0
              rve->fpos.e_col);
2480
0
      }
2481
0
      rval_cache_clean(&c1);
2482
0
      break;
2483
0
    case RVE_SELVALOPT_OP:
2484
0
      break;
2485
0
    case RVE_NONE_OP:
2486
      /*default:*/
2487
0
      LM_BUG("invalid rval expression operation %d (%d,%d-%d,%d)\n",
2488
0
          rve->op, rve->fpos.s_line, rve->fpos.s_col,
2489
0
          rve->fpos.e_line, rve->fpos.e_col);
2490
0
      goto error;
2491
0
  };
2492
0
  rval_destroy(rv1);
2493
0
  rval_destroy(rv2);
2494
0
  return ret;
2495
0
error:
2496
0
  rval_destroy(rv1);
2497
0
  rval_destroy(rv2);
2498
0
  return 0;
2499
0
}
2500
2501
2502
/** evals a rval expr and always returns a new rval.
2503
 * like rval_expr_eval, but always returns a new rvalue (never a reference
2504
 * to an existing one).
2505
 * WARNING: result must be rval_destroy()'ed if non-null (it might be
2506
 * a reference to another rval). The result can be modified only
2507
 * if rv_chg_in_place() returns true.
2508
 * @result rvalue on success, 0 on error
2509
 */
2510
struct rvalue *rval_expr_eval_new(
2511
    struct run_act_ctx *h, struct sip_msg *msg, struct rval_expr *rve)
2512
0
{
2513
0
  struct rvalue *ret;
2514
0
  struct rvalue *rv;
2515
2516
0
  ret = rval_expr_eval(h, msg, rve);
2517
0
  if(ret && !rv_chg_in_place(ret)) {
2518
0
    rv = ret;
2519
    /* create a new rv */
2520
0
    ret = rval_new(rv->type, &rv->v, 0);
2521
0
    rval_destroy(rv);
2522
0
  }
2523
0
  return ret;
2524
0
}
2525
2526
2527
/** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type.
2528
 *
2529
 * @param rv_type - rval type
2530
 * @param val     - rval value
2531
 * @param pos     - config position
2532
 * @return new pkg_malloc'ed rval_expr or 0 on error.
2533
 */
2534
struct rval_expr *mk_rval_expr_v(
2535
    enum rval_type rv_type, void *val, struct cfg_pos *pos)
2536
0
{
2537
0
  struct rval_expr *rve;
2538
0
  union rval_val v;
2539
0
  str *s;
2540
0
  int flags;
2541
2542
0
  rve = pkg_malloc(sizeof(*rve));
2543
0
  if(rve == 0) {
2544
0
    PKG_MEM_ERROR;
2545
0
    return 0;
2546
0
  }
2547
0
  memset(rve, 0, sizeof(*rve));
2548
0
  flags = 0;
2549
0
  switch(rv_type) {
2550
0
    case RV_LONG:
2551
0
      v.l = (long)val;
2552
0
      break;
2553
0
    case RV_STR:
2554
0
      s = (str *)val;
2555
0
      v.s.s = pkg_malloc(s->len + 1 /*0*/);
2556
0
      if(v.s.s == 0) {
2557
0
        pkg_free(rve);
2558
0
        PKG_MEM_ERROR;
2559
0
        return 0;
2560
0
      }
2561
0
      v.s.len = s->len;
2562
0
      memcpy(v.s.s, s->s, s->len);
2563
0
      v.s.s[s->len] = 0;
2564
0
      flags = RV_CNT_ALLOCED_F;
2565
0
      break;
2566
0
    case RV_AVP:
2567
0
      v.avps = *(avp_spec_t *)val;
2568
0
      break;
2569
0
    case RV_PVAR:
2570
0
      v.pvs = *(pv_spec_t *)val;
2571
0
      break;
2572
0
    case RV_SEL:
2573
0
      v.sel = *(select_t *)val;
2574
0
      break;
2575
0
    case RV_BEXPR:
2576
0
      v.bexpr = (struct expr *)val;
2577
0
      break;
2578
0
    case RV_ACTION_ST:
2579
0
      v.action = (struct action *)val;
2580
0
      break;
2581
0
    default:
2582
0
      LM_BUG("unsupported rv type %d\n", rv_type);
2583
0
      pkg_free(rve);
2584
0
      return 0;
2585
0
  }
2586
0
  rval_init(&rve->left.rval, rv_type, &v, flags);
2587
0
  rve->op = RVE_RVAL_OP;
2588
0
  if(pos)
2589
0
    rve->fpos = *pos;
2590
0
  return rve;
2591
0
}
2592
2593
2594
/**
2595
 * @brief Create an unary op. rval_expr
2596
 * ret= op rve1
2597
 * @param op   - rval expr. unary operator
2598
 * @param rve1 - rval expr. on which the operator will act.
2599
 * @param pos configuration position
2600
 * @return new pkg_malloc'ed rval_expr or 0 on error.
2601
 */
2602
struct rval_expr *mk_rval_expr1(
2603
    enum rval_expr_op op, struct rval_expr *rve1, struct cfg_pos *pos)
2604
0
{
2605
0
  struct rval_expr *ret;
2606
2607
0
  switch(op) {
2608
0
    case RVE_UMINUS_OP:
2609
0
    case RVE_BOOL_OP:
2610
0
    case RVE_LNOT_OP:
2611
0
    case RVE_BNOT_OP:
2612
0
    case RVE_STRLEN_OP:
2613
0
    case RVE_STREMPTY_OP:
2614
0
    case RVE_DEFINED_OP:
2615
0
    case RVE_NOTDEFINED_OP:
2616
0
    case RVE_LONG_OP:
2617
0
    case RVE_STR_OP:
2618
0
      break;
2619
0
    default:
2620
0
      LM_BUG("unsupported unary operator %d\n", op);
2621
0
      return 0;
2622
0
  }
2623
0
  ret = pkg_malloc(sizeof(*ret));
2624
0
  if(ret == 0) {
2625
0
    PKG_MEM_ERROR;
2626
0
    return 0;
2627
0
  }
2628
0
  memset(ret, 0, sizeof(*ret));
2629
0
  ret->op = op;
2630
0
  ret->left.rve = rve1;
2631
0
  if(pos)
2632
0
    ret->fpos = *pos;
2633
0
  return ret;
2634
0
}
2635
2636
2637
/**
2638
 * @brief Create a rval_expr. from 2 other rval exprs, using op
2639
 * ret = rve1 op rve2
2640
 * @param op   - rval expr. operator
2641
 * @param rve1 - rval expr. on which the operator will act.
2642
 * @param rve2 - rval expr. on which the operator will act.
2643
 * @param pos configuration position
2644
 * @return new pkg_malloc'ed rval_expr or 0 on error.
2645
 */
2646
struct rval_expr *mk_rval_expr2(enum rval_expr_op op, struct rval_expr *rve1,
2647
    struct rval_expr *rve2, struct cfg_pos *pos)
2648
0
{
2649
0
  struct rval_expr *ret;
2650
2651
0
  switch(op) {
2652
0
    case RVE_MUL_OP:
2653
0
    case RVE_DIV_OP:
2654
0
    case RVE_MOD_OP:
2655
0
    case RVE_MINUS_OP:
2656
0
    case RVE_BOR_OP:
2657
0
    case RVE_BAND_OP:
2658
0
    case RVE_BXOR_OP:
2659
0
    case RVE_BLSHIFT_OP:
2660
0
    case RVE_BRSHIFT_OP:
2661
0
    case RVE_LAND_OP:
2662
0
    case RVE_LOR_OP:
2663
0
    case RVE_GT_OP:
2664
0
    case RVE_GTE_OP:
2665
0
    case RVE_LT_OP:
2666
0
    case RVE_LTE_OP:
2667
0
    case RVE_PLUS_OP:
2668
0
    case RVE_IPLUS_OP:
2669
0
    case RVE_EQ_OP:
2670
0
    case RVE_DIFF_OP:
2671
0
    case RVE_IEQ_OP:
2672
0
    case RVE_IDIFF_OP:
2673
0
    case RVE_STREQ_OP:
2674
0
    case RVE_STRDIFF_OP:
2675
0
    case RVE_MATCH_OP:
2676
0
    case RVE_CONCAT_OP:
2677
0
    case RVE_SELVALEXP_OP:
2678
0
    case RVE_SELVALOPT_OP:
2679
0
      break;
2680
0
    default:
2681
0
      LM_BUG("unsupported operator %d\n", op);
2682
0
      return 0;
2683
0
  }
2684
0
  ret = pkg_malloc(sizeof(*ret));
2685
0
  if(ret == 0) {
2686
0
    PKG_MEM_ERROR;
2687
0
    return 0;
2688
0
  }
2689
0
  memset(ret, 0, sizeof(*ret));
2690
0
  ret->op = op;
2691
0
  ret->left.rve = rve1;
2692
0
  ret->right.rve = rve2;
2693
0
  if(pos)
2694
0
    ret->fpos = *pos;
2695
0
  return ret;
2696
0
}
2697
2698
2699
/** returns true if the operator is associative. */
2700
static int rve_op_is_assoc(enum rval_expr_op op)
2701
0
{
2702
0
  switch(op) {
2703
0
    case RVE_NONE_OP:
2704
0
    case RVE_RVAL_OP:
2705
0
    case RVE_UMINUS_OP:
2706
0
    case RVE_BOOL_OP:
2707
0
    case RVE_LNOT_OP:
2708
0
    case RVE_BNOT_OP:
2709
0
    case RVE_STRLEN_OP:
2710
0
    case RVE_STREMPTY_OP:
2711
0
    case RVE_DEFINED_OP:
2712
0
    case RVE_NOTDEFINED_OP:
2713
0
    case RVE_LONG_OP:
2714
0
    case RVE_STR_OP:
2715
      /* one operand expression => cannot be assoc. */
2716
0
      return 0;
2717
0
    case RVE_DIV_OP:
2718
0
    case RVE_MOD_OP:
2719
0
    case RVE_MINUS_OP:
2720
0
    case RVE_BLSHIFT_OP:
2721
0
    case RVE_BRSHIFT_OP:
2722
0
      return 0;
2723
0
    case RVE_PLUS_OP:
2724
      /* the generic plus is not assoc, e.g.
2725
       * "a" + 1 + "2" => "a12" in one case and "a3" in the other */
2726
0
      return 0;
2727
0
    case RVE_IPLUS_OP:
2728
0
    case RVE_CONCAT_OP:
2729
0
    case RVE_MUL_OP:
2730
0
    case RVE_BAND_OP:
2731
0
    case RVE_BOR_OP:
2732
0
    case RVE_BXOR_OP:
2733
0
      return 1;
2734
0
    case RVE_LAND_OP:
2735
0
    case RVE_LOR_OP:
2736
0
      return 1;
2737
0
    case RVE_GT_OP:
2738
0
    case RVE_GTE_OP:
2739
0
    case RVE_LT_OP:
2740
0
    case RVE_LTE_OP:
2741
0
    case RVE_EQ_OP:
2742
0
    case RVE_DIFF_OP:
2743
0
    case RVE_IEQ_OP:
2744
0
    case RVE_IDIFF_OP:
2745
0
    case RVE_STREQ_OP:
2746
0
    case RVE_STRDIFF_OP:
2747
0
    case RVE_MATCH_OP:
2748
0
    case RVE_SELVALEXP_OP:
2749
0
    case RVE_SELVALOPT_OP:
2750
0
      return 0;
2751
0
  }
2752
0
  return 0;
2753
0
}
2754
2755
2756
/** returns true if the operator is commutative. */
2757
static int rve_op_is_commutative(enum rval_expr_op op)
2758
0
{
2759
0
  switch(op) {
2760
0
    case RVE_NONE_OP:
2761
0
    case RVE_RVAL_OP:
2762
0
    case RVE_UMINUS_OP:
2763
0
    case RVE_BOOL_OP:
2764
0
    case RVE_LNOT_OP:
2765
0
    case RVE_BNOT_OP:
2766
0
    case RVE_STRLEN_OP:
2767
0
    case RVE_STREMPTY_OP:
2768
0
    case RVE_DEFINED_OP:
2769
0
    case RVE_NOTDEFINED_OP:
2770
0
    case RVE_LONG_OP:
2771
0
    case RVE_STR_OP:
2772
      /* one operand expression => cannot be commut. */
2773
0
      return 0;
2774
0
    case RVE_DIV_OP:
2775
0
    case RVE_MOD_OP:
2776
0
    case RVE_MINUS_OP:
2777
0
    case RVE_BLSHIFT_OP:
2778
0
    case RVE_BRSHIFT_OP:
2779
0
      return 0;
2780
0
    case RVE_PLUS_OP:
2781
      /* non commut. when diff. type
2782
       * (e.g 1 + "2" != "2" + 1 ) => non commut. in general
2783
       * (specific same type versions are covered by IPLUS & CONCAT) */
2784
0
      return 0;
2785
0
    case RVE_IPLUS_OP:
2786
0
    case RVE_MUL_OP:
2787
0
    case RVE_BAND_OP:
2788
0
    case RVE_BOR_OP:
2789
0
    case RVE_BXOR_OP:
2790
0
    case RVE_LAND_OP:
2791
0
    case RVE_LOR_OP:
2792
0
    case RVE_IEQ_OP:
2793
0
    case RVE_IDIFF_OP:
2794
0
    case RVE_STREQ_OP:
2795
0
    case RVE_STRDIFF_OP:
2796
0
      return 1;
2797
0
    case RVE_GT_OP:
2798
0
    case RVE_GTE_OP:
2799
0
    case RVE_LT_OP:
2800
0
    case RVE_LTE_OP:
2801
0
    case RVE_CONCAT_OP:
2802
0
    case RVE_MATCH_OP:
2803
0
    case RVE_SELVALEXP_OP:
2804
0
    case RVE_SELVALOPT_OP:
2805
0
      return 0;
2806
0
    case RVE_DIFF_OP:
2807
0
    case RVE_EQ_OP:
2808
      /* non. commut. in general, only for same type e.g.:
2809
       * "" == 0  diff. 0 == "" ( "" == "0" and 0 == 0)
2810
       * same type versions are covered by IEQ, IDIFF, STREQ, STRDIFF
2811
       */
2812
0
      return 0 /* asymmetrical undef handling */;
2813
0
  }
2814
0
  return 0;
2815
0
}
2816
2817
2818
static int fix_rval(struct rvalue *rv, struct rval_expr *rve)
2819
0
{
2820
0
  LM_DBG("RV fixing type %d\n", rv->type);
2821
0
  switch(rv->type) {
2822
0
    case RV_LONG:
2823
      /*nothing to do*/
2824
0
      LM_DBG("RV is int: %d\n", (int)rv->v.l);
2825
0
      return 0;
2826
0
    case RV_STR:
2827
      /*nothing to do*/
2828
0
      LM_DBG("RV is str: \"%s\"\n", rv->v.s.s);
2829
0
      return 0;
2830
0
    case RV_BEXPR:
2831
0
      return fix_expr(rv->v.bexpr);
2832
0
    case RV_ACTION_ST:
2833
0
      return fix_actions(rv->v.action);
2834
0
    case RV_SEL:
2835
0
      if(resolve_select(&rv->v.sel) < 0) {
2836
0
        if(rve == NULL) {
2837
0
          LM_ERR("Unable to resolve select\n");
2838
0
        } else {
2839
0
          LM_ERR("Unable to resolve select in cfg at line: %d col: "
2840
0
               "%d\n",
2841
0
              rve->fpos.s_line, rve->fpos.s_col);
2842
0
        }
2843
0
        err_select(&rv->v.sel);
2844
0
      }
2845
0
      return 0;
2846
0
    case RV_AVP:
2847
      /* nothing to do, resolved at runtime */
2848
0
      return 0;
2849
0
    case RV_PVAR:
2850
      /* nothing to do, resolved at parsing time */
2851
0
      return 0;
2852
0
    case RV_NONE:
2853
0
      LM_BUG("uninitialized rvalue\n");
2854
0
      return -1;
2855
0
  }
2856
0
  LM_BUG("unknown rvalue type %d\n", rv->type);
2857
0
  return -1;
2858
0
}
2859
2860
2861
/**
2862
 * @brief Helper function: replace a rve (in-place) with a constant rval_val
2863
 * @warning since it replaces in-place, one should make sure that if
2864
 * rve is in fact a rval (rve->op==RVE_RVAL_OP), no reference is kept
2865
 * to the rval!
2866
 * @param rve expression to be replaced (in-place)
2867
 * @param type rvalue type
2868
 * @param v pointer to a rval_val union containing the replacement value.
2869
 * @param flags value flags (how it was alloc'ed, e.g.: RV_CNT_ALLOCED_F)
2870
 * @return 0 on success, -1 on error
2871
 */
2872
static int rve_replace_with_val(struct rval_expr *rve, enum rval_type type,
2873
    union rval_val *v, int flags)
2874
0
{
2875
0
  int refcnt;
2876
2877
0
  refcnt = 1; /* replaced-in-place rval refcnt */
2878
0
  if(rve->op != RVE_RVAL_OP) {
2879
0
    rve_destroy(rve->left.rve);
2880
0
    if(rve_op_unary(rve->op) == 0)
2881
0
      rve_destroy(rve->right.rve);
2882
0
  } else {
2883
0
    if(rve->left.rval.refcnt != 1) {
2884
0
      LM_BUG("trying to replace a referenced rval! (refcnt=%d)\n",
2885
0
          rve->left.rval.refcnt);
2886
      /* try to recover */
2887
0
      refcnt = rve->left.rval.refcnt;
2888
0
      abort(); /* find bugs quicker -- andrei */
2889
0
    }
2890
0
    rval_destroy_content(&rve->left.rval);
2891
0
  }
2892
0
  rval_init(&rve->left.rval, type, v, flags);
2893
0
  rve->left.rval.refcnt = refcnt;
2894
0
  rval_init(&rve->right.rval, RV_NONE, 0, 0);
2895
0
  rve->op = RVE_RVAL_OP;
2896
0
  return 0;
2897
0
}
2898
2899
2900
/** helper function: replace a rve (in-place) with a constant rvalue.
2901
 * @param rve - expression to be replaced (in-place)
2902
 * @param rv   - pointer to the replacement _constant_ rvalue structure
2903
 * @return 0 on success, -1 on error */
2904
static int rve_replace_with_ct_rv(struct rval_expr *rve, struct rvalue *rv)
2905
0
{
2906
0
  enum rval_type type;
2907
0
  int flags;
2908
0
  long i;
2909
0
  union rval_val v;
2910
2911
0
  type = rv->type;
2912
0
  flags = 0;
2913
0
  if(rv->type == RV_LONG) {
2914
0
    if(rval_get_long(0, 0, &i, rv, 0) != 0) {
2915
0
      LM_BUG("unexpected int evaluation failure (%d,%d-%d,%d)\n",
2916
0
          rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
2917
0
          rve->fpos.e_col);
2918
0
      return -1;
2919
0
    }
2920
0
    v.l = i;
2921
0
  } else if(rv->type == RV_STR) {
2922
0
    if(rval_get_str(0, 0, &v.s, rv, 0) < 0) {
2923
0
      LM_BUG("unexpected str evaluation failure(%d,%d-%d,%d)\n",
2924
0
          rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
2925
0
          rve->fpos.e_col);
2926
0
      return -1;
2927
0
    }
2928
0
    flags |= RV_CNT_ALLOCED_F;
2929
0
  } else {
2930
0
    LM_BUG("unknown constant expression type %d (%d,%d-%d,%d)\n", rv->type,
2931
0
        rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
2932
0
        rve->fpos.e_col);
2933
0
    return -1;
2934
0
  }
2935
0
  return rve_replace_with_val(rve, type, &v, flags);
2936
0
}
2937
2938
2939
/** try to replace the right side of the rve with a compiled regex.
2940
 * @return 0 on success and -1 on error.
2941
 */
2942
static int fix_match_rve(struct rval_expr *rve)
2943
0
{
2944
0
  struct rvalue *rv;
2945
0
  regex_t *re;
2946
0
  union rval_val v;
2947
0
  int flags;
2948
0
  int ret;
2949
2950
0
  rv = 0;
2951
0
  v.s.s = 0;
2952
0
  v.re.regex = 0;
2953
  /* normal fix-up for the  left side */
2954
0
  ret = fix_rval_expr((void *)rve->left.rve);
2955
0
  if(ret < 0)
2956
0
    return ret;
2957
2958
  /* fixup the right side (RE) */
2959
0
  if(rve_is_constant(rve->right.rve)) {
2960
0
    if((rve_guess_type(rve->right.rve) != RV_STR)) {
2961
0
      LM_ERR("fixup failure(%d,%d-%d,%d): right side of  =~ is not string"
2962
0
           " (%d,%d)\n",
2963
0
          rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
2964
0
          rve->fpos.e_col, rve->right.rve->fpos.s_line,
2965
0
          rve->right.rve->fpos.s_col);
2966
0
      goto error;
2967
0
    }
2968
0
    if((rv = rval_expr_eval(0, 0, rve->right.rve)) == 0) {
2969
0
      LM_ERR("fixup failure(%d,%d-%d,%d): bad RE expression\n",
2970
0
          rve->right.rve->fpos.s_line, rve->right.rve->fpos.s_col,
2971
0
          rve->right.rve->fpos.e_line, rve->right.rve->fpos.e_col);
2972
0
      goto error;
2973
0
    }
2974
0
    if(rval_get_str(0, 0, &v.s, rv, 0) < 0) {
2975
0
      LM_BUG("fixup unexpected failure (%d,%d-%d,%d)\n", rve->fpos.s_line,
2976
0
          rve->fpos.s_col, rve->fpos.e_line, rve->fpos.e_col);
2977
0
      goto error;
2978
0
    }
2979
    /* we have the str, we don't need the rv anymore */
2980
0
    rval_destroy(rv);
2981
0
    rv = 0;
2982
0
    re = pkg_malloc(sizeof(*re));
2983
0
    if(re == 0) {
2984
0
      PKG_MEM_ERROR;
2985
0
      goto error;
2986
0
    }
2987
    /* same flags as for expr. =~ (fix_expr()) */
2988
0
    if(regcomp(re, v.s.s, REG_EXTENDED | REG_NOSUB | REG_ICASE)) {
2989
0
      pkg_free(re);
2990
0
      LM_ERR("Bad regular expression \"%s\"(%d,%d-%d,%d)\n", v.s.s,
2991
0
          rve->right.rve->fpos.s_line, rve->right.rve->fpos.s_col,
2992
0
          rve->right.rve->fpos.e_line, rve->right.rve->fpos.e_col);
2993
0
      goto error;
2994
0
    }
2995
0
    v.re.regex = re;
2996
0
    flags = RV_RE_F | RV_RE_ALLOCED_F | RV_CNT_ALLOCED_F;
2997
0
    if(rve_replace_with_val(rve->right.rve, RV_STR, &v, flags) < 0)
2998
0
      goto error;
2999
0
  } else {
3000
    /* right side is not constant => normal fixup */
3001
0
    return fix_rval_expr((void *)rve->right.rve);
3002
0
  }
3003
0
  return 0;
3004
0
error:
3005
0
  if(rv)
3006
0
    rval_destroy(rv);
3007
0
  if(v.s.s)
3008
0
    pkg_free(v.s.s);
3009
0
  if(v.re.regex) {
3010
0
    regfree(v.re.regex);
3011
0
    pkg_free(v.re.regex);
3012
0
  }
3013
0
  return -1;
3014
0
}
3015
3016
3017
/** optimize op($v, 0) or op($v, 1).
3018
 * Note: internal use only from rve_optimize
3019
 * It should be called after ct optimization, for non-constant
3020
 *  expressions (the left or right side is not constant).
3021
 * @return 1 on success (rve was changed), 0 on failure and -1 on error
3022
 */
3023
static int rve_opt_01(struct rval_expr *rve, enum rval_type rve_type)
3024
0
{
3025
0
  struct rvalue *rv;
3026
0
  struct rval_expr *ct_rve;
3027
0
  struct rval_expr *v_rve;
3028
0
  struct rval_expr *r_rve = NULL;
3029
0
  int i;
3030
0
  int ret;
3031
0
  enum rval_expr_op op;
3032
0
  struct cfg_pos pos;
3033
0
  int right; /* debugging msg */
3034
0
  int dbg;   /* debugging msg on/off */
3035
3036
/* helper macro: replace in-place a <ctype> type rve with v (another rve).
3037
 * if type_of(v)== <ctype> => rve:=*v (copy v contents into rve and free v)
3038
 * else if type_of(v)!=<ctype> => rve:= (ctype) v (casts v to <ctype>)
3039
 * Uses pos.
3040
 * ctype can be INT or STR
3041
 * WARNING: - v might be pkg_free()'d
3042
 *          - rve members _are_ _not_ freed or destroyed
3043
 */
3044
0
#define replace_rve_type_cast(e, v, ctype)                   \
3045
0
  do {                                                     \
3046
0
    if(rve_guess_type((v)) == RV_##ctype) {              \
3047
      /* if type_of($v)==int we don't need to add an \
3048
       * int cast operator => replace with v */ \
3049
0
      pos = (e)->fpos;                                 \
3050
0
      *(e) = *(v); /* replace e with v (in-place) */   \
3051
0
      (e)->fpos = pos;                                 \
3052
0
      r_rve = v; /* link to free it */                 \
3053
0
    } else {                                             \
3054
      /* unknown type or str => (int) $v */            \
3055
0
      (e)->op = RVE_##ctype##_OP;                      \
3056
0
      (e)->left.rve = (v);                             \
3057
0
      (e)->right.rve = 0;                              \
3058
0
    }                                                    \
3059
0
  } while(0)
3060
3061
/* helper macro: replace in-place an int type rve with v (another rve).*/
3062
0
#define replace_long_rve(e, v) replace_rve_type_cast(e, v, LONG)
3063
/* helper macro: replace in-place a str type rve with v (another rve).*/
3064
0
#define replace_str_rve(e, v) replace_rve_type_cast(e, v, STR)
3065
3066
0
  rv = 0;
3067
0
  ret = 0;
3068
0
  right = 0;
3069
0
  dbg = 1;
3070
3071
0
  if(rve_is_constant(rve->right.rve)) {
3072
0
    ct_rve = rve->right.rve;
3073
0
    v_rve = rve->left.rve;
3074
0
    right = 1;
3075
0
  } else if(rve_is_constant(rve->left.rve)) {
3076
0
    ct_rve = rve->left.rve;
3077
0
    v_rve = rve->right.rve;
3078
0
    right = 0;
3079
0
  } else
3080
0
    return 0; /* op($v, $w) */
3081
3082
  /* rval_expr_eval_new() instead of rval_expr_eval() to avoid
3083
   * referencing a ct_rve->left.rval if ct_rve is a rval, which
3084
   * would prevent rve_destroy(ct_rve) from working */
3085
0
  if((rv = rval_expr_eval_new(0, 0, ct_rve)) == 0) {
3086
0
    LM_ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
3087
0
        ct_rve->fpos.s_line, ct_rve->fpos.s_col, ct_rve->fpos.e_line,
3088
0
        ct_rve->fpos.e_col);
3089
0
    goto error;
3090
0
  }
3091
0
  op = rve->op;
3092
0
  if(rv->type == RV_LONG) {
3093
0
    i = rv->v.l;
3094
0
    switch(op) {
3095
0
      case RVE_MUL_OP:
3096
0
        if(i == 0) {
3097
          /* $v *  0 -> 0
3098
           *  0 * $v -> 0 */
3099
0
          if(rve_replace_with_ct_rv(rve, rv) < 0)
3100
0
            goto error;
3101
0
          ret = 1;
3102
0
        } else if(i == 1) {
3103
          /* $v *  1 -> (int)$v
3104
           *  1 * $v -> (int)$v */
3105
0
          rve_destroy(ct_rve);
3106
0
          replace_long_rve(rve, v_rve);
3107
0
          ret = 1;
3108
0
        }
3109
0
        break;
3110
0
      case RVE_DIV_OP:
3111
0
        if(i == 0) {
3112
0
          if(ct_rve == rve->left.rve) {
3113
            /* 0 / $v -> 0 */
3114
0
            if(rve_replace_with_ct_rv(rve, rv) < 0)
3115
0
              goto error;
3116
0
            ret = 1;
3117
0
          } else {
3118
            /* $v / 0 */
3119
0
            LM_ERR("RVE divide by 0 at %d,%d\n",
3120
0
                ct_rve->fpos.s_line, ct_rve->fpos.s_col);
3121
0
          }
3122
0
        } else if(i == 1) {
3123
0
          if(ct_rve == rve->right.rve) {
3124
            /* $v / 1 -> (int)$v */
3125
0
            rve_destroy(ct_rve);
3126
0
            replace_long_rve(rve, v_rve);
3127
0
            ret = 1;
3128
0
          }
3129
0
        }
3130
0
        break;
3131
0
      case RVE_MOD_OP:
3132
0
        if(i == 0) {
3133
0
          if(ct_rve == rve->left.rve) {
3134
            /* 0 % $v -> 0 */
3135
0
            if(rve_replace_with_ct_rv(rve, rv) < 0)
3136
0
              goto error;
3137
0
            ret = 1;
3138
0
          } else {
3139
            /* $v % 0 */
3140
0
            LM_ERR("RVE modulo by 0 at %d,%d\n",
3141
0
                ct_rve->fpos.s_line, ct_rve->fpos.s_col);
3142
0
          }
3143
0
        }
3144
        /* $v % 1 -> 0 ? */
3145
0
        break;
3146
0
      case RVE_MINUS_OP:
3147
0
        if(i == 0) {
3148
0
          if(ct_rve == rve->right.rve) {
3149
            /* $v - 0 -> $v */
3150
0
            rve_destroy(ct_rve);
3151
0
            replace_long_rve(rve, v_rve);
3152
0
            ret = 1;
3153
0
          }
3154
          /* ? 0 - $v -> -($v)  ? */
3155
0
        }
3156
0
        break;
3157
0
      case RVE_BAND_OP:
3158
0
        if(i == 0) {
3159
          /* $v &  0 -> 0
3160
           *  0 & $v -> 0 */
3161
0
          if(rve_replace_with_ct_rv(rve, rv) < 0)
3162
0
            goto error;
3163
0
          ret = 1;
3164
0
        }
3165
        /* no 0xffffff optimization for now (haven't decided on
3166
         * the number of bits ) */
3167
0
        break;
3168
0
      case RVE_BOR_OP:
3169
0
        if(i == 0) {
3170
          /* $v |  0 -> (int)$v
3171
           *  0 | $v -> (int)$v */
3172
0
          rve_destroy(ct_rve);
3173
0
          replace_long_rve(rve, v_rve);
3174
0
          ret = 1;
3175
0
        }
3176
0
        break;
3177
0
      case RVE_LAND_OP:
3178
0
        if(i == 0) {
3179
          /* $v &&  0 -> 0
3180
           *  0 && $v -> 0 */
3181
0
          if(rve_replace_with_ct_rv(rve, rv) < 0)
3182
0
            goto error;
3183
0
          ret = 1;
3184
0
        } else if(i == 1) {
3185
          /* $v &&  1 -> (int)$v
3186
           *  1 && $v -> (int)$v */
3187
0
          rve_destroy(ct_rve);
3188
0
          replace_long_rve(rve, v_rve);
3189
0
          ret = 1;
3190
0
        }
3191
0
        break;
3192
0
      case RVE_LOR_OP:
3193
0
        if(i == 1) {
3194
          /* $v ||  1 -> 1
3195
           *  1 || $v -> 1 */
3196
0
          if(rve_replace_with_ct_rv(rve, rv) < 0)
3197
0
            goto error;
3198
0
          ret = 1;
3199
0
        } else if(i == 0) {
3200
          /* $v ||  0 -> (int)$v
3201
           *  0 && $v -> (int)$v */
3202
0
          rve_destroy(ct_rve);
3203
0
          replace_long_rve(rve, v_rve);
3204
0
          ret = 1;
3205
0
        }
3206
0
        break;
3207
0
      case RVE_PLUS_OP:
3208
0
      case RVE_IPLUS_OP:
3209
        /* we must make sure that this is an int PLUS
3210
         * (because "foo"+0 is valid => "foo0") =>
3211
         * check if it's an IPLUS or the result is an integer
3212
         * (which generally means unoptimized <int> + <something>).
3213
         */
3214
0
        if((i == 0)
3215
0
            && ((op == RVE_IPLUS_OP) || (rve_type == RV_LONG))) {
3216
          /* $v +  0 -> (int)$v
3217
           *  0 + $v -> (int)$v */
3218
0
          rve_destroy(ct_rve);
3219
0
          replace_long_rve(rve, v_rve);
3220
0
          ret = 1;
3221
0
        }
3222
0
        break;
3223
0
      default:
3224
        /* do nothing */
3225
0
        break;
3226
0
    }
3227
    /* debugging messages */
3228
0
    if(ret == 1 && dbg) {
3229
0
      if(right) {
3230
0
        if(rve->op == RVE_RVAL_OP) {
3231
0
          if(rve->left.rval.type == RV_LONG)
3232
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3233
0
                 " op%d($v, %d) -> %d\n",
3234
0
                rve->fpos.s_line, rve->fpos.s_col,
3235
0
                rve->fpos.e_line, rve->fpos.e_col, op, i,
3236
0
                (int)rve->left.rval.v.l);
3237
0
          else
3238
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3239
0
                 " op%d($v, %d) -> $v (rval)\n",
3240
0
                rve->fpos.s_line, rve->fpos.s_col,
3241
0
                rve->fpos.e_line, rve->fpos.e_col, op, i);
3242
0
        } else if(rve->op == RVE_LONG_OP) {
3243
0
          if(rve->left.rve->op == RVE_RVAL_OP
3244
0
              && rve->left.rve->left.rval.type == RV_LONG)
3245
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3246
0
                 " op%d($v, %d) -> (int)%d\n",
3247
0
                rve->fpos.s_line, rve->fpos.s_col,
3248
0
                rve->fpos.e_line, rve->fpos.e_col, op, i,
3249
0
                (int)rve->left.rve->left.rval.v.l);
3250
0
          else
3251
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3252
0
                 " op%d($v, %d) -> (int)$v\n",
3253
0
                rve->fpos.s_line, rve->fpos.s_col,
3254
0
                rve->fpos.e_line, rve->fpos.e_col, op, i);
3255
0
        } else {
3256
0
          LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3257
0
               " op%d($v, %d) -> $v\n",
3258
0
              rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3259
0
              rve->fpos.e_col, op, i);
3260
0
        }
3261
0
      } else {
3262
0
        if(rve->op == RVE_RVAL_OP) {
3263
0
          if(rve->left.rval.type == RV_LONG)
3264
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3265
0
                 " op%d(%d, $v) -> %d\n",
3266
0
                rve->fpos.s_line, rve->fpos.s_col,
3267
0
                rve->fpos.e_line, rve->fpos.e_col, op, i,
3268
0
                (int)rve->left.rval.v.l);
3269
0
          else
3270
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3271
0
                 " op%d(%d, $v) -> $v (rval)\n",
3272
0
                rve->fpos.s_line, rve->fpos.s_col,
3273
0
                rve->fpos.e_line, rve->fpos.e_col, op, i);
3274
0
        } else if(rve->op == RVE_LONG_OP) {
3275
0
          if(rve->left.rve->op == RVE_RVAL_OP
3276
0
              && rve->left.rve->left.rval.type == RV_LONG)
3277
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3278
0
                 " op%d(%d, $v) -> (int)%d\n",
3279
0
                rve->fpos.s_line, rve->fpos.s_col,
3280
0
                rve->fpos.e_line, rve->fpos.e_col, op, i,
3281
0
                (int)rve->left.rve->left.rval.v.l);
3282
0
          else
3283
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3284
0
                 " op%d(%d, $v) -> (int)$v\n",
3285
0
                rve->fpos.s_line, rve->fpos.s_col,
3286
0
                rve->fpos.e_line, rve->fpos.e_col, op, i);
3287
0
        } else {
3288
0
          LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3289
0
               " op%d(%d, $v) -> $v\n",
3290
0
              rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3291
0
              rve->fpos.e_col, op, i);
3292
0
        }
3293
0
      }
3294
0
    }
3295
0
  } else if(rv->type == RV_STR) {
3296
0
    switch(op) {
3297
0
      case RVE_CONCAT_OP:
3298
0
        if(rv->v.s.len == 0) {
3299
          /* $v . "" -> (str)$v
3300
           * "" . $v -> (str)$v */
3301
0
          rve_destroy(ct_rve);
3302
0
          replace_str_rve(rve, v_rve);
3303
0
          ret = 1;
3304
0
        }
3305
0
        break;
3306
0
      case RVE_EQ_OP:
3307
0
      case RVE_STREQ_OP:
3308
0
        if(rv->v.s.len == 0) {
3309
          /* $v == "" -> strempty($v)
3310
           * "" == $v -> strempty ($v) */
3311
0
          rve_destroy(ct_rve);
3312
          /* replace current expr. with strempty(rve) */
3313
0
          rve->op = RVE_STREMPTY_OP;
3314
0
          rve->left.rve = v_rve;
3315
0
          rve->right.rve = 0;
3316
0
          ret = 1;
3317
0
          if(dbg)
3318
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3319
0
                 " op%d($v, \"\") -> strempty($v)\n",
3320
0
                rve->fpos.s_line, rve->fpos.s_col,
3321
0
                rve->fpos.e_line, rve->fpos.e_col, op);
3322
0
          dbg = 0;
3323
0
        }
3324
0
        break;
3325
0
      default:
3326
0
        break;
3327
0
    }
3328
    /* no optimization for generic RVE_PLUS_OP for now, only for RVE_CONCAT_OP
3329
   * (RVE_PLUS_OP should be converted to RVE_CONCAT_OP if it's supposed
3330
   * to work on strings. If it's not converted/optimized it means its type
3331
   * can be determined only at runtime => we cannot optimize */
3332
    /* debugging messages */
3333
0
    if(ret == 1 && dbg) {
3334
0
      if(right) {
3335
0
        if(rve->op == RVE_RVAL_OP) {
3336
0
          if(rve->left.rval.type == RV_STR)
3337
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3338
0
                 " op%d($v, <string>) -> \"%s\"\n",
3339
0
                rve->fpos.s_line, rve->fpos.s_col,
3340
0
                rve->fpos.e_line, rve->fpos.e_col, op,
3341
0
                rve->left.rval.v.s.s);
3342
0
          else
3343
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3344
0
                 " op%d($v, <string>) -> $v (rval)\n",
3345
0
                rve->fpos.s_line, rve->fpos.s_col,
3346
0
                rve->fpos.e_line, rve->fpos.e_col, op);
3347
0
        } else if(rve->op == RVE_STR_OP) {
3348
0
          if(rve->left.rve->op == RVE_RVAL_OP
3349
0
              && rve->left.rve->left.rval.type == RV_STR)
3350
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3351
0
                 " op%d($v, <string>) -> (str)\"%s\"\n",
3352
0
                rve->fpos.s_line, rve->fpos.s_col,
3353
0
                rve->fpos.e_line, rve->fpos.e_col, op,
3354
0
                rve->left.rve->left.rval.v.s.s);
3355
0
          else
3356
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3357
0
                 " op%d($v, <string>) -> (str)$v\n",
3358
0
                rve->fpos.s_line, rve->fpos.s_col,
3359
0
                rve->fpos.e_line, rve->fpos.e_col, op);
3360
0
        } else {
3361
0
          LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3362
0
               " op%d($v, <string>) -> $v\n",
3363
0
              rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3364
0
              rve->fpos.e_col, op);
3365
0
        }
3366
0
      } else {
3367
0
        if(rve->op == RVE_RVAL_OP) {
3368
0
          if(rve->left.rval.type == RV_STR)
3369
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3370
0
                 " op%d(<string>, $v) -> \"%s\"\n",
3371
0
                rve->fpos.s_line, rve->fpos.s_col,
3372
0
                rve->fpos.e_line, rve->fpos.e_col, op,
3373
0
                rve->left.rval.v.s.s);
3374
0
          else
3375
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3376
0
                 " op%d(<string>, $v) -> $v (rval)\n",
3377
0
                rve->fpos.s_line, rve->fpos.s_col,
3378
0
                rve->fpos.e_line, rve->fpos.e_col, op);
3379
0
        } else if(rve->op == RVE_STR_OP) {
3380
0
          if(rve->left.rve->op == RVE_RVAL_OP
3381
0
              && rve->left.rve->left.rval.type == RV_STR)
3382
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3383
0
                 " op%d(<string>, $v) -> (str)\"%s\"\n",
3384
0
                rve->fpos.s_line, rve->fpos.s_col,
3385
0
                rve->fpos.e_line, rve->fpos.e_col, op,
3386
0
                rve->left.rve->left.rval.v.s.s);
3387
0
          else
3388
0
            LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3389
0
                 " op%d(<string>, $v) -> (str)$v\n",
3390
0
                rve->fpos.s_line, rve->fpos.s_col,
3391
0
                rve->fpos.e_line, rve->fpos.e_col, op);
3392
0
        } else {
3393
0
          LM_DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3394
0
               " op%d(<string>, $v) -> $v\n",
3395
0
              rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3396
0
              rve->fpos.e_col, op);
3397
0
        }
3398
0
      }
3399
0
    }
3400
0
  }
3401
0
  if(rv)
3402
0
    rval_destroy(rv);
3403
0
  if(r_rve)
3404
0
    pkg_free(r_rve); /* rve_destroy(v_rve) would free everything*/
3405
0
  return ret;
3406
0
error:
3407
0
  if(rv)
3408
0
    rval_destroy(rv);
3409
0
  if(r_rve)
3410
0
    pkg_free(r_rve); /* rve_destroy(v_rve) would free everything*/
3411
0
  return -1;
3412
0
}
3413
3414
3415
/** tries to optimize a rval_expr. */
3416
static int rve_optimize(struct rval_expr *rve)
3417
0
{
3418
0
  int ret;
3419
0
  struct rvalue *rv;
3420
0
  struct rvalue *trv; /* used only for DBG() */
3421
0
  enum rval_expr_op op;
3422
0
  struct rval_expr tmp_rve;
3423
0
  enum rval_type type, l_type;
3424
0
  struct rval_expr *bad_rve;
3425
0
  enum rval_type bad_type, exp_type;
3426
3427
0
  ret = 0;
3428
0
  rv = 0;
3429
0
  if(scr_opt_lev < 1)
3430
0
    return 0;
3431
0
  if(rve->op == RVE_RVAL_OP) /* if rval, nothing to do */
3432
0
    return 0;
3433
0
  if(rve_is_constant(rve)) {
3434
0
    if((rv = rval_expr_eval_new(0, 0, rve)) == 0) {
3435
0
      LM_ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
3436
0
          rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3437
0
          rve->fpos.e_col);
3438
0
      goto error;
3439
0
    }
3440
0
    op = rve->op;
3441
0
    if(rve_replace_with_ct_rv(rve, rv) < 0)
3442
0
      goto error;
3443
0
    rval_destroy(rv);
3444
0
    rv = 0;
3445
0
    trv = &rve->left.rval;
3446
0
    if(trv->type == RV_LONG)
3447
0
      LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized constant int rve "
3448
0
           "(old op %d) to %d\n",
3449
0
          rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3450
0
          rve->fpos.e_col, op, (int)trv->v.l);
3451
0
    else if(trv->type == RV_STR)
3452
0
      LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized constant str rve "
3453
0
           "(old op %d) to \"%.*s\"\n",
3454
0
          rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3455
0
          rve->fpos.e_col, op, trv->v.s.len, trv->v.s.s);
3456
0
    ret = 1;
3457
0
  } else {
3458
    /* expression is not constant */
3459
    /* if unary => nothing to do */
3460
0
    if(rve_op_unary(rve->op))
3461
0
      return rve_optimize(rve->left.rve);
3462
0
    rve_optimize(rve->left.rve);
3463
0
    rve_optimize(rve->right.rve);
3464
0
    if(!rve_check_type(&type, rve, &bad_rve, &bad_type, &exp_type)) {
3465
0
      LM_ERR("optimization failure while optimizing %d,%d-%d,%d:"
3466
0
           " type mismatch in expression (%d,%d-%d,%d), "
3467
0
           "type %s, but expected %s\n",
3468
0
          rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3469
0
          rve->fpos.e_col, bad_rve->fpos.s_line, bad_rve->fpos.s_col,
3470
0
          bad_rve->fpos.e_line, bad_rve->fpos.e_col,
3471
0
          rval_type_name(bad_type), rval_type_name(exp_type));
3472
0
      return 0;
3473
0
    }
3474
    /* $v - a => $v + (-a)  (easier to optimize)*/
3475
0
    if((rve->op == RVE_MINUS_OP) && (rve_is_constant(rve->right.rve))) {
3476
0
      if((rv = rval_expr_eval_new(0, 0, rve->right.rve)) == 0) {
3477
0
        LM_ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
3478
0
            rve->right.rve->fpos.s_line, rve->right.rve->fpos.s_col,
3479
0
            rve->right.rve->fpos.e_line,
3480
0
            rve->right.rve->fpos.e_col);
3481
0
        goto error;
3482
0
      }
3483
0
      if(rv->type == RV_LONG) {
3484
0
        rv->v.l = -rv->v.l;
3485
0
        if(rve_replace_with_ct_rv(rve->right.rve, rv) < 0)
3486
0
          goto error;
3487
0
        rve->op = RVE_IPLUS_OP;
3488
0
        LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized $v - an into "
3489
0
             "$v + (%d)\n",
3490
0
            rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3491
0
            rve->fpos.e_col, (int)rve->right.rve->left.rval.v.l);
3492
0
      }
3493
0
      rval_destroy(rv);
3494
0
      rv = 0;
3495
0
    }
3496
3497
    /* e1 PLUS_OP e2 -> change op if we know e1 basic type */
3498
0
    if(rve->op == RVE_PLUS_OP) {
3499
0
      l_type = rve_guess_type(rve->left.rve);
3500
0
      if(l_type == RV_LONG) {
3501
0
        rve->op = RVE_IPLUS_OP;
3502
0
        LM_DBG("FIXUP RVE (%d,%d-%d,%d): changed + into integer plus\n",
3503
0
            rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3504
0
            rve->fpos.e_col);
3505
0
      } else if(l_type == RV_STR) {
3506
0
        rve->op = RVE_CONCAT_OP;
3507
0
        LM_DBG("FIXUP RVE (%d,%d-%d,%d): changed + into string "
3508
0
             "concat\n",
3509
0
            rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3510
0
            rve->fpos.e_col);
3511
0
      }
3512
0
    }
3513
    /* e1 EQ_OP e2 -> change op if we know e1 basic type
3514
     * e1 DIFF_OP e2 -> change op if we know e2 basic type */
3515
0
    if(rve->op == RVE_EQ_OP || rve->op == RVE_DIFF_OP) {
3516
0
      l_type = rve_guess_type(rve->left.rve);
3517
0
      if(l_type == RV_LONG) {
3518
0
        rve->op = (rve->op == RVE_EQ_OP) ? RVE_IEQ_OP : RVE_IDIFF_OP;
3519
0
        LM_DBG("FIXUP RVE (%d,%d-%d,%d): changed ==/!= into integer"
3520
0
             " ==/!=\n",
3521
0
            rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3522
0
            rve->fpos.e_col);
3523
0
      } else if(l_type == RV_STR) {
3524
0
        rve->op =
3525
0
            (rve->op == RVE_EQ_OP) ? RVE_STREQ_OP : RVE_STRDIFF_OP;
3526
0
        LM_DBG("FIXUP RVE (%d,%d-%d,%d): changed ==/!= into string"
3527
0
             " ==/!=\n",
3528
0
            rve->fpos.s_line, rve->fpos.s_col, rve->fpos.e_line,
3529
0
            rve->fpos.e_col);
3530
0
      }
3531
0
    }
3532
3533
    /* $v * 0 => 0; $v * 1 => $v (for *, /, &, |, &&, ||, +, -) */
3534
0
    if(rve_opt_01(rve, type) == 1) {
3535
      /* success, rve was changed => return now
3536
       * (since this is recursively invoked the "new" rve
3537
       * is already optimized) */
3538
0
      ret = 1;
3539
0
      goto end;
3540
0
    }
3541
3542
    /* op(op($v, a), b) => op($v, op(a,b)) */
3543
0
    if(rve_is_constant(rve->right.rve)) {
3544
      /* op1(op2(...), b) */
3545
0
      if((rve->op == rve->left.rve->op) && rve_op_is_assoc(rve->op)) {
3546
        /* op(op(...), b) */
3547
0
        if(rve_is_constant(rve->left.rve->right.rve)) {
3548
          /* op(op($v, a), b) => op($v, op(a, b)) */
3549
          /* rv= op(a, b) */
3550
0
          tmp_rve.op = rve->op;
3551
0
          tmp_rve.left.rve = rve->left.rve->right.rve;
3552
0
          tmp_rve.right.rve = rve->right.rve;
3553
          /* hack for RVE_PLUS_OP which can work on string, ints
3554
           * or a combination of them */
3555
0
          if((rve->op == RVE_PLUS_OP)
3556
0
              && (rve_guess_type(tmp_rve.left.rve) != RV_STR)) {
3557
0
            LM_DBG("RVE optimization failed (%d,%d-%d,%d): cannot "
3558
0
                 "optimize +(+($v, a), b) when typeof(a)==INT\n",
3559
0
                rve->fpos.s_line, rve->fpos.s_col,
3560
0
                rve->fpos.e_line, rve->fpos.e_col);
3561
0
            return 0;
3562
0
          }
3563
0
          if((rv = rval_expr_eval_new(0, 0, &tmp_rve)) == 0) {
3564
0
            LM_ERR("optimization failure, bad expression\n");
3565
0
            goto error;
3566
0
          }
3567
          /* op($v, rv) */
3568
0
          if(rve_replace_with_ct_rv(rve->right.rve, rv) < 0)
3569
0
            goto error;
3570
0
          rval_destroy(rv);
3571
0
          rv = 0;
3572
0
          rve_destroy(tmp_rve.left.rve);
3573
0
          rve->left.rve = rve->left.rve->left.rve;
3574
0
          trv = &rve->right.rve->left.rval;
3575
0
          if(trv->type == RV_LONG)
3576
0
            LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized int rve: "
3577
0
                 "op(op($v, a), b) with op($v, %d); op=%d\n",
3578
0
                rve->fpos.s_line, rve->fpos.s_col,
3579
0
                rve->fpos.e_line, rve->fpos.e_col,
3580
0
                (int)trv->v.l, rve->op);
3581
0
          else if(trv->type == RV_STR)
3582
0
            LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized str rve "
3583
0
                 "op(op($v, a), b) with op($v, \"%.*s\");"
3584
0
                 " op=%d\n",
3585
0
                rve->fpos.s_line, rve->fpos.s_col,
3586
0
                rve->fpos.e_line, rve->fpos.e_col, trv->v.s.len,
3587
0
                trv->v.s.s, rve->op);
3588
0
          ret = 1;
3589
0
        } else if(rve_is_constant(rve->left.rve->left.rve)
3590
0
              && rve_op_is_commutative(rve->op)) {
3591
          /* op(op(a, $v), b) => op(op(a, b), $v) */
3592
          /* rv= op(a, b) */
3593
0
          tmp_rve.op = rve->op;
3594
0
          tmp_rve.left.rve = rve->left.rve->left.rve;
3595
0
          tmp_rve.right.rve = rve->right.rve;
3596
          /* no need for the RVE_PLUS_OP hack, all the bad
3597
           * cases are caught by rve_op_is_commutative()
3598
           * (in this case type will be typeof(a)) => ok only if
3599
           * typeof(a) is int) */
3600
0
          if((rv = rval_expr_eval_new(0, 0, &tmp_rve)) == 0) {
3601
0
            LM_ERR("optimization failure, bad expression\n");
3602
0
            goto error;
3603
0
          }
3604
          /* op(rv, $v) */
3605
0
          rve_destroy(rve->right.rve);
3606
0
          rve->right.rve = rve->left.rve->right.rve;
3607
0
          rve->left.rve->right.rve = 0;
3608
0
          if(rve_replace_with_ct_rv(rve->left.rve, rv) < 0)
3609
0
            goto error;
3610
0
          rval_destroy(rv);
3611
0
          rv = 0;
3612
0
          trv = &rve->left.rve->left.rval;
3613
0
          if(trv->type == RV_LONG)
3614
0
            LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized int rve: "
3615
0
                 "op(op(a, $v), b) with op(%d, $v); op=%d\n",
3616
0
                rve->fpos.s_line, rve->fpos.s_col,
3617
0
                rve->fpos.e_line, rve->fpos.e_col,
3618
0
                (int)trv->v.l, rve->op);
3619
0
          else if(trv->type == RV_STR)
3620
0
            LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized str rve "
3621
0
                 "op(op(a, $v), b) with op(\"%.*s\", $v);"
3622
0
                 " op=%d\n",
3623
0
                rve->fpos.s_line, rve->fpos.s_col,
3624
0
                rve->fpos.e_line, rve->fpos.e_col, trv->v.s.len,
3625
0
                trv->v.s.s, rve->op);
3626
0
          ret = 1;
3627
0
        }
3628
        /* op(op($v, $w),b) => can't optimize */
3629
0
      }
3630
      /* op1(op2(...), b) and op1!=op2 or op is non assoc.
3631
       * => can't optimize */
3632
0
    } else if(rve_is_constant(rve->left.rve)) {
3633
      /* op1(a, op2(...)) */
3634
0
      if((rve->op == rve->right.rve->op) && rve_op_is_assoc(rve->op)) {
3635
        /* op(a, op(...)) */
3636
0
        if(rve_is_constant(rve->right.rve->right.rve)
3637
0
            && rve_op_is_commutative(rve->op)) {
3638
          /* op(a, op($v, b)) => op(op(a, b), $v) */
3639
          /* rv= op(a, b) */
3640
0
          tmp_rve.op = rve->op;
3641
0
          tmp_rve.left.rve = rve->left.rve;
3642
0
          tmp_rve.right.rve = rve->right.rve->right.rve;
3643
          /* no need for the RVE_PLUS_OP hack, all the bad
3644
           * cases are caught by rve_op_is_commutative()
3645
           * (in this case type will be typeof(a)) => ok only if
3646
           * typeof(a) is int) */
3647
0
          if((rv = rval_expr_eval_new(0, 0, &tmp_rve)) == 0) {
3648
0
            LM_ERR("optimization failure, bad expression\n");
3649
0
            goto error;
3650
0
          }
3651
          /* op(rv, $v) */
3652
0
          if(rve_replace_with_ct_rv(rve->left.rve, rv) < 0)
3653
0
            goto error;
3654
0
          rval_destroy(rv);
3655
0
          rv = 0;
3656
0
          rve_destroy(tmp_rve.right.rve);
3657
0
          rve->right.rve = rve->right.rve->left.rve;
3658
0
          trv = &rve->left.rve->left.rval;
3659
0
          if(trv->type == RV_LONG)
3660
0
            LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized int rve: "
3661
0
                 "op(a, op($v, b)) with op(%d, $v); op=%d\n",
3662
0
                rve->fpos.s_line, rve->fpos.s_col,
3663
0
                rve->fpos.e_line, rve->fpos.e_col,
3664
0
                (int)trv->v.l, rve->op);
3665
0
          else if(trv->type == RV_STR)
3666
0
            LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized str rve "
3667
0
                 "op(a, op($v, b)) with op(\"%.*s\", $v);"
3668
0
                 " op=%d\n",
3669
0
                rve->fpos.s_line, rve->fpos.s_col,
3670
0
                rve->fpos.e_line, rve->fpos.e_col, trv->v.s.len,
3671
0
                trv->v.s.s, rve->op);
3672
0
          ret = 1;
3673
0
        } else if(rve_is_constant(rve->right.rve->left.rve)) {
3674
          /* op(a, op(b, $v)) => op(op(a, b), $v) */
3675
          /* rv= op(a, b) */
3676
0
          tmp_rve.op = rve->op;
3677
0
          tmp_rve.left.rve = rve->left.rve;
3678
0
          tmp_rve.right.rve = rve->right.rve->left.rve;
3679
          /* hack for RVE_PLUS_OP which can work on string, ints
3680
           * or a combination of them */
3681
0
          if((rve->op == RVE_PLUS_OP)
3682
0
              && (rve_guess_type(tmp_rve.left.rve)
3683
0
                  != rve_guess_type(tmp_rve.right.rve))) {
3684
0
            LM_DBG("RVE optimization failed (%d,%d-%d,%d): cannot "
3685
0
                 "optimize +(a, +(b, $v)) when "
3686
0
                 "typeof(a)!=typeof(b)\n",
3687
0
                rve->fpos.s_line, rve->fpos.s_col,
3688
0
                rve->fpos.e_line, rve->fpos.e_col);
3689
0
            return 0;
3690
0
          }
3691
0
          if((rv = rval_expr_eval_new(0, 0, &tmp_rve)) == 0) {
3692
0
            LM_ERR("optimization failure, bad expression\n");
3693
0
            goto error;
3694
0
          }
3695
          /* op(rv, $v) */
3696
0
          if(rve_replace_with_ct_rv(rve->left.rve, rv) < 0)
3697
0
            goto error;
3698
0
          rval_destroy(rv);
3699
0
          rv = 0;
3700
0
          rve_destroy(tmp_rve.right.rve);
3701
0
          rve->right.rve = rve->right.rve->right.rve;
3702
0
          trv = &rve->left.rve->left.rval;
3703
0
          if(trv->type == RV_LONG)
3704
0
            LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized int rve: "
3705
0
                 "op(a, op(b, $v)) with op(%d, $v); op=%d\n",
3706
0
                rve->fpos.s_line, rve->fpos.s_col,
3707
0
                rve->fpos.e_line, rve->fpos.e_col,
3708
0
                (int)trv->v.l, rve->op);
3709
0
          else if(trv->type == RV_STR)
3710
0
            LM_DBG("FIXUP RVE (%d,%d-%d,%d): optimized str rve "
3711
0
                 "op(a, op(b, $v)) with op(\"%.*s\", $v);"
3712
0
                 " op=%d\n",
3713
0
                rve->fpos.s_line, rve->fpos.s_col,
3714
0
                rve->fpos.e_line, rve->fpos.e_col, trv->v.s.len,
3715
0
                trv->v.s.s, rve->op);
3716
0
          ret = 1;
3717
0
        }
3718
        /* op(a, op($v, $w)) => can't optimize */
3719
0
      }
3720
      /* op1(a, op2(...)) and op1!=op2 or op is non assoc.
3721
       * => can't optimize */
3722
0
    }
3723
    /* op(op($v,a), op($w,b)) => no optimizations for now (TODO) */
3724
0
  }
3725
0
end:
3726
0
  return ret;
3727
0
error:
3728
0
  if(rv)
3729
0
    rval_destroy(rv);
3730
0
  return -1;
3731
0
}
3732
3733
3734
/** fix a rval_expr.
3735
 * fixes action, bexprs, resolves selects, pvars and
3736
 * optimizes simple sub expressions (e.g. 1+2).
3737
 *
3738
 * @param p - pointer to a rval_expr
3739
 * @return 0 on success, <0 on error (modifies also *(struct rval_expr*)p)
3740
 */
3741
int fix_rval_expr(void *p)
3742
0
{
3743
0
  struct rval_expr *rve;
3744
0
  int ret;
3745
3746
0
  rve = (struct rval_expr *)p;
3747
3748
0
  switch(rve->op) {
3749
0
    case RVE_NONE_OP:
3750
0
      LM_BUG("empty rval expr\n");
3751
0
      break;
3752
0
    case RVE_RVAL_OP:
3753
0
      ret = fix_rval(&rve->left.rval, rve);
3754
0
      if(ret < 0)
3755
0
        goto error;
3756
0
      return ret;
3757
0
    case RVE_UMINUS_OP: /* unary operators */
3758
0
    case RVE_BOOL_OP:
3759
0
    case RVE_LNOT_OP:
3760
0
    case RVE_BNOT_OP:
3761
0
    case RVE_STRLEN_OP:
3762
0
    case RVE_STREMPTY_OP:
3763
0
    case RVE_DEFINED_OP:
3764
0
    case RVE_NOTDEFINED_OP:
3765
0
    case RVE_LONG_OP:
3766
0
    case RVE_STR_OP:
3767
0
      ret = fix_rval_expr((void *)rve->left.rve);
3768
0
      if(ret < 0)
3769
0
        goto error;
3770
0
      break;
3771
0
    case RVE_MUL_OP:
3772
0
    case RVE_DIV_OP:
3773
0
    case RVE_MOD_OP:
3774
0
    case RVE_MINUS_OP:
3775
0
    case RVE_BOR_OP:
3776
0
    case RVE_BAND_OP:
3777
0
    case RVE_BXOR_OP:
3778
0
    case RVE_BLSHIFT_OP:
3779
0
    case RVE_BRSHIFT_OP:
3780
0
    case RVE_LAND_OP:
3781
0
    case RVE_LOR_OP:
3782
0
    case RVE_GT_OP:
3783
0
    case RVE_GTE_OP:
3784
0
    case RVE_LT_OP:
3785
0
    case RVE_LTE_OP:
3786
0
    case RVE_PLUS_OP:
3787
0
    case RVE_IPLUS_OP:
3788
0
    case RVE_EQ_OP:
3789
0
    case RVE_DIFF_OP:
3790
0
    case RVE_IEQ_OP:
3791
0
    case RVE_IDIFF_OP:
3792
0
    case RVE_STREQ_OP:
3793
0
    case RVE_STRDIFF_OP:
3794
0
    case RVE_CONCAT_OP:
3795
0
    case RVE_SELVALEXP_OP:
3796
0
    case RVE_SELVALOPT_OP:
3797
0
      ret = fix_rval_expr((void *)rve->left.rve);
3798
0
      if(ret < 0)
3799
0
        goto error;
3800
0
      ret = fix_rval_expr((void *)rve->right.rve);
3801
0
      if(ret < 0)
3802
0
        goto error;
3803
0
      break;
3804
0
    case RVE_MATCH_OP:
3805
0
      ret = fix_match_rve(rve);
3806
0
      if(ret < 0)
3807
0
        goto error;
3808
0
      break;
3809
0
    default:
3810
0
      LM_BUG("unsupported op type %d (cfg line: %d col: %d)\n", rve->op,
3811
0
          rve->fpos.s_line, rve->fpos.s_col);
3812
0
  }
3813
  /* try to optimize */
3814
0
  rve_optimize(rve);
3815
0
  return 0;
3816
3817
0
error:
3818
0
  LM_ERR("failure in cfg at line: %d col: %d\n", rve->fpos.s_line,
3819
0
      rve->fpos.s_col);
3820
0
  return ret;
3821
0
}