Coverage Report

Created: 2023-09-25 07:13

/src/yara/libyara/sizedstr.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright (c) 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 <ctype.h>
31
#include <string.h>
32
#include <yara/globals.h>
33
#include <yara/mem.h>
34
#include <yara/sizedstr.h>
35
#include <yara/strutils.h>
36
#include <yara/types.h>
37
38
////////////////////////////////////////////////////////////////////////////////
39
// ss_compare returns:
40
//     0 if s1 == s2
41
//    -1 if s1 < s2
42
//     1 if s1 > s2
43
//
44
int ss_compare(SIZED_STRING* s1, SIZED_STRING* s2)
45
291
{
46
291
  size_t i = 0;
47
48
18.0k
  while (s1->length > i && s2->length > i && s1->c_string[i] == s2->c_string[i])
49
17.7k
  {
50
17.7k
    i++;
51
17.7k
  }
52
53
291
  if (i == s1->length && i == s2->length)
54
276
    return 0;
55
15
  else if (i == s1->length)
56
0
    return -1;
57
15
  else if (i == s2->length)
58
0
    return 1;
59
15
  else if (s1->c_string[i] < s2->c_string[i])
60
3
    return -1;
61
12
  else
62
12
    return 1;
63
291
}
64
65
////////////////////////////////////////////////////////////////////////////////
66
// ss_icompare is the case-insensitive version of ss_compare.
67
//
68
int ss_icompare(SIZED_STRING* s1, SIZED_STRING* s2)
69
0
{
70
0
  size_t i = 0;
71
72
0
  while (s1->length > i && s2->length > i &&
73
0
         yr_lowercase[(uint8_t) s1->c_string[i]] ==
74
0
             yr_lowercase[(uint8_t) s2->c_string[i]])
75
0
  {
76
0
    i++;
77
0
  }
78
79
0
  if (i == s1->length && i == s2->length)
80
0
    return 0;
81
0
  else if (i == s1->length)
82
0
    return -1;
83
0
  else if (i == s2->length)
84
0
    return 1;
85
0
  else if (s1->c_string[i] < s2->c_string[i])
86
0
    return -1;
87
0
  else
88
0
    return 1;
89
0
}
90
91
////////////////////////////////////////////////////////////////////////////////
92
// ss_contains returns true if the sized string s1 contains s2.
93
//
94
bool ss_contains(SIZED_STRING* s1, SIZED_STRING* s2)
95
0
{
96
0
  return memmem(s1->c_string, s1->length, s2->c_string, s2->length) != NULL;
97
0
}
98
99
////////////////////////////////////////////////////////////////////////////////
100
// ss_icontains is the case-insensitive version of ss_contains.
101
//
102
bool ss_icontains(SIZED_STRING* s1, SIZED_STRING* s2)
103
0
{
104
0
  if (s1->length < s2->length)
105
0
    return false;
106
107
0
  for (uint32_t i = 0; i < s1->length - s2->length + 1; i++)
108
0
  {
109
0
    uint32_t j = 0;
110
111
0
    for (j = 0; j < s2->length; j++)
112
0
      if (yr_lowercase[(uint8_t) s1->c_string[i + j]] !=
113
0
          yr_lowercase[(uint8_t) s2->c_string[j]])
114
0
        break;
115
116
0
    if (j == s2->length)
117
0
      return true;
118
0
  }
119
120
0
  return false;
121
0
}
122
123
////////////////////////////////////////////////////////////////////////////////
124
// ss_startswith returns true if the sized string s1 starts with s2.
125
//
126
bool ss_startswith(SIZED_STRING* s1, SIZED_STRING* s2)
127
0
{
128
0
  if (s1->length < s2->length)
129
0
    return false;
130
131
0
  for (uint32_t i = 0; i < s2->length; i++)
132
0
  {
133
0
    if (s1->c_string[i] != s2->c_string[i])
134
0
      return false;
135
0
  }
136
137
0
  return true;
138
0
}
139
140
////////////////////////////////////////////////////////////////////////////////
141
// ss_istartswith is the case-insensitive version of ss_startswith.
142
//
143
bool ss_istartswith(SIZED_STRING* s1, SIZED_STRING* s2)
144
0
{
145
0
  if (s1->length < s2->length)
146
0
    return false;
147
148
0
  for (uint32_t i = 0; i < s2->length; i++)
149
0
  {
150
0
    if (yr_lowercase[(uint8_t) s1->c_string[i]] !=
151
0
        yr_lowercase[(uint8_t) s2->c_string[i]])
152
0
      return false;
153
0
  }
154
155
0
  return true;
156
0
}
157
158
////////////////////////////////////////////////////////////////////////////////
159
// ss_endswith returns true if the sized string s1 ends with s2.
160
//
161
bool ss_endswith(SIZED_STRING* s1, SIZED_STRING* s2)
162
0
{
163
0
  if (s1->length < s2->length)
164
0
    return false;
165
166
0
  for (uint32_t i = 0; i < s2->length; i++)
167
0
  {
168
0
    if (s1->c_string[s1->length - s2->length + i] != s2->c_string[i])
169
0
      return false;
170
0
  }
171
172
0
  return true;
173
0
}
174
175
////////////////////////////////////////////////////////////////////////////////
176
// ss_iendswith is the case-insensitive version of ss_endswith.
177
//
178
bool ss_iendswith(SIZED_STRING* s1, SIZED_STRING* s2)
179
0
{
180
0
  if (s1->length < s2->length)
181
0
    return false;
182
183
0
  for (uint32_t i = 0; i < s2->length; i++)
184
0
  {
185
0
    if (yr_lowercase[(uint8_t) s1->c_string[s1->length - s2->length + i]] !=
186
0
        yr_lowercase[(uint8_t) s2->c_string[i]])
187
0
      return false;
188
0
  }
189
190
0
  return true;
191
0
}
192
193
////////////////////////////////////////////////////////////////////////////////
194
// ss_dup creates a new copy of a given SIZED_STRING.
195
//
196
SIZED_STRING* ss_dup(SIZED_STRING* s)
197
0
{
198
0
  SIZED_STRING* result = (SIZED_STRING*) yr_malloc(
199
0
      sizeof(SIZED_STRING) + s->length);
200
201
0
  if (result == NULL)
202
0
    return NULL;
203
204
0
  result->length = s->length;
205
0
  result->flags = s->flags;
206
207
0
  memcpy(result->c_string, s->c_string, s->length + 1);
208
209
0
  return result;
210
0
}
211
212
////////////////////////////////////////////////////////////////////////////////
213
// ss_new creates a SIZED_STRING from a C string.
214
//
215
SIZED_STRING* ss_new(const char* s)
216
1.52k
{
217
1.52k
  SIZED_STRING* result;
218
219
1.52k
  size_t length = strlen(s);
220
221
1.52k
  result = (SIZED_STRING*) yr_malloc(sizeof(SIZED_STRING) + length);
222
223
1.52k
  if (result == NULL)
224
0
    return NULL;
225
226
1.52k
  result->length = (uint32_t) length;
227
1.52k
  result->flags = 0;
228
229
  // Copy the string and the null terminator.
230
1.52k
  strcpy(result->c_string, s);
231
232
1.52k
  return result;
233
1.52k
}
234
235
////////////////////////////////////////////////////////////////////////////////
236
// Convert a SIZED_STRING to a wide version. It is up to the caller to free
237
// the returned string.
238
//
239
SIZED_STRING* ss_convert_to_wide(SIZED_STRING* s)
240
2.71k
{
241
2.71k
  SIZED_STRING* wide = (SIZED_STRING*) yr_malloc(
242
2.71k
      sizeof(SIZED_STRING) + s->length * 2);
243
244
2.71k
  if (wide == NULL)
245
0
    return NULL;
246
247
856k
  for (size_t i = 0; i < s->length; i++)
248
854k
  {
249
854k
    wide->c_string[i * 2] = s->c_string[i];
250
854k
    wide->c_string[i * 2 + 1] = '\x00';
251
854k
  }
252
253
2.71k
  wide->length = s->length * 2;
254
2.71k
  wide->flags = s->flags | STRING_FLAGS_WIDE;
255
256
2.71k
  return wide;
257
2.71k
}