Coverage Report

Created: 2025-08-26 06:38

/src/opensips/parser/parse_to.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2001-2003 Fhg Fokus
3
 *
4
 * This file is part of opensips, a free SIP server.
5
 *
6
 * opensips is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version
10
 *
11
 * opensips is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19
 *
20
 * History:
21
 * ---------
22
 * 2003-04-26 ZSW (jiri)
23
 * 2006-05-29 removed the NO_PINGTEL_TAG_HACK - it's conflicting the RFC 3261;
24
 *            TAG parameter must have value; other parameters are accepted
25
 *            without value (bogdan)
26
 */
27
28
29
#include "parse_to.h"
30
#include <stdlib.h>
31
#include <string.h>
32
#include "../dprint.h"
33
#include "msg_parser.h"
34
#include "parse_uri.h"
35
#include "../ut.h"
36
#include "../mem/mem.h"
37
#include "../errinfo.h"
38
39
40
enum {
41
  START_TO, DISPLAY_QUOTED, E_DISPLAY_QUOTED, DISPLAY_TOKEN, DISPLAY_TOKEN2,
42
  S_URI_ENCLOSED, URI_ENCLOSED, E_URI_ENCLOSED,
43
  URI_OR_TOKEN, MAYBE_URI_END, END, F_CR, F_LF, F_CRLF
44
};
45
46
47
enum {
48
  S_PARA_NAME=20, PARA_NAME, S_EQUAL, S_PARA_VALUE, TAG1, TAG2,
49
  TAG3, PARA_VALUE_TOKEN , PARA_VALUE_QUOTED, E_PARA_VALUE
50
};
51
52
53
54
#define add_param( _param , _body ) \
55
94.1k
  do{\
56
94.1k
    LM_DBG("%.*s=%.*s\n",param->name.len,ZSW(param->name.s),\
57
0
      param->value.len,ZSW(param->value.s));\
58
94.1k
    if (!(_body)->param_lst)  (_body)->param_lst=(_param);\
59
94.1k
    else (_body)->last_param->next=(_param);\
60
94.1k
    (_body)->last_param =(_param);\
61
94.1k
    if ((_param)->type==TAG_PARAM)\
62
94.1k
      memcpy(&((_body)->tag_value),&((_param)->value),sizeof(str));\
63
94.1k
    (_param) = 0;\
64
94.1k
  }while(0);
65
66
67
68
void free_to_params(struct to_body* tb)
69
5.60M
{
70
5.60M
  struct to_param *tp=tb->param_lst;
71
5.60M
  struct to_param *foo;
72
5.69M
  while (tp){
73
94.1k
    foo = tp->next;
74
94.1k
    pkg_free(tp);
75
94.1k
    tp=foo;
76
94.1k
  }
77
78
5.60M
  tb->param_lst = tb->last_param = NULL;
79
5.60M
}
80
81
82
void free_to(struct to_body* tb)
83
5.68M
{
84
5.68M
  if (tb) {
85
5.59M
    free_to( tb->next );
86
5.59M
    free_to_params(tb);
87
5.59M
    pkg_free(tb);
88
5.59M
  }
89
5.68M
}
90
91
92
static inline char* parse_to_param(char *buffer, char *end,
93
          struct to_body *to_b,
94
          int *returned_status,
95
          int multi)
96
55.8k
{
97
55.8k
  struct to_param *param;
98
55.8k
  int status;
99
55.8k
  int saved_status;
100
55.8k
  char  *tmp;
101
102
55.8k
  param=0;
103
55.8k
  status=E_PARA_VALUE;
104
55.8k
  saved_status=E_PARA_VALUE;
105
1.71M
  for( tmp=buffer; tmp<end; tmp++)
106
1.71M
  {
107
1.71M
    switch(*tmp)
108
1.71M
    {
109
16.5k
      case ' ':
110
26.9k
      case '\t':
111
26.9k
        switch (status)
112
26.9k
        {
113
430
          case TAG3:
114
430
            param->type=TAG_PARAM;
115
3.96k
          case PARA_NAME:
116
5.17k
          case TAG1:
117
5.68k
          case TAG2:
118
5.68k
            param->name.len = tmp-param->name.s;
119
5.68k
            status = S_EQUAL;
120
5.68k
            break;
121
3.72k
          case PARA_VALUE_TOKEN:
122
3.72k
            param->value.len = tmp-param->value.s;
123
3.72k
            status = E_PARA_VALUE;
124
3.72k
            add_param( param , to_b );
125
3.72k
            break;
126
665
          case F_CRLF:
127
6.23k
          case F_LF:
128
11.1k
          case F_CR:
129
            /*previous=crlf and now =' '*/
130
11.1k
            status=saved_status;
131
11.1k
            break;
132
26.9k
        }
133
26.9k
        break;
134
39.8k
      case '\n':
135
39.8k
        switch (status)
136
39.8k
        {
137
1.21k
          case S_PARA_NAME:
138
2.30k
          case S_EQUAL:
139
3.32k
          case S_PARA_VALUE:
140
5.14k
          case E_PARA_VALUE:
141
5.14k
            saved_status=status;
142
5.14k
            status=F_LF;
143
5.14k
            break;
144
421
          case TAG3:
145
421
            param->type=TAG_PARAM;
146
11.4k
          case PARA_NAME:
147
12.7k
          case TAG1:
148
13.9k
          case TAG2:
149
13.9k
            param->name.len = tmp-param->name.s;
150
13.9k
            saved_status = S_EQUAL;
151
13.9k
            status = F_LF;
152
13.9k
            break;
153
7.18k
          case PARA_VALUE_TOKEN:
154
7.18k
            param->value.len = tmp-param->value.s;
155
7.18k
            saved_status = E_PARA_VALUE;
156
7.18k
            status = F_LF;
157
7.18k
            add_param( param , to_b );
158
7.18k
            break;
159
13.3k
          case F_CR:
160
13.3k
            status=F_CRLF;
161
13.3k
            break;
162
2
          case F_CRLF:
163
8
          case F_LF:
164
8
            status=saved_status;
165
8
            goto endofheader;
166
221
          default:
167
221
            goto parse_error;
168
39.8k
        }
169
39.6k
        break;
170
39.6k
      case '\r':
171
25.2k
        switch (status)
172
25.2k
        {
173
1.08k
          case S_PARA_NAME:
174
1.85k
          case S_EQUAL:
175
2.51k
          case S_PARA_VALUE:
176
3.37k
          case E_PARA_VALUE:
177
3.37k
            saved_status=status;
178
3.37k
            status=F_CR;
179
3.37k
            break;
180
623
          case TAG3:
181
623
            param->type=TAG_PARAM;
182
16.3k
          case PARA_NAME:
183
17.9k
          case TAG1:
184
18.2k
          case TAG2:
185
18.2k
            param->name.len = tmp-param->name.s;
186
18.2k
            saved_status = S_EQUAL;
187
18.2k
            status = F_CR;
188
18.2k
            break;
189
3.56k
          case PARA_VALUE_TOKEN:
190
3.56k
            param->value.len = tmp-param->value.s;
191
3.56k
            saved_status = E_PARA_VALUE;
192
3.56k
            status = F_CR;
193
3.56k
            add_param( param , to_b );
194
3.56k
            break;
195
3
          case F_CRLF:
196
25
          case F_CR:
197
28
          case F_LF:
198
28
            status=saved_status;
199
28
            goto endofheader;
200
40
          default:
201
40
            goto parse_error;
202
25.2k
        }
203
25.1k
        break;
204
25.1k
      case  0:
205
15.4k
      case ',':
206
15.4k
        switch (status)
207
15.4k
        {
208
2.24k
          case PARA_VALUE_QUOTED:
209
2.24k
            break;
210
7.20k
          case PARA_NAME:
211
7.20k
            param->name.len = tmp-param->name.s;
212
8.43k
          case S_EQUAL:
213
9.43k
          case S_PARA_VALUE:
214
9.43k
            if (param->type==TAG_PARAM)
215
34
              goto parse_error;
216
9.39k
            param->value.s = tmp;
217
12.1k
          case PARA_VALUE_TOKEN:
218
12.1k
            status = E_PARA_VALUE;
219
12.1k
            param->value.len = tmp-param->value.s;
220
12.1k
            add_param( param , to_b );
221
13.0k
          case E_PARA_VALUE:
222
13.0k
            saved_status = status;
223
13.0k
            if ( !multi && *tmp==',')
224
278
              goto parse_error;
225
12.8k
            goto endofheader;
226
12.8k
            break;
227
12.8k
          default:
228
120
            goto parse_error;
229
15.4k
        }
230
2.24k
        break;
231
2.24k
      case '\\':
232
610
        switch (status)
233
610
        {
234
475
          case PARA_VALUE_QUOTED:
235
475
            if (tmp+1==end)
236
3
              goto parse_error;
237
472
            switch (*(tmp+1))
238
472
            {
239
18
              case '\r':
240
36
              case '\n':
241
36
                break;
242
436
              default:
243
436
                tmp++;
244
436
                break;
245
472
            }
246
472
            break;
247
472
          default:
248
135
            goto parse_error;
249
610
        }
250
472
        break;
251
5.86k
      case '"':
252
5.86k
        switch (status)
253
5.86k
        {
254
2.35k
          case S_PARA_VALUE:
255
2.35k
            param->value.s = tmp+1;
256
2.35k
            status = PARA_VALUE_QUOTED;
257
2.35k
            break;
258
1.95k
          case PARA_VALUE_QUOTED:
259
1.95k
            param->value.len=tmp-param->value.s ;
260
1.95k
            add_param( param , to_b );
261
1.95k
            status = E_PARA_VALUE;
262
1.95k
            break;
263
442
          case F_CRLF:
264
897
          case F_LF:
265
1.44k
          case F_CR:
266
            /*previous=crlf and now !=' '*/
267
1.44k
            goto endofheader;
268
116
          default:
269
116
            goto parse_error;
270
5.86k
        }
271
4.30k
        break;
272
99.6k
      case ';' :
273
99.6k
        switch (status)
274
99.6k
        {
275
541
          case PARA_VALUE_QUOTED:
276
541
            break;
277
20.8k
          case PARA_NAME:
278
20.8k
            param->name.len = tmp-param->name.s;
279
25.2k
          case S_EQUAL:
280
26.9k
          case S_PARA_VALUE:
281
26.9k
            if (param->type==TAG_PARAM)
282
19
              goto parse_error;
283
26.9k
            param->value.s = tmp;
284
35.6k
          case PARA_VALUE_TOKEN:
285
35.6k
            param->value.len=tmp-param->value.s;
286
35.6k
            add_param(param,to_b);
287
97.0k
          case E_PARA_VALUE:
288
97.0k
            param = (struct to_param*)
289
97.0k
              pkg_malloc(sizeof(struct to_param));
290
97.0k
            if (!param){
291
0
              LM_ERR("out of pkg memory\n" );
292
0
              goto error;
293
0
            }
294
97.0k
            memset(param,0,sizeof(struct to_param));
295
97.0k
            param->type=GENERAL_PARAM;
296
97.0k
            status = S_PARA_NAME;
297
97.0k
            break;
298
583
          case F_CRLF:
299
1.22k
          case F_LF:
300
2.05k
          case F_CR:
301
            /*previous=crlf and now !=' '*/
302
2.05k
            goto endofheader;
303
59
          default:
304
59
            goto parse_error;
305
99.6k
        }
306
97.5k
        break;
307
97.5k
      case 'T':
308
77.6k
      case 't' :
309
77.6k
        switch (status)
310
77.6k
        {
311
1.20k
          case PARA_VALUE_QUOTED:
312
10.7k
          case PARA_VALUE_TOKEN:
313
19.0k
          case PARA_NAME:
314
19.0k
            break;
315
38.2k
          case S_PARA_NAME:
316
38.2k
            param->name.s = tmp;
317
38.2k
            status = TAG1;
318
38.2k
            break;
319
2.42k
          case S_PARA_VALUE:
320
2.42k
            param->value.s = tmp;
321
2.42k
            status = PARA_VALUE_TOKEN;
322
2.42k
            break;
323
795
          case TAG1:
324
1.57k
          case TAG2:
325
1.98k
          case TAG3:
326
1.98k
            status = PARA_NAME;
327
1.98k
            break;
328
5.84k
          case F_CRLF:
329
13.9k
          case F_LF:
330
15.8k
          case F_CR:
331
            /*previous=crlf and now !=' '*/
332
15.8k
            goto endofheader;
333
48
          default:
334
48
            goto parse_error;
335
77.6k
        }
336
61.7k
        break;
337
61.7k
      case 'A':
338
62.0k
      case 'a' :
339
62.0k
        switch (status)
340
62.0k
        {
341
938
          case PARA_VALUE_QUOTED:
342
8.15k
          case PARA_VALUE_TOKEN:
343
26.8k
          case PARA_NAME:
344
26.8k
            break;
345
4.84k
          case S_PARA_NAME:
346
4.84k
            param->name.s = tmp;
347
4.84k
            status = PARA_NAME;
348
4.84k
            break;
349
930
          case S_PARA_VALUE:
350
930
            param->value.s = tmp;
351
930
            status = PARA_VALUE_TOKEN;
352
930
            break;
353
20.7k
          case TAG1:
354
20.7k
            status = TAG2;
355
20.7k
            break;
356
962
          case TAG2:
357
1.71k
          case TAG3:
358
1.71k
            status = PARA_NAME;
359
1.71k
            break;
360
3.27k
          case F_CRLF:
361
5.98k
          case F_LF:
362
6.84k
          case F_CR:
363
            /*previous=crlf and now !=' '*/
364
6.84k
            goto endofheader;
365
39
          default:
366
39
            goto parse_error;
367
62.0k
        }
368
55.1k
        break;
369
55.1k
      case 'G':
370
39.7k
      case 'g' :
371
39.7k
        switch (status)
372
39.7k
        {
373
490
          case PARA_VALUE_QUOTED:
374
5.86k
          case PARA_VALUE_TOKEN:
375
15.9k
          case PARA_NAME:
376
15.9k
            break;
377
3.07k
          case S_PARA_NAME:
378
3.07k
            param->name.s = tmp;
379
3.07k
            status = PARA_NAME;
380
3.07k
            break;
381
1.74k
          case S_PARA_VALUE:
382
1.74k
            param->value.s = tmp;
383
1.74k
            status = PARA_VALUE_TOKEN;
384
1.74k
            break;
385
1.03k
          case TAG1:
386
2.82k
          case TAG3:
387
2.82k
            status = PARA_NAME;
388
2.82k
            break;
389
13.5k
          case TAG2:
390
13.5k
            status = TAG3;
391
13.5k
            break;
392
447
          case F_CRLF:
393
1.57k
          case F_LF:
394
2.47k
          case F_CR:
395
            /*previous=crlf and now !=' '*/
396
2.47k
            goto endofheader;
397
65
          default:
398
65
            goto parse_error;
399
39.7k
        }
400
37.1k
        break;
401
37.1k
      case '=':
402
34.6k
        switch (status)
403
34.6k
        {
404
526
          case PARA_VALUE_QUOTED:
405
526
            break;
406
8.42k
          case TAG3:
407
8.42k
            param->type=TAG_PARAM;
408
24.4k
          case PARA_NAME:
409
28.6k
          case TAG1:
410
29.6k
          case TAG2:
411
29.6k
            param->name.len = tmp-param->name.s;
412
29.6k
            status = S_PARA_VALUE;
413
29.6k
            break;
414
2.35k
          case S_EQUAL:
415
2.35k
            status = S_PARA_VALUE;
416
2.35k
            break;
417
436
          case F_CRLF:
418
1.49k
          case F_LF:
419
1.94k
          case F_CR:
420
            /*previous=crlf and now !=' '*/
421
1.94k
            goto endofheader;
422
191
          default:
423
191
            goto parse_error;
424
34.6k
        }
425
32.5k
        break;
426
1.28M
      default:
427
1.28M
        switch (status)
428
1.28M
        {
429
7.32k
          case TAG1:
430
9.71k
          case TAG2:
431
10.4k
          case TAG3:
432
10.4k
            status = PARA_NAME;
433
10.4k
            break;
434
199k
          case PARA_VALUE_TOKEN:
435
1.19M
          case PARA_NAME:
436
1.19M
          case PARA_VALUE_QUOTED:
437
1.19M
            break;
438
49.7k
          case S_PARA_NAME:
439
49.7k
            param->name.s = tmp;
440
49.7k
            status = PARA_NAME;
441
49.7k
            break;
442
20.9k
          case S_PARA_VALUE:
443
20.9k
            param->value.s = tmp;
444
20.9k
            status = PARA_VALUE_TOKEN;
445
20.9k
            break;
446
1.66k
          case F_CRLF:
447
7.53k
          case F_LF:
448
8.78k
          case F_CR:
449
            /*previous=crlf and now !=' '*/
450
8.78k
            goto endofheader;
451
683
          default:
452
683
            LM_ERR("spitting out [%c] in status %d\n",*tmp,status );
453
683
            goto error;
454
1.28M
        }
455
1.71M
    }/*switch*/
456
1.71M
  }/*for*/
457
458
1.59k
  if (status==PARA_VALUE_QUOTED) {
459
132
      LM_ERR("unexpected end of header in state %d\n", status);
460
132
      goto parse_error;
461
132
  }
462
463
53.7k
endofheader:
464
53.7k
  LM_DBG("end of header reached, state=%d\n", status);
465
53.7k
  if (param) {
466
31.3k
    if (saved_status==S_EQUAL||saved_status==S_PARA_VALUE) {
467
30.1k
      saved_status = E_PARA_VALUE;
468
30.1k
      param->value.s= 0;
469
30.1k
      param->value.len=0;
470
30.1k
      if (param->type==TAG_PARAM)
471
165
        goto parse_error;
472
29.9k
      add_param(param, to_b);
473
29.9k
    } else {
474
1.25k
      pkg_free(param);
475
1.25k
    }
476
31.3k
  }
477
53.5k
  *returned_status=saved_status;
478
53.5k
  return tmp;
479
480
1.66k
parse_error:
481
1.66k
  LM_ERR("unexpected char [%c] in status %d: <<%.*s>> .\n",
482
1.66k
      tmp < end? *tmp : *(end-1),status, (int)(tmp-buffer), ZSW(buffer));
483
2.34k
error:
484
2.34k
  if (param) pkg_free(param);
485
2.34k
  free_to_params(to_b);
486
2.34k
  to_b->error=PARSE_ERROR;
487
2.34k
  *returned_status = status;
488
2.34k
  return tmp;
489
1.66k
}
490
491
492
493
494
static inline char* _parse_to(char* buffer, char *end, struct to_body *to_b,
495
                                  int multi)
496
89.3k
{
497
89.3k
  int status;
498
89.3k
  int saved_status;
499
89.3k
  char  *tmp;
500
89.3k
  char  *end_mark;
501
89.3k
  struct to_body *first_b = to_b;
502
503
89.3k
  status=START_TO;
504
89.3k
  saved_status=START_TO;
505
89.3k
  memset(to_b, 0, sizeof(struct to_body));
506
89.3k
  to_b->error=PARSE_OK;
507
89.3k
  end_mark=0;
508
509
14.5M
  for( tmp=buffer; tmp<end; tmp++)
510
14.5M
  {
511
14.5M
    switch(*tmp)
512
14.5M
    {
513
2.55M
      case ' ':
514
2.55M
      case '\t':
515
2.55M
        switch (status)
516
2.55M
        {
517
704
          case F_CRLF:
518
3.86k
          case F_LF:
519
6.36k
          case F_CR:
520
            /*previous=crlf and now =' '*/
521
6.36k
            status=saved_status;
522
6.36k
            break;
523
1.24k
          case URI_ENCLOSED:
524
1.24k
            to_b->uri.len = tmp - to_b->uri.s;
525
1.24k
            status = E_URI_ENCLOSED;
526
1.24k
            break;
527
15.5k
          case URI_OR_TOKEN:
528
15.5k
            status = MAYBE_URI_END;
529
15.5k
            end_mark = tmp;
530
15.5k
            break;
531
2.19k
          case DISPLAY_TOKEN:
532
2.19k
            end_mark = tmp;
533
2.19k
            status = DISPLAY_TOKEN2;
534
2.19k
            break;
535
2.55M
        }
536
2.55M
        break;
537
2.55M
      case '\n':
538
28.4k
        switch (status)
539
28.4k
        {
540
11.2k
          case URI_OR_TOKEN:
541
11.2k
            end_mark = tmp;
542
11.2k
            status = MAYBE_URI_END;
543
12.5k
          case MAYBE_URI_END:
544
13.4k
          case DISPLAY_TOKEN:
545
14.3k
          case DISPLAY_TOKEN2:
546
14.5k
          case E_DISPLAY_QUOTED:
547
19.4k
          case END:
548
19.4k
            saved_status=status;
549
19.4k
            status=F_LF;
550
19.4k
            break;
551
8.34k
          case F_CR:
552
8.34k
            status=F_CRLF;
553
8.34k
            break;
554
2
          case F_CRLF:
555
10
          case F_LF:
556
10
            status=saved_status;
557
10
            goto endofheader;
558
669
          default:
559
669
            goto parse_error;
560
28.4k
        }
561
27.7k
        break;
562
27.7k
      case '\r':
563
16.9k
        switch (status)
564
16.9k
        {
565
12.5k
          case URI_OR_TOKEN:
566
12.5k
            end_mark = tmp;
567
12.5k
            status = MAYBE_URI_END;
568
            /* fall through */
569
13.7k
          case MAYBE_URI_END:
570
14.2k
          case DISPLAY_TOKEN:
571
15.3k
          case DISPLAY_TOKEN2:
572
15.7k
          case E_DISPLAY_QUOTED:
573
16.8k
          case END:
574
16.8k
            saved_status=status;
575
16.8k
            status=F_CR;
576
16.8k
            break;
577
2
          case F_CRLF:
578
41
          case F_CR:
579
52
          case F_LF:
580
52
            status=saved_status;
581
52
            goto endofheader;
582
66
          default:
583
66
            goto parse_error;
584
16.9k
        }
585
16.8k
        break;
586
16.8k
      case 0:
587
4.89k
        switch (status)
588
4.89k
        {
589
3.81k
          case URI_OR_TOKEN:
590
4.28k
          case MAYBE_URI_END:
591
4.28k
            to_b->uri.len = tmp - to_b->uri.s;
592
            /* fall through */
593
4.73k
          case END:
594
4.73k
            saved_status = status = END;
595
4.73k
            goto endofheader;
596
162
          default:
597
162
            goto parse_error;
598
4.89k
        }
599
0
        break;
600
5.51M
      case ',':
601
5.51M
        switch (status)
602
5.51M
        {
603
713
          case DISPLAY_QUOTED:
604
6.00k
          case URI_ENCLOSED:
605
6.00k
            break;
606
5.50M
          case URI_OR_TOKEN:
607
            /* the next transition cannot be determined here. The
608
             * ',' maybe part of the username inside URI, or 
609
             * it can be separator between 2 hdr parts. As this
610
             * parsed is not URI aware (we do not actually parse
611
             * the URI, but we simply skip it), we have no idea
612
             * in which care we are..... For the moment, if the
613
             * header is marked as single part, at least let's
614
             * consider the ',' as part of the URI */
615
5.50M
            if (multi==0)
616
4.55k
              break;
617
5.50M
          case MAYBE_URI_END:
618
5.50M
            to_b->uri.len = tmp - to_b->uri.s;
619
            /* fall through */
620
5.50M
          case END:
621
5.50M
            if (multi==0)
622
51
              goto parse_error;
623
5.50M
            to_b->next = (struct to_body*)
624
5.50M
              pkg_malloc(sizeof(struct to_body));
625
5.50M
            if (to_b->next==NULL) {
626
0
              LM_ERR("failed to allocate new TO body\n");
627
0
              goto error;
628
0
            }
629
5.50M
            to_b = to_b->next;
630
5.50M
            memset(to_b, 0, sizeof(struct to_body));
631
5.50M
            to_b->error = PARSE_OK;
632
5.50M
            saved_status = status = START_TO;
633
5.50M
            end_mark=0;
634
5.50M
            break;
635
113
          default:
636
113
            goto parse_error;
637
5.51M
        }
638
5.51M
        break;
639
5.51M
      case '\\':
640
439
        switch (status)
641
439
        {
642
403
          case DISPLAY_QUOTED:
643
403
            tmp++; /* jump over next char */
644
403
            break;
645
36
          default:
646
36
            goto parse_error;
647
439
        }
648
403
        break;
649
16.0k
      case '<':
650
16.0k
        switch (status)
651
16.0k
        {
652
8.20k
          case START_TO:
653
8.20k
            to_b->body.s=tmp;
654
8.20k
            status = S_URI_ENCLOSED;
655
8.20k
            break;
656
427
          case DISPLAY_QUOTED:
657
427
            break;
658
592
          case E_DISPLAY_QUOTED:
659
592
            status = S_URI_ENCLOSED;
660
592
            break;
661
3.10k
          case URI_OR_TOKEN:
662
3.80k
          case DISPLAY_TOKEN:
663
3.80k
            end_mark = tmp;
664
            /* fall through */
665
4.52k
          case DISPLAY_TOKEN2:
666
5.29k
          case MAYBE_URI_END:
667
5.29k
            to_b->display.len=end_mark-to_b->display.s;
668
5.29k
            status = S_URI_ENCLOSED;
669
5.29k
            break;
670
606
          case F_CRLF:
671
1.01k
          case F_LF:
672
1.45k
          case F_CR:
673
            /*previous=crlf and now !=' '*/
674
1.45k
            goto endofheader;
675
66
          default:
676
66
            goto parse_error;
677
16.0k
        }
678
14.5k
        break;
679
19.2k
      case '>':
680
19.2k
        switch (status)
681
19.2k
        {
682
438
          case DISPLAY_QUOTED:
683
438
            break;
684
12.3k
          case URI_ENCLOSED:
685
12.3k
            to_b->uri.len = tmp - to_b->uri.s;
686
            /* fall through */
687
13.5k
          case E_URI_ENCLOSED:
688
13.5k
            status = END;
689
13.5k
            break;
690
3.29k
          case F_CRLF:
691
3.78k
          case F_LF:
692
5.11k
          case F_CR:
693
            /*previous=crlf and now !=' '*/
694
5.11k
            goto endofheader;
695
106
          default:
696
106
            goto parse_error;
697
19.2k
        }
698
14.0k
        break;
699
14.0k
      case '"':
700
3.69k
        switch (status)
701
3.69k
        {
702
906
          case START_TO:
703
906
            to_b->body.s = tmp;
704
906
            to_b->display.s = tmp;
705
906
            status = DISPLAY_QUOTED;
706
906
            break;
707
692
          case DISPLAY_QUOTED:
708
692
            status = E_DISPLAY_QUOTED;
709
692
            to_b->display.len = tmp-to_b->display.s+1;
710
692
            break;
711
452
          case F_CRLF:
712
1.53k
          case F_LF:
713
2.01k
          case F_CR:
714
            /*previous=crlf and now !=' '*/
715
2.01k
            goto endofheader;
716
81
          default:
717
81
            goto parse_error;
718
3.69k
        }
719
1.59k
        break;
720
77.5k
      case ';' :
721
77.5k
        switch (status)
722
77.5k
        {
723
480
          case DISPLAY_QUOTED:
724
1.23k
          case DISPLAY_TOKEN:
725
18.0k
          case URI_ENCLOSED:
726
18.0k
            break;
727
39.0k
          case URI_OR_TOKEN:
728
39.0k
            end_mark = tmp;
729
            /* fall through */
730
49.4k
          case MAYBE_URI_END:
731
49.4k
            to_b->uri.len = end_mark - to_b->uri.s;
732
            /* fall through */
733
55.8k
          case END:
734
55.8k
            to_b->body.len = tmp-to_b->body.s;
735
55.8k
            tmp = parse_to_param(tmp,end,to_b,&saved_status,multi);
736
55.8k
            if (to_b->error!=PARSE_ERROR && multi && *tmp==',') {
737
              /* continue with a new body instance */
738
3.10k
              to_b->next = (struct to_body*)
739
3.10k
                pkg_malloc(sizeof(struct to_body));
740
3.10k
              if (to_b->next==NULL) {
741
0
                LM_ERR("failed to allocate new TO body\n");
742
0
                goto error;
743
0
              }
744
3.10k
              to_b = to_b->next;
745
3.10k
              memset(to_b, 0, sizeof(struct to_body));
746
3.10k
              to_b->error=PARSE_OK;
747
3.10k
              saved_status = status = START_TO;
748
3.10k
              end_mark=0;
749
3.10k
              break;
750
52.7k
            } else {
751
52.7k
              goto endofheader;
752
52.7k
            }
753
713
          case F_CRLF:
754
2.73k
          case F_LF:
755
3.52k
          case F_CR:
756
            /*previous=crlf and now !=' '*/
757
3.52k
            goto endofheader;
758
59
          default:
759
59
            goto parse_error;
760
77.5k
        }
761
21.1k
        break;
762
6.30M
      default:
763
6.30M
        switch (status)
764
6.30M
        {
765
5.58M
          case START_TO:
766
5.58M
            to_b->uri.s = to_b->body.s = tmp;
767
5.58M
            status = URI_OR_TOKEN;
768
5.58M
            to_b->display.s=tmp;
769
5.58M
            break;
770
13.9k
          case S_URI_ENCLOSED:
771
13.9k
            to_b->uri.s=tmp;
772
13.9k
            status=URI_ENCLOSED;
773
13.9k
            break;
774
2.21k
          case MAYBE_URI_END:
775
3.43k
          case DISPLAY_TOKEN2:
776
3.43k
            status = DISPLAY_TOKEN;
777
7.96k
          case DISPLAY_QUOTED:
778
25.5k
          case DISPLAY_TOKEN:
779
292k
          case URI_ENCLOSED:
780
683k
          case URI_OR_TOKEN:
781
683k
            break;
782
2.55k
          case F_CRLF:
783
13.9k
          case F_LF:
784
16.7k
          case F_CR:
785
            /*previous=crlf and now !=' '*/
786
16.7k
            goto endofheader;
787
123
          default:
788
123
            LM_DBG("spitting out [%c] in status %d\n",
789
123
            *tmp,status );
790
123
            goto error;
791
6.30M
        }
792
14.5M
    }/*char switch*/
793
14.5M
  }/*for*/
794
795
87.7k
endofheader:
796
87.7k
  if (to_b->display.len==0) to_b->display.s=0;
797
87.7k
  status=saved_status;
798
87.7k
  LM_DBG("end of header reached, state=%d\n", status);
799
  /* check if error*/
800
87.7k
  switch(status){
801
24.0k
    case MAYBE_URI_END:
802
24.0k
      to_b->uri.len = end_mark - to_b->uri.s;
803
33.9k
    case END:
804
33.9k
      to_b->body.len = tmp - to_b->body.s;
805
84.3k
    case E_PARA_VALUE:
806
84.3k
      break;
807
3.45k
    default:
808
3.45k
      LM_ERR("unexpected end of header in state %d\n", status);
809
3.45k
      goto error;
810
87.7k
  }
811
812
84.3k
  LM_DBG("display={%.*s}, ruri={%.*s}\n",
813
84.3k
    to_b->display.len, ZSW(to_b->display.s),
814
0
    to_b->uri.len, ZSW(to_b->uri.s));
815
84.3k
  return tmp;
816
817
1.40k
parse_error:
818
1.40k
  LM_ERR("unexpected char [%c] in status %d: <<%.*s>> .\n",
819
1.40k
      tmp < end? *tmp : *(end-1), status, (int)(tmp-buffer), buffer);
820
4.98k
error:
821
4.98k
  first_b->error=PARSE_ERROR;
822
4.98k
  free_to_params(first_b);
823
4.98k
  free_to(first_b->next);
824
4.98k
  return tmp;
825
826
1.40k
}
827
828
829
char* parse_to(char* buffer, char *end, struct to_body *to_b)
830
87.9k
{
831
87.9k
  return _parse_to( buffer, end, to_b, 0/*multi*/);
832
87.9k
}
833
834
835
char* parse_multi_to(char* buffer, char *end, struct to_body *to_b)
836
1.37k
{
837
1.37k
  return _parse_to( buffer, end, to_b, 1/*multi*/);
838
1.37k
}
839
840
841
/**
842
 *
843
 */
844
struct sip_uri *parse_to_uri(struct sip_msg *msg)
845
11.6k
{
846
11.6k
  struct to_body *tb = NULL;
847
11.6k
  if(msg==NULL || msg->to==NULL || msg->to->parsed==NULL)
848
0
    return NULL;
849
850
11.6k
  tb = get_to(msg);
851
852
11.6k
  if(tb->parsed_uri.user.s!=NULL || tb->parsed_uri.host.s!=NULL)
853
4.78k
    return &tb->parsed_uri;
854
855
6.86k
  if (parse_uri(tb->uri.s, tb->uri.len , &tb->parsed_uri)<0)
856
5.26k
  {
857
5.26k
    LM_ERR("failed to parse To uri\n");
858
5.26k
    memset(&tb->parsed_uri, 0, sizeof(struct sip_uri));
859
5.26k
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM, "error parsing To uri");
860
5.26k
    set_err_reply(400, "bad To uri");
861
5.26k
    return NULL;
862
5.26k
  }
863
864
1.59k
  return &tb->parsed_uri;
865
6.86k
}
866
867
int parse_to_header( struct sip_msg *msg)
868
0
{
869
0
  struct to_body* to_b;
870
871
0
  if ( !msg->to && ( parse_headers(msg,HDR_TO_F,0)==-1 || !msg->to)) {
872
0
    LM_ERR("bad msg or missing To header\n");
873
0
    goto error;
874
0
  }
875
876
  /* maybe the header is already parsed! */
877
0
  if (msg->to->parsed)
878
0
    return 0;
879
880
  /* bad luck! :-( - we have to parse it */
881
  /* first, get some memory */
882
0
  to_b = pkg_malloc(sizeof(struct to_body));
883
0
  if (to_b == 0) {
884
0
    LM_ERR("out of pkg_memory\n");
885
0
    goto error;
886
0
  }
887
888
  /* now parse it!! */
889
0
  memset(to_b, 0, sizeof(struct to_body));
890
0
  parse_to(msg->to->body.s,msg->to->body.s+msg->to->body.len+1,to_b);
891
0
  if (to_b->error == PARSE_ERROR) {
892
0
    LM_ERR("bad to header\n");
893
0
    pkg_free(to_b);
894
0
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
895
0
      "error parsing too header");
896
0
    set_err_reply(400, "bad header");
897
0
    goto error;
898
0
  }
899
900
0
  msg->to->parsed = to_b;
901
902
0
  return 0;
903
0
error:
904
0
  return -1;
905
0
}
906
907
/*
908
 * Checks if From includes a To-tag -- good to identify
909
 * if a request creates a new dialog
910
 */
911
int has_totag(struct sip_msg* _m)
912
0
{
913
0
  str tag;
914
915
0
  if (!_m->to && parse_headers(_m, HDR_TO_F,0)==-1) {
916
0
    LM_ERR("To parsing failed\n");
917
0
    return 0;
918
0
  }
919
0
  if (!_m->to) {
920
0
    LM_ERR("no To\n");
921
0
    return 0;
922
0
  }
923
0
  tag=get_to(_m)->tag_value;
924
0
  if (tag.s==0 || tag.len==0) {
925
0
    LM_DBG("no totag\n");
926
0
    return 0;
927
0
  }
928
0
  LM_DBG("totag found\n");
929
0
  return 1;
930
0
}
931
932
/*
933
 * Parses the URI from a generic to_body structure
934
 * Helper function (not specific to TO hdr)
935
 */
936
int parse_to_body_uri(struct to_body *to_b)
937
0
{
938
0
  if (to_b==NULL)
939
0
    return -1;
940
941
0
  if (parse_uri(to_b->uri.s, to_b->uri.len, &to_b->parsed_uri) < 0) {
942
0
    memset( &to_b->parsed_uri, 0, sizeof(struct sip_uri));
943
0
    return -1;
944
0
  }
945
0
  return 0;
946
0
}