Coverage Report

Created: 2023-06-07 07:18

/src/yara/libyara/strutils.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright (c) 2007-2014. The YARA Authors. All Rights Reserved.
3
4
Redistribution and use in source and binary forms, with or without modification,
5
are permitted provided that the following conditions are met:
6
7
1. Redistributions of source code must retain the above copyright notice, this
8
list of conditions and the following disclaimer.
9
10
2. Redistributions in binary form must reproduce the above copyright notice,
11
this list of conditions and the following disclaimer in the documentation and/or
12
other materials provided with the distribution.
13
14
3. Neither the name of the copyright holder nor the names of its contributors
15
may be used to endorse or promote products derived from this software without
16
specific prior written permission.
17
18
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
#include <stdio.h>
31
#include <string.h>
32
#include <yara/mem.h>
33
#include <yara/strutils.h>
34
35
uint64_t xtoi(const char* hexstr)
36
0
{
37
0
  size_t i;
38
0
  size_t l = strlen(hexstr);
39
40
0
  uint64_t r = 0;
41
42
0
  for (i = 0; i < l; i++)
43
0
  {
44
0
    switch (hexstr[i])
45
0
    {
46
0
    case '0':
47
0
    case '1':
48
0
    case '2':
49
0
    case '3':
50
0
    case '4':
51
0
    case '5':
52
0
    case '6':
53
0
    case '7':
54
0
    case '8':
55
0
    case '9':
56
0
      r |= ((uint64_t) (hexstr[i] - '0')) << ((l - i - 1) * 4);
57
0
      break;
58
0
    case 'a':
59
0
    case 'b':
60
0
    case 'c':
61
0
    case 'd':
62
0
    case 'e':
63
0
    case 'f':
64
0
      r |= ((uint64_t) (hexstr[i] - 'a' + 10)) << ((l - i - 1) * 4);
65
0
      break;
66
0
    case 'A':
67
0
    case 'B':
68
0
    case 'C':
69
0
    case 'D':
70
0
    case 'E':
71
0
    case 'F':
72
0
      r |= ((uint64_t) (hexstr[i] - 'A' + 10)) << ((l - i - 1) * 4);
73
0
      break;
74
0
    default:
75
0
      i = l;  // force loop exit
76
0
    }
77
0
  }
78
79
0
  return r;
80
0
}
81
82
/*
83
84
strlcpy and strlcat are defined in FreeBSD and OpenBSD,
85
the following implementations were taken from OpenBSD.
86
87
*/
88
89
#if !HAVE_STRLCPY && !defined(strlcpy)
90
size_t strlcpy(char* dst, const char* src, size_t size)
91
0
{
92
0
  register char* d = dst;
93
0
  register const char* s = src;
94
0
  register size_t n = size;
95
96
  // Copy as many bytes as will fit
97
98
0
  if (n != 0 && --n != 0)
99
0
  {
100
0
    do
101
0
    {
102
0
      if ((*d++ = *s++) == 0)
103
0
        break;
104
105
0
    } while (--n != 0);
106
0
  }
107
108
  // Not enough room in dst, add NUL and traverse rest of src
109
110
0
  if (n == 0)
111
0
  {
112
0
    if (size != 0)
113
0
      *d = '\0';  // NULL-terminate dst
114
115
0
    while (*s++)
116
0
      ;
117
0
  }
118
119
0
  return (s - src - 1);  // count does not include NULL
120
0
}
121
#endif
122
123
#if !HAVE_STRLCAT && !defined(strlcat)
124
size_t strlcat(char* dst, const char* src, size_t size)
125
0
{
126
0
  register char* d = dst;
127
0
  register const char* s = src;
128
0
  register size_t n = size;
129
0
  size_t dlen;
130
131
  // Find the end of dst and adjust bytes left but don't go past end
132
133
0
  while (n-- != 0 && *d != '\0') d++;
134
135
0
  dlen = d - dst;
136
0
  n = size - dlen;
137
138
0
  if (n == 0)
139
0
    return (dlen + strlen(s));
140
141
0
  while (*s != '\0')
142
0
  {
143
0
    if (n != 1)
144
0
    {
145
0
      *d++ = *s;
146
0
      n--;
147
0
    }
148
0
    s++;
149
0
  }
150
151
0
  *d = '\0';
152
153
0
  return (dlen + (s - src));  // count does not include NULL
154
0
}
155
#endif
156
157
int strnlen_w(const char* w_str)
158
0
{
159
0
  int len = 0;
160
161
0
  while (w_str[0] || w_str[1])
162
0
  {
163
0
    w_str += 2;
164
0
    len += 1;
165
0
  }
166
167
0
  return len;
168
0
}
169
170
int strcmp_w(const char* w_str, const char* str)
171
0
{
172
0
  while (*str != 0 && w_str[0] == *str && w_str[1] == 0)
173
0
  {
174
0
    w_str += 2;
175
0
    str += 1;
176
0
  }
177
178
  // Higher-order byte of wide char non-zero? -> w_str is larger than str
179
180
0
  if (w_str[1] != 0)
181
0
    return 1;
182
183
0
  return w_str[0] - *str;
184
0
}
185
186
size_t strlcpy_w(char* dst, const char* w_src, size_t n)
187
0
{
188
0
  register char* d = dst;
189
0
  register const char* s = w_src;
190
191
0
  while (n > 1 && *s != 0)
192
0
  {
193
0
    *d = *s;
194
0
    d += 1;
195
0
    n -= 1;
196
0
    s += 2;
197
0
  }
198
199
0
  while (*s) s += 2;
200
201
0
  *d = '\0';
202
203
0
  return (s - w_src) / 2;
204
0
}
205
206
#if !HAVE_MEMMEM && !defined(memmem)
207
void* memmem(
208
    const void* haystack,
209
    size_t haystack_size,
210
    const void* needle,
211
    size_t needle_size)
212
{
213
  char* sp = (char*) haystack;
214
  char* pp = (char*) needle;
215
  char* eos;
216
217
  if (haystack == NULL || haystack_size == 0 || needle == NULL ||
218
      needle_size == 0)
219
    return NULL;
220
221
  eos = sp + haystack_size - needle_size;
222
223
  while (sp <= eos)
224
  {
225
    if (*sp == *pp && memcmp(sp, pp, needle_size) == 0)
226
      return sp;
227
228
    sp++;
229
  }
230
231
  return NULL;
232
}
233
#endif
234
235
///////////////////////////////////////////////////////////////////////////////
236
// This our own implementation of isalnum(). The library version is locale
237
// dependent in some platforms and can consider non-ASCII characters to be
238
// alphanumeric.
239
//
240
int yr_isalnum(const uint8_t* s)
241
0
{
242
0
  return (*s >= 0x30 && *s <= 0x39) || (*s >= 0x41 && *s <= 0x5a) ||
243
0
         (*s >= 0x61 && *s <= 0x7a);
244
0
}
245
246
//////////////////////////////////////////////////////////////////////////
247
// This our own implementation of vasprintf(), as it is not available on
248
// some platforms. It is based on the implementation of vsnprintf but it
249
// allocates memory using yr_malloc, and therefore the caller must free
250
// the memory using yr_free.
251
//
252
void yr_vasprintf(char** strp, const char* fmt, va_list ap)
253
0
{
254
0
  va_list ap_copy;
255
0
  va_copy(ap_copy, ap);
256
0
  *strp = NULL;
257
258
0
  int len = vsnprintf(NULL, 0, fmt, ap_copy);
259
260
0
  va_end(ap_copy);
261
262
0
  if (len < 0)
263
0
    return;
264
265
0
  *strp = (char*) yr_malloc(len + 1);
266
267
0
  if (*strp == NULL)
268
0
    return;
269
270
0
  vsnprintf(*strp, len + 1, fmt, ap);
271
0
}
272
273
//////////////////////////////////////////////////////////////////////////
274
// This our own implementation of asprintf(), see yr_vasprintf() for details.
275
//
276
void yr_asprintf(char** strp, const char* fmt, ...)
277
0
{
278
0
  va_list ap;
279
0
  va_start(ap, fmt);
280
0
  yr_vasprintf(strp, fmt, ap);
281
0
  va_end(ap);
282
0
}