Coverage Report

Created: 2025-07-09 06:29

/src/opensips/parser/parse_content.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
 * 2003-08-04 parse_content_type_hdr separates type from subtype inside
22
 * the mime type (bogdan)
23
 * 2003-08-04 CPL subtype added (bogdan)
24
 * 2003-08-05 parse_accept_hdr function added (bogdan)
25
 * 2011-06-22 ISUP subtype added (roger)
26
 */
27
28
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <sys/types.h>
32
#include <unistd.h>
33
#include "../mem/mem.h"
34
#include "../dprint.h"
35
#include "../str.h"
36
#include "../ut.h"
37
#include "../errinfo.h"
38
#include "parse_content.h"
39
40
41
#define is_mime_char(_c_) \
42
8.70k
  (isalnum((int)_c_) || (_c_)=='-' || (_c_)=='+' || (_c_)=='.')
43
#define is_char_equal(_c_,_cs_) \
44
6.19k
  ( (isalpha((int)_c_)?(((_c_)|0x20)==(_cs_)):((_c_)==(_cs_)))==1 )
45
46
47
/*
48
 * Node of the type's tree; this tree contains all the known types;
49
 */
50
typedef struct type_node_s {
51
  char c;                      /* char contained by this node */
52
  unsigned char final;         /* says what mime type/subtype was detected
53
                                * if string ends at this node */
54
  unsigned char nr_sons;       /* the number of sub-nodes */
55
  int next;                    /* the next sibling node */
56
}type_node_t;
57
58
59
static type_node_t type_tree[] = {
60
  {'t',TYPE_UNKNOWN,1,4}, /* 0 */
61
    {'e',TYPE_UNKNOWN,1,-1},
62
      {'x',TYPE_UNKNOWN,1,-1},
63
        {'t',TYPE_TEXT,0,-1},
64
  {'m',TYPE_UNKNOWN,2,19}, /* 4 */
65
    {'e',TYPE_UNKNOWN,1,11}, /* 5 */
66
      {'s',TYPE_UNKNOWN,1,-1},
67
        {'s',TYPE_UNKNOWN,1,-1},
68
          {'a',TYPE_UNKNOWN,1,-1},
69
            {'g',TYPE_UNKNOWN,1,-1},
70
              {'e',TYPE_MESSAGE,0,-1},
71
    {'u',TYPE_UNKNOWN,1,-1}, /* 11 */
72
      {'l',TYPE_UNKNOWN,1,-1},
73
        {'t',TYPE_UNKNOWN,1,-1},
74
          {'i',TYPE_UNKNOWN,1,-1},
75
            {'p',TYPE_UNKNOWN,1,-1},
76
              {'a',TYPE_UNKNOWN,1,-1},
77
                {'r',TYPE_UNKNOWN,1,-1},
78
                  {'t',TYPE_MULTIPART,0,-1},
79
  {'a',TYPE_UNKNOWN,1,-1}, /* 19 */
80
    {'p',TYPE_UNKNOWN,1,-1},
81
      {'p',TYPE_UNKNOWN,1,-1},
82
        {'l',TYPE_UNKNOWN,1,-1},
83
          {'i',TYPE_UNKNOWN,1,-1},
84
            {'c',TYPE_UNKNOWN,1,-1},
85
              {'a',TYPE_UNKNOWN,1,-1},
86
                {'t',TYPE_UNKNOWN,1,-1},
87
                  {'i',TYPE_UNKNOWN,1,-1},
88
                    {'o',TYPE_UNKNOWN,1,-1},
89
                      {'n',TYPE_APPLICATION,0,-1},
90
  };
91
92
93
static type_node_t subtype_tree[] = {
94
        {'p',SUBTYPE_UNKNOWN,2,12},  /* 0 */
95
    {'l',SUBTYPE_UNKNOWN,1,5},
96
      {'a',SUBTYPE_UNKNOWN,1,-1},
97
        {'i',SUBTYPE_UNKNOWN,1,-1},
98
          {'n',SUBTYPE_PLAIN,0,-1},
99
    {'i',SUBTYPE_UNKNOWN,1,-1}, /* 5 */
100
      {'d',SUBTYPE_UNKNOWN,1,-1},
101
        {'f',SUBTYPE_UNKNOWN,1,-1},
102
          {'+',SUBTYPE_UNKNOWN,1,-1},
103
            {'x',SUBTYPE_UNKNOWN,1,-1},
104
              {'m',SUBTYPE_UNKNOWN,1,-1},
105
                {'l',SUBTYPE_PIDFXML,0,-1},
106
  {'s',SUBTYPE_UNKNOWN,2,36}, /* 12 */
107
    {'d',SUBTYPE_UNKNOWN,1,15},
108
      {'p',SUBTYPE_SDP,0,-1},
109
          {'i',SUBTYPE_UNKNOWN,1,-1},  /* 15 */
110
                  {'m',SUBTYPE_UNKNOWN,1,-1},
111
                      {'p',SUBTYPE_UNKNOWN,1,-1},
112
                          {'l',SUBTYPE_UNKNOWN,1,-1},
113
                              {'e',SUBTYPE_UNKNOWN,1,-1},
114
                                  {'-',SUBTYPE_UNKNOWN,1,-1},
115
                                      {'m',SUBTYPE_UNKNOWN,1,-1},
116
                                          {'e',SUBTYPE_UNKNOWN,1,-1},
117
                                              {'s',SUBTYPE_UNKNOWN,1,-1},
118
                                                  {'s',SUBTYPE_UNKNOWN,1,-1},
119
                                                      {'a',SUBTYPE_UNKNOWN,1,-1},
120
                                                          {'g',SUBTYPE_UNKNOWN,1,-1},
121
                                                              {'e',SUBTYPE_UNKNOWN,1,-1},
122
                                                                  {'-',SUBTYPE_UNKNOWN,1,-1},
123
                                                                      {'s',SUBTYPE_UNKNOWN,1,-1},
124
                                                                          {'u',SUBTYPE_UNKNOWN,1,-1},
125
                                                                              {'m',SUBTYPE_UNKNOWN,1,-1},
126
                                                                                  {'m',SUBTYPE_UNKNOWN,1,-1},
127
                                                                                      {'a',SUBTYPE_UNKNOWN,1,-1},
128
                                                                                          {'r',SUBTYPE_UNKNOWN,1,-1},
129
                                                                                              {'y',SUBTYPE_SMS,0,-1},
130
  {'c',SUBTYPE_UNKNOWN,1,45}, /* 36 */
131
    {'p',SUBTYPE_UNKNOWN,2,-1},
132
      {'i',SUBTYPE_UNKNOWN,1,40},
133
        {'m',SUBTYPE_CPIM,0,-1},
134
                  {'l',SUBTYPE_UNKNOWN,1,-1}, /* 40 */
135
        {'+',SUBTYPE_UNKNOWN,1,-1},
136
          {'x',SUBTYPE_UNKNOWN,1,-1},
137
            {'m',SUBTYPE_UNKNOWN,1,-1},
138
              {'l',SUBTYPE_CPLXML,0,-1},
139
  {'r',SUBTYPE_UNKNOWN,2,59}, /* 45 */
140
    {'l',SUBTYPE_UNKNOWN,1,53},
141
      {'m',SUBTYPE_UNKNOWN,1,-1},
142
        {'i',SUBTYPE_UNKNOWN,1,-1},
143
          {'+',SUBTYPE_UNKNOWN,1,-1},
144
            {'x',SUBTYPE_UNKNOWN,1,-1},
145
              {'m',SUBTYPE_UNKNOWN,1,-1},
146
                {'l',SUBTYPE_RLMIXML,0,-1},
147
    {'e',SUBTYPE_UNKNOWN,1,-1}, /* 53 */
148
      {'l',SUBTYPE_UNKNOWN,1,-1},
149
        {'a',SUBTYPE_UNKNOWN,1,-1},
150
          {'t',SUBTYPE_UNKNOWN,1,-1},
151
            {'e',SUBTYPE_UNKNOWN,1,-1},
152
              {'d',SUBTYPE_RELATED,0,-1},
153
  {'l',SUBTYPE_UNKNOWN,1,68}, /* 59 */
154
    {'p',SUBTYPE_UNKNOWN,1,-1},
155
      {'i',SUBTYPE_UNKNOWN,1,-1},
156
        {'d',SUBTYPE_UNKNOWN,1,-1},
157
          {'f',SUBTYPE_UNKNOWN,1,-1},
158
            {'+',SUBTYPE_UNKNOWN,1,-1},
159
              {'x',SUBTYPE_UNKNOWN,1,-1},
160
                {'m',SUBTYPE_UNKNOWN,1,-1},
161
                  {'l',SUBTYPE_LPIDFXML,0,-1},
162
  {'w',SUBTYPE_UNKNOWN,1,83}, /* 68 */
163
    {'a',SUBTYPE_UNKNOWN,1,-1},
164
      {'t',SUBTYPE_UNKNOWN,1,-1},
165
        {'c',SUBTYPE_UNKNOWN,1,-1},
166
          {'h',SUBTYPE_UNKNOWN,1,-1},
167
            {'e',SUBTYPE_UNKNOWN,1,-1},
168
              {'r',SUBTYPE_UNKNOWN,1,-1},
169
                {'i',SUBTYPE_UNKNOWN,1,-1},
170
                  {'n',SUBTYPE_UNKNOWN,1,-1},
171
                    {'f',SUBTYPE_UNKNOWN,1,-1},
172
                      {'o',SUBTYPE_UNKNOWN,1,-1},
173
                        {'+',SUBTYPE_UNKNOWN,1,-1},
174
                          {'x',SUBTYPE_UNKNOWN,1,-1},
175
                            {'m',SUBTYPE_UNKNOWN,1,-1},
176
                              {'l',SUBTYPE_WATCHERINFOXML,0,-1},
177
  {'x',SUBTYPE_UNKNOWN,2,105}, /* 83 */
178
    {'p',SUBTYPE_UNKNOWN,1,92},
179
      {'i',SUBTYPE_UNKNOWN,1,-1},
180
        {'d',SUBTYPE_UNKNOWN,1,-1},
181
          {'f',SUBTYPE_UNKNOWN,1,-1},
182
            {'+',SUBTYPE_UNKNOWN,1,-1},
183
              {'x',SUBTYPE_UNKNOWN,1,-1},
184
                {'m',SUBTYPE_UNKNOWN,1,-1},
185
                  {'l',SUBTYPE_XPIDFXML,0,-1},
186
    {'m',SUBTYPE_UNKNOWN,1,-1}, /* 92 */
187
      {'l',SUBTYPE_UNKNOWN,1,-1},
188
        {'+',SUBTYPE_UNKNOWN,1,-1},
189
          {'m',SUBTYPE_UNKNOWN,1,-1},
190
            {'s',SUBTYPE_UNKNOWN,1,-1},
191
              {'r',SUBTYPE_UNKNOWN,1,-1},
192
                {'t',SUBTYPE_UNKNOWN,1,-1},
193
                  {'c',SUBTYPE_UNKNOWN,1,-1},
194
                    {'.',SUBTYPE_UNKNOWN,1,-1},
195
                      {'p',SUBTYPE_UNKNOWN,1,-1},
196
                        {'i',SUBTYPE_UNKNOWN,1,-1},
197
                          {'d',SUBTYPE_UNKNOWN,1,-1},
198
                            {'f',SUBTYPE_XML_MSRTC_PIDF,0,-1},
199
  {'e',SUBTYPE_UNKNOWN,1,118}, /* 105 */
200
    {'x',SUBTYPE_UNKNOWN,1,-1},
201
      {'t',SUBTYPE_UNKNOWN,1,-1},
202
        {'e',SUBTYPE_UNKNOWN,1,-1},
203
          {'r',SUBTYPE_UNKNOWN,1,-1},
204
            {'n',SUBTYPE_UNKNOWN,1,-1},
205
              {'a',SUBTYPE_UNKNOWN,1,-1},
206
                {'l',SUBTYPE_UNKNOWN,1,-1},
207
                  {'-',SUBTYPE_UNKNOWN,1,-1},
208
                    {'b',SUBTYPE_UNKNOWN,1,-1},
209
                      {'o',SUBTYPE_UNKNOWN,1,-1},
210
                        {'d',SUBTYPE_UNKNOWN,1,-1},
211
                          {'y',SUBTYPE_EXTERNAL_BODY,0,-1},
212
  {'m',SUBTYPE_UNKNOWN,1,123}, /* 118 */
213
           {'i',SUBTYPE_UNKNOWN,1,-1},
214
      {'x',SUBTYPE_UNKNOWN,1,-1},
215
        {'e',SUBTYPE_UNKNOWN,1,-1},
216
          {'d',SUBTYPE_MIXED,0,-1},
217
  {'i',SUBTYPE_UNKNOWN,1,-1}, /* 123 */
218
    {'s',SUBTYPE_UNKNOWN,1,-1},
219
      {'u',SUBTYPE_UNKNOWN,1,-1},
220
        {'p',SUBTYPE_ISUP,0,-1},
221
222
        };
223
char str_contenttype[50];
224
225
226
227
char* parse_content_length( char* buffer, char* end, int* length)
228
7.52k
{
229
7.52k
  int number;
230
7.52k
  char *p, *numstart;
231
232
7.52k
  p = buffer;
233
  /* search the beginning of the number */
234
7.53k
  while ( p<end && (*p==' ' || *p=='\t'
235
7.53k
                || (*p=='\r' && p+1<end && *(p+1)=='\n')
236
7.53k
                || (*p=='\n' && p+1<end && (*(p+1)==' '||*(p+1)=='\t')) ))
237
5
    p++;
238
7.52k
  if (p==end)
239
0
    goto error;
240
  /* parse the number */
241
7.52k
  numstart = p;
242
7.52k
  number = 0;
243
17.1k
  while (p<end && *p>='0' && *p<='9') {
244
    /* do not actually cause an integer overflow, as it is UB! --liviu */
245
9.63k
    if (number >= INT_MAX/10) {
246
5
      LM_ERR("integer overflow risk at pos %d in length value [%.*s]\n",
247
5
        (int)(p-buffer),(int)(end-buffer), buffer);
248
5
      return NULL;
249
5
    }
250
251
9.63k
    number = number*10 + ((*p)-'0');
252
9.63k
    p++;
253
9.63k
  }
254
7.52k
  if (p==end || p==numstart)
255
82
    goto error;
256
257
  /* now we should have only spaces at the end */
258
11.9k
  while ( p<end && (*p==' ' || *p=='\t'
259
11.9k
                || (*p=='\n' && p+1<end && (*(p+1)==' '||*(p+1)=='\t')) ))
260
4.53k
    p++;
261
7.44k
  if (p==end)
262
27
    goto error;
263
  /* the header ends proper? */
264
7.41k
  if ( (*(p++)!='\n') && (*(p-1)!='\r' || p==end || *(p++)!='\n' ) )
265
44
    goto error;
266
267
7.37k
  *length = number;
268
7.37k
  return p;
269
153
error:
270
153
  LM_ERR("parse error at pos %ld, dec-char: %d, start/p/end: %p/%p/%p\n",
271
153
         (long)(p - buffer), p < end && (end-buffer) ? *p:-1, buffer, p, end);
272
153
  return NULL;
273
7.41k
}
274
275
276
277
char* decode_mime_type(char *start, char *end, unsigned int *mime_type, content_t * con)
278
670
{
279
670
  int node;
280
670
  char *mark;
281
670
  char *p;
282
283
670
  p = start;
284
285
670
  LM_DBG("Decoding MIME type for:[%.*s]\n",(int)(end-start),start);
286
287
  /* search the beginning of the type */
288
670
  while ( p<end && (*p==' ' || *p=='\t' || (*p=='\r' && *(p+1)=='\n') ||
289
666
  (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
290
0
    p++;
291
670
  if (p==end)
292
4
    goto error;
293
294
  /* parse the type */
295
666
  if (*p=='*') {
296
32
    *mime_type = TYPE_ALL<<16;
297
32
    p++;
298
634
  } else {
299
634
    node = 0;
300
634
    mark = p;
301
3.26k
    while (p<end && is_mime_char(*p)  ) {
302
4.37k
      while ( node!=-1 && !is_char_equal(*p,type_tree[node].c) ){
303
1.74k
        node = type_tree[node].next;
304
1.74k
      }
305
2.62k
      if (node!=-1 && type_tree[node].nr_sons)
306
408
        node++;
307
2.62k
      p++;
308
2.62k
    }
309
634
    if (p==end || mark==p)
310
48
      goto error;
311
586
    if (node!=-1)
312
68
      *mime_type = type_tree[node].final<<16;
313
518
    else
314
518
      *mime_type = TYPE_UNKNOWN<<16;
315
586
  }
316
317
  /* search the '/' separator */
318
1.95k
  while ( p<end && (*p==' ' || *p=='\t' ||
319
1.92k
  (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
320
1.33k
    p++;
321
618
  if ( p==end || *(p++)!='/')
322
124
    goto error;
323
324
  /* search the beginning of the sub-type */
325
1.78k
  while ( p<end && (*p==' ' || *p=='\t' ||
326
1.75k
  (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
327
1.29k
    p++;
328
494
  if (p==end)
329
32
    goto error;
330
331
  /* parse the sub-type */
332
462
  if (*p=='*') {
333
12
    *mime_type |= SUBTYPE_ALL;
334
12
    p++;
335
450
  } else {
336
450
    node = 0;
337
450
    mark = p;
338
2.78k
    while (p<end && (is_mime_char(*p) || *p == '_')) {
339
5.63k
      while(node!=-1 && !is_char_equal(*p,subtype_tree[node].c) )
340
3.30k
        node = subtype_tree[node].next;
341
2.33k
      if (node!=-1 && subtype_tree[node].nr_sons)
342
184
        node++;
343
2.33k
      p++;
344
2.33k
    }
345
450
    if (p==mark)
346
34
      goto error;
347
416
    if (node!=-1)
348
62
      *mime_type |= subtype_tree[node].final;
349
354
    else
350
354
      *mime_type |= SUBTYPE_UNKNOWN;
351
416
  }
352
353
  /* now its possible to have some spaces */
354
1.76k
  while ( p<end && (*p==' ' || *p=='\t' ||
355
1.70k
  (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
356
1.33k
    p++;
357
358
  /* if there are params, ignore them!! -> eat everything to
359
   * the end or to the first ',' */
360
428
  if ( p<end && *p==';' )
361
226
  {
362
226
    if( con == NULL)
363
0
      for(p++; p<end && *p!=','; p++);
364
226
    else
365
226
    {
366
226
      str params_str;
367
226
      param_hooks_t phooks;
368
226
      param_t * cur;
369
370
226
      params_str.s = p;
371
226
      params_str.len = end - p ;
372
373
226
      if (parse_params(&params_str, CLASS_ANY, &phooks, &con->params) < 0)
374
60
        goto error;
375
376
166
      p = params_str.s;
377
378
166
      cur = con->params;
379
380
3.33k
      while(cur)
381
3.17k
      {
382
3.17k
        if( cur->name.len == 8 && !strncasecmp(cur->name.s,"boundary",cur->name.len ) )
383
230
          con->boundary = cur->body;
384
385
3.17k
        if( cur->name.len == 5 && !strncasecmp(cur->name.s,"start",cur->name.len ) )
386
208
          con->start = cur->body;
387
388
3.17k
        cur = cur ->next;
389
3.17k
      }
390
391
166
    }
392
226
  }
393
394
  /* is this the correct end? */
395
368
  if (p!=end && *p!=',' )
396
138
    goto error;
397
398
  /* check the format of the decoded mime */
399
230
  if ((*mime_type)>>16==TYPE_ALL && ((*mime_type)&0x00ff)!=SUBTYPE_ALL) {
400
16
    LM_ERR("invalid mime format found "
401
16
      " <*/submime> in [%.*s]!!\n", (int)(end-start),start);
402
16
    return 0;
403
16
  }
404
405
214
  return p;
406
440
error:
407
440
  LM_ERR("parse error near in [%.*s] char"
408
440
    "[%d][%c] offset=%d\n", (int)(end-start),start,*p,*p,(int)(p-start));
409
440
  return 0;
410
230
}
411
412
413
414
/* returns: > 0 mime found
415
 *          = 0 hdr not found
416
 *          =-1 error */
417
int parse_content_type_hdr( struct sip_msg *msg )
418
718
{
419
718
  char *end;
420
718
  char *ret;
421
718
  unsigned int  mime;
422
718
  content_t * rez;
423
424
  /* is the header already found? */
425
718
  if ( msg->content_type==0 ) {
426
    /* if not, found it */
427
48
    if ( parse_headers(msg, HDR_CONTENTTYPE_F, 0)==-1)
428
0
      goto error;
429
48
    if ( msg->content_type==0 ) {
430
48
      LM_DBG("missing Content-Type header\n");
431
48
      return 0;
432
48
    }
433
48
  }
434
435
  /* maybe the header is already parsed! */
436
670
  if ( msg->content_type->parsed!=0)
437
0
    return get_content_type(msg);
438
439
670
  rez = (content_t*) pkg_malloc(sizeof (content_t));
440
670
  if (rez == NULL)
441
0
  {
442
0
    LM_ERR("Unable to allocate memory\n");
443
0
    goto error;
444
0
  }
445
670
  memset(rez, 0, sizeof (content_t));
446
447
  /* it seams we have to parse it! :-( */
448
670
  end = msg->content_type->body.s + msg->content_type->body.len;
449
670
  ret = decode_mime_type(msg->content_type->body.s, end , &mime, rez);
450
670
  if (ret==0)
451
456
    goto parse_error;
452
214
  if (ret!=end) {
453
110
    LM_ERR("the header CONTENT_TYPE contains "
454
110
      "more then one mime type :-(!\n");
455
110
    goto parse_error;
456
110
  }
457
104
  if ((mime&0x00ff)==SUBTYPE_ALL || (mime>>16)==TYPE_ALL) {
458
10
    LM_ERR("invalid mime with wildcard '*' in Content-Type hdr!\n");
459
10
    goto parse_error;
460
10
  }
461
462
463
94
  rez->type = mime;
464
94
  msg->content_type->parsed = rez;
465
94
  return mime;
466
467
576
parse_error:
468
576
  pkg_free(rez);
469
576
  set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
470
576
    "error parsing CT-TYPE header");
471
576
  set_err_reply(400, "bad headers");
472
473
576
error:
474
576
  return -1;
475
576
}
476
477
478
479
/* returns: > 0 ok
480
 *          = 0 hdr not found
481
 *          = -1 error */
482
int parse_accept_hdr( struct sip_msg *msg )
483
0
{
484
0
  static unsigned int mimes[MAX_MIMES_NR];
485
0
  int nr_mimes;
486
0
  unsigned int mime;
487
0
  char *end;
488
0
  char *ret;
489
490
  /* is the header already found? */
491
0
  if ( msg->accept==0 ) {
492
    /* if not, found it */
493
0
    if ( parse_headers(msg, HDR_ACCEPT_F, 0)==-1)
494
0
      goto error;
495
0
    if ( msg->accept==0 ) {
496
0
      LM_DBG("missing Accept header\n");
497
0
      return 0;
498
0
    }
499
0
  }
500
501
  /* maybe the header is already parsed! */
502
0
  if ( msg->accept->parsed!=0)
503
0
    return 1;
504
505
  /* it seams we have to parse it! :-( */
506
0
  ret = msg->accept->body.s;
507
0
  end = ret + msg->accept->body.len;
508
0
  nr_mimes = 0;
509
0
  while (1){
510
0
    ret = decode_mime_type(ret, end , &mime, NULL);
511
0
    if (ret==0)
512
0
      goto parse_error;
513
    /* a new mime was found  -> put it into array */
514
0
    if (nr_mimes==MAX_MIMES_NR) {
515
0
      LM_ERR("accept hdr contains more than"
516
0
        " %d mime type -> buffer overflow!!\n",MAX_MIMES_NR);
517
0
      goto error;
518
0
    }
519
0
    mimes[nr_mimes++] = mime;
520
    /* is another mime following? */
521
0
    if (ret==end )
522
0
      break;
523
    /* parse the mime separator ',' */
524
0
    if (*ret!=',' || ret+1==end) {
525
0
      LM_ERR("parse error between mimes at "
526
0
        "char <%x> (offset=%d) in <%.*s>!\n",
527
0
        *ret, (int)(ret-msg->accept->body.s),
528
0
        msg->accept->body.len, msg->accept->body.s);
529
0
      goto parse_error;
530
0
    }
531
    /* skip the ',' */
532
0
    ret++;
533
0
  }
534
535
  /* copy and link the mime buffer into the message */
536
0
  msg->accept->parsed = (void*)pkg_malloc((nr_mimes+1)*sizeof(int));
537
0
  if (msg->accept->parsed==0) {
538
0
    LM_ERR("no more pkg memory\n");
539
0
    goto error;
540
0
  }
541
0
  memcpy(msg->accept->parsed,mimes,nr_mimes*sizeof(int));
542
  /* make the buffer null terminated */
543
0
  ((int*)msg->accept->parsed)[nr_mimes] = 0;
544
545
0
  return 1;
546
547
0
parse_error:
548
0
  set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
549
0
    "error parsing ACCEPT header");
550
0
  set_err_reply(400, "bad headers");
551
0
error:
552
0
  return -1;
553
0
}
554
555
void free_contenttype(content_t ** con)
556
94
{
557
558
94
  if (*con)
559
94
  {
560
94
    if((*con)->params)
561
44
      free_params((*con)->params);
562
94
    pkg_free(*con);
563
94
  }
564
94
  *con = 0;
565
94
}
566
567
char* convert_mime2string_CT(int contenttype)
568
0
{
569
0
  #define SET_TYPE_PTRS(_type_) \
570
0
    do { \
571
0
      subtype_start = type_start + sizeof(_type_) - 1; \
572
0
      memcpy(type_start, _type_, sizeof(_type_) - 1); \
573
0
    } while(0);
574
575
0
  #define SET_SUBTYPE_PTR(_subtype_) memcpy(subtype_start, _subtype_, sizeof(_subtype_))
576
577
  /* last 16 bits */
578
0
  int type = contenttype >> 16;
579
  /* only first 16 bits */
580
0
  int subtype = contenttype & (0xFF);
581
0
  char* type_start;
582
0
  char* subtype_start;
583
584
0
  memset(str_contenttype, 0 , sizeof(str_contenttype));
585
0
  type_start = str_contenttype;
586
587
0
  switch (type) {
588
0
    case TYPE_TEXT:
589
0
      SET_TYPE_PTRS("text/");
590
0
      break;
591
0
    case TYPE_MESSAGE:
592
0
      SET_TYPE_PTRS("message/");
593
0
      break;
594
0
    case TYPE_APPLICATION:
595
0
      SET_TYPE_PTRS("application/");
596
0
      break;
597
0
    case TYPE_MULTIPART:
598
0
      SET_TYPE_PTRS("multipart/");
599
0
      break;
600
0
    case TYPE_ALL:
601
0
      SET_TYPE_PTRS("*/");
602
0
      break;
603
0
    case TYPE_UNKNOWN:
604
0
      SET_TYPE_PTRS("unknown/");
605
0
      break;
606
0
    default:
607
0
      LM_ERR("invalid type\n");
608
0
      return 0;
609
0
  }
610
611
0
  switch (subtype) {
612
0
    case SUBTYPE_PLAIN:
613
0
      SET_SUBTYPE_PTR("plain");
614
0
      break;
615
0
    case SUBTYPE_CPIM:
616
0
      SET_SUBTYPE_PTR("cpim");
617
0
      break;
618
0
    case SUBTYPE_SDP:
619
0
      SET_SUBTYPE_PTR("sdp");
620
0
      break;
621
0
    case SUBTYPE_CPLXML:
622
0
      SET_SUBTYPE_PTR("cplxml");
623
0
      break;
624
0
    case SUBTYPE_PIDFXML:
625
0
      SET_SUBTYPE_PTR("pidfxml");
626
0
      break;
627
0
    case SUBTYPE_RLMIXML:
628
0
      SET_SUBTYPE_PTR("rlmixml");
629
0
      break;
630
0
    case SUBTYPE_RELATED:
631
0
      SET_SUBTYPE_PTR("related");
632
0
      break;
633
0
    case SUBTYPE_LPIDFXML:
634
0
      SET_SUBTYPE_PTR("lpidfxml");
635
0
      break;
636
0
    case SUBTYPE_XPIDFXML:
637
0
      SET_SUBTYPE_PTR("xpidfxml");
638
0
      break;
639
0
    case SUBTYPE_WATCHERINFOXML:
640
0
      SET_SUBTYPE_PTR("watcherinfoxml");
641
0
      break;
642
0
    case SUBTYPE_EXTERNAL_BODY:
643
0
      SET_SUBTYPE_PTR("external_body");
644
0
      break;
645
0
    case SUBTYPE_XML_MSRTC_PIDF:
646
0
      SET_SUBTYPE_PTR("xmlmsrtcpidf");
647
0
      break;
648
0
    case SUBTYPE_SMS:
649
0
      SET_SUBTYPE_PTR("sms");
650
0
      break;
651
0
    case SUBTYPE_MIXED:
652
0
      SET_SUBTYPE_PTR("mixed");
653
0
      break;
654
0
    case SUBTYPE_ISUP:
655
0
      SET_SUBTYPE_PTR("isup");
656
0
      break;
657
0
    case SUBTYPE_ALL:
658
0
      SET_SUBTYPE_PTR("*");
659
0
      break;
660
0
    case SUBTYPE_UNKNOWN:
661
0
      SET_SUBTYPE_PTR("unknown");
662
0
      break;
663
0
    default:
664
0
      LM_ERR("invalid subtype\n");
665
0
      return 0;
666
0
  }
667
668
0
  return str_contenttype;
669
670
0
#undef SET_TYPE_PTRS
671
0
#undef SET_SUBTYPE_PTR
672
0
}
673
674
675