Coverage Report

Created: 2025-08-26 06:38

/src/opensips/parser/parse_fcaps.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Feature-Caps header field body parser
3
 *
4
 * Copyright (c) 2020 OpenSIPS Solutions
5
 *
6
 * This file is part of opensips, a free SIP server.
7
 *
8
 * opensips is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version
12
 *
13
 * opensips is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#include "../mem/mem.h"
24
#include "../ut.h"
25
26
#include "parse_fcaps.h"
27
28
static str fcaps_pns = str_init("+sip.pns");
29
30
/* Feature-Caps: +sip.pns="apns";+sip.pnsreg="130" */
31
int parse_fcaps(struct hdr_field* _h)
32
0
{
33
0
  fcaps_body_t *b = NULL;
34
0
  int len = _h->body.len;
35
0
  char *s = _h->body.s, *end = s + len, *p;
36
37
0
  if (_h->parsed)
38
0
    return 0;
39
40
  /* optimized, simplistic parser.  Ideal for the PN proxy use case! */
41
0
  while (len > 0 && (p = q_memchr(s, '+', len))) {
42
0
    len -= p + 1 - s;
43
0
    s = p + 1;
44
45
0
    if (end - p >= (fcaps_pns.len + 4) &&
46
0
            !memcmp(p, fcaps_pns.s, fcaps_pns.len)) {
47
48
0
      p += fcaps_pns.len;
49
0
      len -= p - s;
50
0
      s = p;
51
52
      /* start LDQUOT */
53
0
      if (*p != '=' || *(p + 1) != '"')
54
0
        continue;
55
56
      /* end LDQUOT */
57
0
      p += 2;
58
0
      len -= 2;
59
0
      s = p;
60
61
0
      if (!(p = q_memchr(s + 1, '"', len - 1)))
62
0
        goto out;
63
64
      /* successfully matched a +sip.pns="..." string */
65
66
0
      if (!b) {
67
0
        b = pkg_malloc(sizeof *b);
68
0
        if (!b) {
69
0
          LM_ERR("oom\n");
70
0
          return -1;
71
0
        }
72
0
        memset(b, 0, sizeof *b);
73
0
      }
74
75
0
      b->pns.s = s;
76
0
      b->pns.len = p - s;
77
78
0
      p++;
79
0
      len -= p - s;
80
0
      s = p;
81
0
    }
82
0
  }
83
84
0
out:
85
0
  if (!b)
86
0
    return -1;
87
88
0
  _h->parsed = (void *)b;
89
0
  return 0;
90
0
}
91
92
void free_fcaps(fcaps_body_t** _fc)
93
0
{
94
0
  pkg_free(*_fc);
95
0
  *_fc = NULL;
96
0
}