Skip to content

Commit ed60363

Browse files
committed
Improve qvalue parsing
* accept qvalues with no decimal digits (e.g. "1." and "0.") (this removes E_Q_DEC_MISSING from error.h) * improve bad qvalue error reporting
1 parent 0a2cc3e commit ed60363

File tree

7 files changed

+30
-26
lines changed

7 files changed

+30
-26
lines changed

cfg.y

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ extern int yylex();
125125
static void yyerror(char* s);
126126
static void yyerrorf(char* fmt, ...);
127127
static char* tmp;
128-
static int i_tmp;
128+
static int i_tmp, rc;
129129
static void* cmd_tmp;
130130
static struct socket_id* lst_tmp;
131131
static int rt; /* Type of route block for find_export */
@@ -2233,12 +2233,17 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T,
22332233
| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, "
22342234
"number expected"); }
22352235
| APPEND_BRANCH LPAREN STRING COMMA STRING RPAREN {
2236-
{ qvalue_t q;
2237-
if (str2q(&q, $5, strlen($5)) < 0) {
2238-
yyerror("bad argument, q value expected");
2239-
}
2236+
{
2237+
qvalue_t q;
2238+
2239+
rc = str2q(&q, $5, strlen($5));
2240+
if (rc < 0)
2241+
yyerrorf("bad qvalue (%.*s): %s",
2242+
strlen($5), $5, qverr2str(rc));
2243+
22402244
mk_action2( $$, APPEND_BRANCH_T, STR_ST, NUMBER_ST, $3,
2241-
(void *)(long)q); }
2245+
(void *)(long)q);
2246+
}
22422247
}
22432248
| APPEND_BRANCH LPAREN STRING RPAREN { mk_action2( $$, APPEND_BRANCH_T,
22442249
STR_ST, NUMBER_ST, $3, (void *)Q_UNSPECIFIED) ; }

error.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ int err2reason_phrase(
103103
error_txt="q parameter too big";
104104
*sip_error=-E_BAD_REQ;
105105
break;
106-
case E_Q_DEC_MISSING:
107-
error_txt="Decimal part missing in q";
108-
*sip_error=-E_BAD_REQ;
109-
break;
110106
case E_NO_DESTINATION:
111107
error_txt="No destination available";
112108
*sip_error=-E_BAD_SERVER;

error.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@
4444
#define E_Q_INV_CHAR -15 /*!< Invalid character in q */
4545
#define E_Q_EMPTY -16 /*!< Empty q */
4646
#define E_Q_TOO_BIG -17 /*!< q too big (> 1) */
47-
#define E_Q_DEC_MISSING -18 /*!< Decimal part missing */
48-
#define E_NO_DESTINATION -19 /*!< No available destination */
47+
#define E_NO_DESTINATION -18 /*!< No available destination */
4948

5049
/* opensips specific error codes */
5150
#define E_IP_BLOCKED -473 /*!< destination filtered */

modules/registrar/sip_msg.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,16 @@ void calc_contact_expires(struct sip_msg* _m, param_t* _ep, int* _e, struct save
279279
*/
280280
int calc_contact_q(param_t* _q, qvalue_t* _r)
281281
{
282+
int rc;
283+
282284
if (!_q || (_q->body.len == 0)) {
283285
*_r = default_q;
284286
} else {
285-
if (str2q(_r, _q->body.s, _q->body.len) < 0) {
287+
rc = str2q(_r, _q->body.s, _q->body.len);
288+
if (rc < 0) {
286289
rerrno = R_INV_Q; /* Invalid q parameter */
287-
LM_ERR("invalid q parameter\n");
290+
LM_ERR("invalid qvalue (%.*s): %s\n",
291+
_q->body.len, _q->body.s, qverr2str(rc));
288292
return -1;
289293
}
290294
}

modules/uac_redirect/rd_funcs.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static void sort_contacts(contact_t *ct_list, str *ct_array,
104104
{
105105
param_t *q_para;
106106
qvalue_t q;
107-
int i,j;
107+
int i, j, rc;
108108
char backup;
109109

110110
for( ; ct_list ; ct_list = ct_list->next ) {
@@ -121,8 +121,10 @@ static void sort_contacts(contact_t *ct_list, str *ct_array,
121121
if (q_para==0 || q_para->body.len==0) {
122122
q = DEFAULT_Q_VALUE;
123123
} else {
124-
if (str2q( &q, q_para->body.s, q_para->body.len)!=0) {
125-
LM_ERR("invalid q param\n");
124+
rc = str2q( &q, q_para->body.s, q_para->body.len);
125+
if (rc != 0) {
126+
LM_ERR("invalid qvalue (%.*s): %s\n",
127+
q_para->body.len, q_para->body.s, qverr2str(rc));
126128
/* skip this contact */
127129
continue;
128130
}

qvalue.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ int str2q(qvalue_t* q, char* s, int len)
7373
break;
7474

7575
case '.':
76+
*q = 0;
7677
state = ST_0_PT;
7778
break;
7879

@@ -165,15 +166,8 @@ int str2q(qvalue_t* q, char* s, int len)
165166
}
166167
}
167168

168-
switch(state) {
169-
case ST_START:
169+
if (state == ST_START)
170170
return E_Q_EMPTY;
171171

172-
case ST_0_PT:
173-
case ST_1_PT:
174-
return E_Q_DEC_MISSING;
175-
176-
default:
177-
return 0;
178-
}
172+
return 0;
179173
}

qvalue.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ typedef int qvalue_t;
7474
#define Q_PREFIX "0."
7575
#define Q_PREFIX_LEN (sizeof(Q_PREFIX) - 1)
7676

77+
#define qverr2str(rc) \
78+
(rc == E_Q_INV_CHAR ? "bad characters" : \
79+
rc == E_Q_EMPTY ? "empty value" : \
80+
rc == E_Q_TOO_BIG ? "max value is 1.0" : "bad qvalue")
7781

7882

7983
/*! \brief

0 commit comments

Comments
 (0)