Coverage Report

Created: 2024-02-25 07:20

/src/libvslvm/libcsplit/libcsplit_narrow_string.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Narrow character string functions
3
 *
4
 * Copyright (C) 2008-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program 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 Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <types.h>
24
25
#include "libcsplit_libcerror.h"
26
#include "libcsplit_narrow_split_string.h"
27
#include "libcsplit_narrow_string.h"
28
#include "libcsplit_types.h"
29
30
/* Splits a narrow character string
31
 * Make sure the value split_string is referencing, is set to NULL
32
 * Returns 1 if successful or -1 on error
33
 */
34
int libcsplit_narrow_string_split(
35
     const char *string,
36
     size_t string_size,
37
     char delimiter,
38
     libcsplit_narrow_split_string_t **split_string,
39
     libcerror_error_t **error )
40
478k
{
41
478k
  char *segment_start    = NULL;
42
478k
  char *segment_end      = NULL;
43
478k
  char *string_end       = NULL;
44
478k
  char *string_start     = NULL;
45
478k
  static char *function  = "libcsplit_narrow_string_split";
46
478k
  ssize_t segment_length = 0;
47
478k
  int number_of_segments = 0;
48
478k
  int segment_index      = 0;
49
50
478k
  if( string == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid string.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
478k
  if( string_size > (size_t) SSIZE_MAX )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
66
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
67
0
     "%s: invalid string size value exceeds maximum.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
478k
  if( split_string == NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
77
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
78
0
     "%s: invalid split string.",
79
0
     function );
80
81
0
    return( -1 );
82
0
  }
83
478k
  if( *split_string != NULL )
84
0
  {
85
0
    libcerror_error_set(
86
0
     error,
87
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
88
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
89
0
     "%s: invalid split string already set.",
90
0
     function );
91
92
0
    return( -1 );
93
0
  }
94
  /* An empty string has no segments
95
   */
96
478k
  if( ( string_size == 0 )
97
478k
   || ( string[ 0 ] == 0 ) )
98
20
  {
99
20
    return( 1 );
100
20
  }
101
  /* Determine the number of segments
102
   */
103
478k
  segment_start = (char *) string;
104
478k
  string_end    = (char *) &( string[ string_size - 1 ] );
105
106
478k
  do
107
59.1M
  {
108
59.1M
    segment_end = segment_start;
109
110
133M
    while( segment_end <= string_end )
111
133M
    {
112
133M
      if( ( segment_end == string_end )
113
133M
       || ( *segment_end == 0 ) )
114
478k
      {
115
478k
        segment_end = NULL;
116
117
478k
        break;
118
478k
      }
119
133M
      else if( *segment_end == delimiter )
120
58.7M
      {
121
58.7M
        break;
122
58.7M
      }
123
74.6M
      segment_end++;
124
74.6M
    }
125
59.1M
    if( segment_end > string_end )
126
0
    {
127
0
      break;
128
0
    }
129
59.1M
    segment_index++;
130
131
59.1M
    if( segment_end == NULL )
132
478k
    {
133
478k
      break;
134
478k
    }
135
58.7M
    if( segment_end == segment_start )
136
56.2M
    {
137
56.2M
      segment_start++;
138
56.2M
    }
139
2.42M
    else if( segment_end != string )
140
2.42M
    {
141
2.42M
      segment_start = segment_end + 1;
142
2.42M
    }
143
58.7M
  }
144
58.7M
  while( segment_end != NULL );
145
146
0
  number_of_segments = segment_index;
147
148
478k
  if( libcsplit_narrow_split_string_initialize(
149
478k
       split_string,
150
478k
       string,
151
478k
       string_size,
152
478k
       number_of_segments,
153
478k
       error ) != 1 )
154
0
  {
155
0
    libcerror_error_set(
156
0
     error,
157
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
158
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
159
0
     "%s: unable to initialize split string.",
160
0
     function );
161
162
0
    goto on_error;
163
0
  }
164
  /* Do not bother with strings that do not need splitting
165
   */
166
478k
  if( number_of_segments == 0 )
167
0
  {
168
0
    return( 1 );
169
0
  }
170
  /* Determine the segments
171
   * empty segments are stored as strings only containing the end of character
172
   */
173
478k
  if( libcsplit_narrow_split_string_get_string(
174
478k
       *split_string,
175
478k
       &string_start,
176
478k
       &string_size,
177
478k
       error ) != 1 )
178
0
  {
179
0
    libcerror_error_set(
180
0
     error,
181
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
182
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
183
0
     "%s: unable to retrieve split string.",
184
0
     function );
185
186
0
    goto on_error;
187
0
  }
188
478k
  if( string_start == NULL )
189
0
  {
190
0
    libcerror_error_set(
191
0
     error,
192
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
193
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
194
0
     "%s: missing string start.",
195
0
     function );
196
197
0
    goto on_error;
198
0
  }
199
478k
  if( string_size < 1 )
200
0
  {
201
0
    libcerror_error_set(
202
0
     error,
203
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
204
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
205
0
     "%s: invalid string size value out of bounds.",
206
0
     function );
207
208
0
    goto on_error;
209
0
  }
210
478k
  segment_start = string_start;
211
478k
  string_end    = &( string_start[ string_size - 1 ] );
212
213
478k
  for( segment_index = 0;
214
59.1M
       segment_index < number_of_segments;
215
58.7M
       segment_index++ )
216
59.1M
  {
217
59.1M
    segment_end = segment_start;
218
219
133M
    while( segment_end <= string_end )
220
133M
    {
221
133M
      if( ( segment_end == string_end )
222
133M
       || ( *segment_end == 0 ) )
223
478k
      {
224
478k
        segment_end = NULL;
225
226
478k
        break;
227
478k
      }
228
133M
      else if( *segment_end == delimiter )
229
58.7M
      {
230
58.7M
        break;
231
58.7M
      }
232
74.6M
      segment_end++;
233
74.6M
    }
234
59.1M
    if( segment_end == NULL )
235
478k
    {
236
478k
      segment_length = (ssize_t) ( string_end - segment_start );
237
478k
    }
238
58.7M
    else
239
58.7M
    {
240
58.7M
      segment_length = (ssize_t) ( segment_end - segment_start );
241
58.7M
    }
242
59.1M
    if( segment_length >= 0 )
243
59.1M
    {
244
59.1M
      segment_start[ segment_length ] = 0;
245
246
59.1M
      if( libcsplit_narrow_split_string_set_segment_by_index(
247
59.1M
           *split_string,
248
59.1M
           segment_index,
249
59.1M
           segment_start,
250
59.1M
           segment_length + 1,
251
59.1M
           error ) != 1 )
252
0
      {
253
0
        libcerror_error_set(
254
0
         error,
255
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
256
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
257
0
         "%s: unable to set split string segment: %d.",
258
0
         function,
259
0
         segment_index );
260
261
0
        goto on_error;
262
0
      }
263
59.1M
    }
264
59.1M
    if( segment_end == NULL )
265
478k
    {
266
478k
      break;
267
478k
    }
268
58.7M
    if( segment_end == string_start )
269
15.8k
    {
270
15.8k
      segment_start++;
271
15.8k
    }
272
58.6M
    else
273
58.6M
    {
274
58.6M
      segment_start = segment_end + 1;
275
58.6M
    }
276
58.7M
  }
277
478k
  return( 1 );
278
279
0
on_error:
280
0
  if( *split_string != NULL )
281
0
  {
282
0
    libcsplit_narrow_split_string_free(
283
0
     split_string,
284
0
     NULL );
285
0
  }
286
0
  return( -1 );
287
478k
}
288