Skip to content

Commit 22cbb4e

Browse files
Properly check script functions parameter types with the -c option
Also, do not omit from syntax checking functions that are part of IF statement experssions. Closes OpenSIPS#1993
1 parent bb7afdc commit 22cbb4e

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

mod_fix.c

+66
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,72 @@ static inline gparam_p alloc_gp(void)
7979
return gp;
8080
}
8181

82+
int check_cmd(struct cmd_param *params, action_elem_t *elems)
83+
{
84+
int i;
85+
struct cmd_param *param;
86+
pv_elem_t *pve;
87+
88+
for (param=params, i=1; param->flags; param++, i++) {
89+
pve = NULL;
90+
91+
if (elems[i].type == NOSUBTYPE || elems[i].type == NULLV_ST) {
92+
if (!(param->flags & CMD_PARAM_OPT)) {
93+
LM_BUG("Mandatory parameter missing\n");
94+
return -1;
95+
} else {
96+
continue;
97+
}
98+
}
99+
100+
if (param->flags & CMD_PARAM_INT) {
101+
if (elems[i].type != NUMBER_ST && elems[i].type != SCRIPTVAR_ST) {
102+
LM_ERR("Param [%d] expected to be an integer or variable\n", i);
103+
return -1;
104+
}
105+
} else if (param->flags & CMD_PARAM_STR) {
106+
if (elems[i].type == STR_ST) {
107+
if (!(param->flags & CMD_PARAM_NO_EXPAND) &&
108+
pv_parse_format(&elems[i].u.s, &pve) < 0) {
109+
LM_ERR("Failed to parse formatted string in param "
110+
"[%d]\n",i);
111+
return -1;
112+
}
113+
114+
if ((!(param->flags & CMD_PARAM_NO_EXPAND) &&
115+
(pve->next || pve->spec.type != PVT_NONE)) &&
116+
(param->flags & CMD_PARAM_STATIC)) {
117+
LM_ERR("Param [%d] does not support formatted strings\n",i);
118+
return -1;
119+
}
120+
121+
if (pve)
122+
pv_elem_free_all(pve);
123+
} else if (elems[i].type == SCRIPTVAR_ST) {
124+
if (param->flags & CMD_PARAM_STATIC) {
125+
LM_ERR("Param [%d] does not support variables\n",i);
126+
return -1;
127+
}
128+
} else {
129+
LM_ERR("Param [%d] expected to be a string or variable\n", i);
130+
return -1;
131+
}
132+
} else if (param->flags & CMD_PARAM_VAR) {
133+
if (elems[i].type != SCRIPTVAR_ST) {
134+
LM_ERR("Param [%d] expected to be a variable\n",i);
135+
return -1;
136+
}
137+
} else if (param->flags & CMD_PARAM_REGEX) {
138+
if (elems[i].type != STR_ST && elems[i].type != SCRIPTVAR_ST) {
139+
LM_ERR("Param [%d] expected to be an integer or variable\n", i);
140+
return -1;
141+
}
142+
}
143+
}
144+
145+
return 0;
146+
}
147+
82148
int fix_cmd(struct cmd_param *params, action_elem_t *elems)
83149
{
84150
int i;

mod_fix.h

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ typedef struct _gparam
4545

4646
struct cmd_param;
4747

48+
int check_cmd(struct cmd_param *params, action_elem_t *elems);
4849
int fix_cmd(struct cmd_param *params, action_elem_t *elems);
4950
int get_cmd_fixups(struct sip_msg* msg, struct cmd_param *params,
5051
action_elem_t *elems, void **cmdp, pv_value_t *tmp_val);

route.c

+61
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,8 @@ static int rcheck_stack[RT_NO];
14751475
static int rcheck_stack_p = 0;
14761476
static int rcheck_status = 0;
14771477

1478+
static int check_expr(struct expr* exp, int r_type);
1479+
14781480
static int check_actions(struct action *a, int r_type)
14791481
{
14801482
struct action *aitem;
@@ -1502,6 +1504,8 @@ static int check_actions(struct action *a, int r_type)
15021504
rcheck_stack_p--;
15031505
break;
15041506
case IF_T:
1507+
if (check_expr((struct expr*)a->elem[0].u.data, r_type) < 0)
1508+
goto error;
15051509
if (check_actions((struct action*)a->elem[1].u.data, r_type)!=0)
15061510
goto error;
15071511
if (check_actions((struct action*)a->elem[2].u.data, r_type)!=0)
@@ -1535,6 +1539,12 @@ static int check_actions(struct action *a, int r_type)
15351539
LM_ERR("route stack[%d]=%d\n",n,rcheck_stack[n]);
15361540
}
15371541
}
1542+
1543+
if (check_cmd(fct->params, a->elem) < 0) {
1544+
LM_ERR("check failed for function <%s>, %s:%d\n", fct->name,
1545+
a->file, a->line);
1546+
rcheck_status = -1;
1547+
}
15381548
break;
15391549
default:
15401550
break;
@@ -1546,6 +1556,57 @@ static int check_actions(struct action *a, int r_type)
15461556
return -1;
15471557
}
15481558

1559+
static int check_expr(struct expr* exp, int r_type)
1560+
{
1561+
int ret = -1;
1562+
1563+
if (exp==0) {
1564+
LM_CRIT("null pointer\n");
1565+
return -1;
1566+
}
1567+
1568+
if (exp->type==EXP_T){
1569+
switch(exp->op){
1570+
case AND_OP:
1571+
case OR_OP:
1572+
if (check_expr(exp->left.v.expr, r_type) < 0)
1573+
return -1;
1574+
return check_expr(exp->right.v.expr, r_type);
1575+
case NOT_OP:
1576+
case EVAL_OP:
1577+
return check_expr(exp->left.v.expr, r_type);
1578+
default:
1579+
LM_CRIT("unknown op %d\n", exp->op);
1580+
return -1;
1581+
}
1582+
} else if (exp->type==ELEM_T){
1583+
if (exp->left.type==ACTION_O){
1584+
ret=check_actions((struct action*)exp->right.v.data, r_type);
1585+
if (ret!=0){
1586+
LM_CRIT("check_actions error\n");
1587+
return ret;
1588+
}
1589+
}
1590+
if (exp->left.type==EXPR_O){
1591+
ret=check_expr(exp->left.v.expr, r_type);
1592+
if (ret!=0){
1593+
LM_CRIT("check left exp error\n");
1594+
return ret;
1595+
}
1596+
}
1597+
if (exp->right.type==EXPR_ST){
1598+
ret=check_expr(exp->right.v.expr, r_type);
1599+
if (ret!=0){
1600+
LM_CRIT("fix right exp error\n");
1601+
return ret;
1602+
}
1603+
}
1604+
ret=0;
1605+
}
1606+
1607+
return ret;
1608+
}
1609+
15491610

15501611
/*! \brief check all parsed routing tables for compatiblity between
15511612
* route types and called module functions;

0 commit comments

Comments
 (0)