Coverage Report

Created: 2023-01-19 06:30

/src/wpantund/src/util/string-utils.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2016 Nest Labs, Inc.
4
 * All rights reserved.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 *
18
 *    Description:
19
 *      This file defines utility functions for manipulating and comparing
20
 *      C-strings or other buffers.
21
 *
22
 */
23
24
#if HAVE_CONFIG_H
25
#include <config.h>
26
#endif
27
28
#include <stdio.h>
29
#include "string-utils.h"
30
#include <ctype.h>
31
#include <inttypes.h>
32
#include <stdlib.h>
33
34
#ifndef __USE_GNU
35
#define __USE_GNU // Needed for `strcasestr`
36
#endif
37
38
#include <string.h>
39
40
// Declare function to avoid compile warning: comparison between pointer and integer.
41
extern char *strcasestr(const char *, const char *);
42
43
void
44
memcpyrev(void *dest_, const void *src_, size_t len)
45
0
{
46
0
  uint8_t* const dest = dest_;
47
0
  const uint8_t* const src = src_;
48
0
  size_t i;
49
50
0
  for (i = 0; i < len; i++) {
51
0
    dest[i] = src[len - 1 - i];
52
0
  }
53
0
}
54
55
int
56
memcmprev(const void *dest_, const void *src_, size_t len)
57
0
{
58
0
  const uint8_t* const dest = dest_;
59
0
  const uint8_t* const src = src_;
60
0
  int ret = 0;
61
0
  size_t i;
62
63
0
  for (i = 0; i < len && !ret; i++) {
64
0
    ret = dest[i] - src[len - 1 - i];
65
0
  }
66
0
  return ret;
67
0
}
68
69
void
70
reverse_bytes(uint8_t *bytes, size_t count)
71
0
{
72
0
  size_t i;
73
74
0
  for (i = 0; i < count / 2; i++) {
75
0
    uint8_t x = bytes[i];
76
0
    bytes[i] = bytes[count - i - 1];
77
0
    bytes[count - i - 1] = x;
78
0
  }
79
0
}
80
81
int
82
parse_string_into_data(uint8_t* buffer, size_t len, const char* c_str)
83
736
{
84
736
  int ret = 0;
85
86
736
  if (NULL == buffer) {
87
0
    len = 0;
88
0
  }
89
90
14.6k
  while ((*c_str != 0) && (len > 0)) {
91
14.1k
    int c = tolower(*c_str++);
92
14.1k
    if (!(isdigit(c) || (c >= 'a' && c <= 'f'))) {
93
4.23k
      continue;
94
4.23k
    }
95
9.87k
    c = isdigit(c) ? (c - '0') : (c - 'a' + 10);
96
9.87k
    if (len > 0) {
97
9.87k
      *buffer = (c << 4);
98
9.87k
      len--;
99
9.87k
    }
100
9.87k
    ret++;
101
9.87k
    if (!*c_str) {
102
172
      break;
103
172
    }
104
9.69k
    c = tolower(*c_str++);
105
9.69k
    if (!(isdigit(c) || (c >= 'a' && c <= 'f'))) {
106
1.64k
      continue;
107
1.64k
    }
108
8.05k
    c = isdigit(c) ? (c - '0') : (c - 'a' + 10);
109
8.05k
    *buffer++ |= c;
110
8.05k
  }
111
112
736
  return ret;
113
736
}
114
115
int
116
encode_data_into_string(const uint8_t *buffer, size_t len, char *c_str, size_t c_str_max_len, int pad_to)
117
1.29k
{
118
1.29k
  int ret = 0;
119
120
7.25k
  while (len && (c_str_max_len > 2)) {
121
5.95k
    uint8_t byte = *buffer++;
122
5.95k
    len--;
123
5.95k
    pad_to--;
124
5.95k
    *c_str++ = int_to_hex_digit(byte >> 4);
125
5.95k
    *c_str++ = int_to_hex_digit(byte & 0xF);
126
5.95k
    c_str_max_len -= 2;
127
5.95k
    ret += 2;
128
5.95k
  }
129
130
1.29k
  while (pad_to > 0 && (c_str_max_len > 2)) {
131
0
    pad_to--;
132
0
    *c_str++ = '0';
133
0
    *c_str++ = '0';
134
0
    c_str_max_len -= 2;
135
0
    ret += 2;
136
0
  }
137
138
1.29k
  c_str_max_len--;
139
1.29k
  *c_str++ = 0;
140
1.29k
  return ret;
141
1.29k
}
142
143
bool
144
strtobool(const char* string)
145
0
{
146
0
  bool ret = false;
147
0
  switch(string[0]) {
148
0
  case 'y':
149
0
  case 'Y':
150
0
  case 't':
151
0
  case 'T':
152
0
    ret = true;
153
0
    break;
154
155
0
  case 'n':
156
0
  case 'N':
157
0
  case 'f':
158
0
  case 'F':
159
0
    ret = false;
160
0
    break;
161
162
0
  default:
163
0
    ret = (strtol(string, NULL, 0) != 0);
164
0
    break;
165
0
  }
166
0
  return ret;
167
0
}
168
169
uint32_t
170
strtomask_uint32(const char* in_string)
171
0
{
172
0
  char *tmp_string = strdup(in_string);
173
0
  char *chan_ranges;      // points to a channel num or a range of channels
174
0
  char *dash_location;    // points to location of the dash in a range of channels
175
0
  int channel_start = 0;
176
0
  int channel_stop = 0;
177
0
  uint32_t mask = 0;
178
179
0
  chan_ranges = strtok(tmp_string, ",");
180
0
  while(chan_ranges != NULL) {
181
    // loop to parse channels by comma (,)
182
    // each fragment may include a range (-) of channels
183
184
0
    dash_location = strchr(chan_ranges, '-');
185
0
    if (dash_location != NULL) {
186
      // process a range of channels
187
0
      *dash_location = '\0';
188
0
      dash_location++;
189
0
      if (atoi(chan_ranges) < atoi(dash_location)) {
190
0
        channel_start = atoi(chan_ranges);
191
0
        channel_stop = atoi(dash_location);
192
0
      } else {
193
0
        channel_stop = atoi(chan_ranges);
194
0
        channel_start = atoi(dash_location);
195
0
      }
196
197
0
      while (channel_start <= channel_stop) {
198
0
        mask |= (1 << channel_start);
199
0
        channel_start++;
200
0
      }
201
0
    } else {
202
      // no range, just add channel to the scan mask
203
204
0
      mask |= (1 << strtol(chan_ranges, NULL, 0));
205
0
    }
206
0
    chan_ranges = strtok(NULL, ",");
207
0
  }
208
0
  free(tmp_string);
209
0
  return mask;
210
0
}
211
212
#include <syslog.h>
213
214
int
215
strtologmask(const char* value, int prev_mask)
216
0
{
217
0
  int mask = (int)strtol(value, NULL, 0);
218
219
0
  if (mask == 0) {
220
0
    mask = prev_mask;
221
222
0
    if(strcasestr(value, "all") != NULL) {
223
0
      if (strcasestr(value, "-all") != NULL) {
224
0
        mask &= 0;
225
0
      } else {
226
0
        mask |= ~0;
227
0
      }
228
0
    }
229
0
    if (strcasestr(value, "emerg") != NULL) {
230
0
      if (strcasestr(value, "-emerg") != NULL) {
231
0
        mask &= ~LOG_MASK(LOG_EMERG);
232
0
      } else {
233
0
        mask |= LOG_MASK(LOG_EMERG);
234
0
      }
235
0
    }
236
0
    if (strcasestr(value, "alert") != NULL) {
237
0
      if (strcasestr(value, "-alert") != NULL) {
238
0
        mask &= ~LOG_MASK(LOG_ALERT);
239
0
      } else {
240
0
        mask |= LOG_MASK(LOG_ALERT);
241
0
      }
242
0
    }
243
0
    if (strcasestr(value, "crit") != NULL) {
244
0
      if (strcasestr(value, "-crit") != NULL) {
245
0
        mask &= ~LOG_MASK(LOG_CRIT);
246
0
      } else {
247
0
        mask |= LOG_MASK(LOG_CRIT);
248
0
      }
249
0
    }
250
0
    if (strcasestr(value, "err") != NULL) {
251
0
      if (strcasestr(value, "-err") != NULL) {
252
0
        mask &= ~LOG_MASK(LOG_ERR);
253
0
      } else {
254
0
        mask |= LOG_MASK(LOG_ERR);
255
0
      }
256
0
    }
257
0
    if (strcasestr(value, "warn") != NULL) {
258
0
      if (strcasestr(value, "-warn") != NULL) {
259
0
        mask &= ~LOG_MASK(LOG_WARNING);
260
0
      } else {
261
0
        mask |= LOG_MASK(LOG_WARNING);
262
0
      }
263
0
    }
264
0
    if (strcasestr(value, "notice") != NULL) {
265
0
      if (strcasestr(value, "-notice") != NULL) {
266
0
        mask &= ~LOG_MASK(LOG_NOTICE);
267
0
      } else {
268
0
        mask |= LOG_MASK(LOG_NOTICE);
269
0
      }
270
0
    }
271
0
    if (strcasestr(value, "info") != NULL) {
272
0
      if (strcasestr(value, "-info") != NULL) {
273
0
        mask &= ~LOG_MASK(LOG_INFO);
274
0
      } else {
275
0
        mask |= LOG_MASK(LOG_INFO);
276
0
      }
277
0
    }
278
0
    if (strcasestr(value, "debug") != NULL) {
279
0
      if (strcasestr(value, "-debug") != NULL) {
280
0
        mask &= ~LOG_MASK(LOG_DEBUG);
281
0
      } else {
282
0
        mask |= LOG_MASK(LOG_DEBUG);
283
0
      }
284
0
    }
285
0
  }
286
287
0
  return mask;
288
0
}
289
290
bool
291
buffer_is_nonzero(const uint8_t* buffer, size_t len)
292
3.19k
{
293
12.6k
  while (len--) {
294
11.8k
    if (*buffer++ != 0) {
295
2.46k
      return true;
296
2.46k
    }
297
11.8k
  }
298
735
  return false;
299
3.19k
}
300
301
bool
302
is_hex(const uint8_t* buff, size_t len)
303
0
{
304
0
  while (len--) {
305
0
    if (!isxdigit(*buff++)) {
306
0
      return false;
307
0
    }
308
0
  }
309
0
  return true;
310
0
}
311
312
bool
313
is_uppercase_or_digit(const uint8_t* buff, size_t len)
314
0
{
315
0
  while (len--) {
316
0
    if (!(isupper(*buff) || isdigit(*buff))) {
317
0
      return false;
318
0
    }
319
0
    buff++;
320
0
  }
321
0
  return true;
322
0
}