Coverage Report

Created: 2025-10-12 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/strongswan/src/libstrongswan/utils/lexparser.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2001-2006 Andreas Steffen
3
 *
4
 * Copyright (C) secunet Security Networks AG
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 *
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 */
16
17
#include "lexparser.h"
18
19
/**
20
 * eat whitespace
21
 */
22
bool eat_whitespace(chunk_t *src)
23
27.8k
{
24
37.0k
  while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
25
9.18k
  {
26
9.18k
    src->ptr++;  src->len--;
27
9.18k
  }
28
27.8k
  return  src->len > 0 && *src->ptr != '#';
29
27.8k
}
30
31
/**
32
 * compare string with chunk
33
 */
34
bool match(const char *pattern, const chunk_t *ch)
35
54.6k
{
36
54.6k
  return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0;
37
54.6k
}
38
39
/**
40
 * compare string with chunk ignoring the case of the characters
41
 */
42
bool matchcase(const char *pattern, const chunk_t *ch)
43
0
{
44
0
  return ch->len == strlen(pattern) && strncasecmp(pattern, ch->ptr, ch->len) == 0;
45
0
}
46
47
/**
48
 * extracts a token ending with the first occurrence of a given termination symbol
49
 */
50
bool extract_token(chunk_t *token, const char termination, chunk_t *src)
51
363k
{
52
363k
  u_char *eot = memchr(src->ptr, termination, src->len);
53
54
363k
  if (termination == ' ')
55
93.5k
  {
56
93.5k
    u_char *eot_tab = memchr(src->ptr, '\t', src->len);
57
58
    /* check if a tab instead of a space terminates the token */
59
93.5k
    eot = ( eot_tab == NULL || (eot && eot < eot_tab) ) ? eot : eot_tab;
60
93.5k
  }
61
62
  /* initialize empty token */
63
363k
  *token = chunk_empty;
64
65
363k
  if (eot == NULL) /* termination symbol not found */
66
90.9k
  {
67
90.9k
    return FALSE;
68
90.9k
  }
69
70
  /* extract token */
71
272k
  token->ptr = src->ptr;
72
272k
  token->len = (u_int)(eot - src->ptr);
73
74
  /* advance src pointer after termination symbol */
75
272k
  src->ptr = eot + 1;
76
272k
  src->len -= (token->len + 1);
77
78
272k
  return TRUE;
79
363k
}
80
81
/**
82
 * extracts a token ending with the first occurrence of a given null-terminated string
83
 */
84
bool extract_token_str(chunk_t *token, const char *termination, chunk_t *src)
85
0
{
86
0
  u_char *eot = memstr(src->ptr, termination, src->len);
87
0
  size_t l = strlen(termination);
88
89
  /* initialize empty token */
90
0
  *token = chunk_empty;
91
92
0
  if (eot == NULL) /* termination string not found */
93
0
  {
94
0
    return FALSE;
95
0
  }
96
97
  /* extract token */
98
0
  token->ptr = src->ptr;
99
0
  token->len = (u_int)(eot - src->ptr);
100
101
  /* advance src pointer after termination string */
102
0
  src->ptr = eot + l;
103
0
  src->len -= (token->len + l);
104
105
0
  return TRUE;
106
0
}
107
108
/**
109
 *  fetches a new line terminated by \n or \r\n
110
 */
111
bool fetchline(chunk_t *src, chunk_t *line)
112
227k
{
113
227k
  if (src->len == 0) /* end of src reached */
114
1.26k
    return FALSE;
115
116
225k
  if (extract_token(line, '\n', src))
117
224k
  {
118
224k
    if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
119
1.17k
      line->len--;  /* remove optional \r */
120
224k
  }
121
1.31k
  else /*last line ends without newline */
122
1.31k
  {
123
1.31k
    *line = *src;
124
1.31k
    src->ptr += src->len;
125
1.31k
    src->len = 0;
126
1.31k
  }
127
225k
  return TRUE;
128
227k
}
129
130
err_t extract_value(chunk_t *value, chunk_t *line)
131
25.1k
{
132
25.1k
  char delimiter = ' ';
133
134
25.1k
  if (!eat_whitespace(line))
135
11.3k
  {
136
11.3k
    *value = chunk_empty;
137
11.3k
    return NULL;
138
11.3k
  }
139
13.7k
  if (*line->ptr == '\'' || *line->ptr == '"')
140
2.08k
  {
141
2.08k
    delimiter = *line->ptr;
142
2.08k
    line->ptr++;  line->len--;
143
2.08k
  }
144
13.7k
  if (!extract_token(value, delimiter, line))
145
10.5k
  {
146
10.5k
    if (delimiter == ' ')
147
8.53k
    {
148
8.53k
      *value = *line;
149
8.53k
      line->len = 0;
150
8.53k
    }
151
2.04k
    else
152
2.04k
    {
153
2.04k
      return "missing second delimiter";
154
2.04k
    }
155
10.5k
  }
156
11.7k
  return NULL;
157
13.7k
}
158
159
/**
160
 * extracts a parameter: value pair
161
 */
162
err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line)
163
38.9k
{
164
  /* extract name */
165
38.9k
  if (!extract_token(name,':', line))
166
13.8k
  {
167
13.8k
    return "missing ':'";
168
13.8k
  }
169
170
  /* extract value */
171
25.1k
  return extract_value(value, line);
172
38.9k
}