Coverage Report

Created: 2024-02-25 07:20

/src/libbde/libcsplit/libcsplit_narrow_split_string.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Split narrow 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 <memory.h>
24
#include <narrow_string.h>
25
#include <types.h>
26
27
#include "libcsplit_libcerror.h"
28
#include "libcsplit_narrow_split_string.h"
29
#include "libcsplit_types.h"
30
31
/* Creates a split string
32
 * Make sure the value split_string is referencing, is set to NULL
33
 * Returns 1 if successful or -1 on error
34
 */
35
int libcsplit_narrow_split_string_initialize(
36
     libcsplit_narrow_split_string_t **split_string,
37
     const char *string,
38
     size_t string_size,
39
     int number_of_segments,
40
     libcerror_error_t **error )
41
478k
{
42
478k
  libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
43
478k
  static char *function                                           = "libcsplit_narrow_split_string_initialize";
44
45
478k
  if( split_string == NULL )
46
0
  {
47
0
    libcerror_error_set(
48
0
     error,
49
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51
0
     "%s: invalid split string.",
52
0
     function );
53
54
0
    return( -1 );
55
0
  }
56
478k
  if( *split_string != NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
61
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62
0
     "%s: invalid split string value already set.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
478k
  if( number_of_segments < 0 )
68
0
  {
69
0
    libcerror_error_set(
70
0
     error,
71
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
72
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
73
0
     "%s: invalid number of segments less than zero.",
74
0
     function );
75
76
0
    return( -1 );
77
0
  }
78
478k
  internal_split_string = memory_allocate_structure(
79
478k
               libcsplit_internal_narrow_split_string_t );
80
81
478k
  if( internal_split_string == NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
86
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
87
0
     "%s: unable to create split string.",
88
0
     function );
89
90
0
    goto on_error;
91
0
  }
92
478k
  if( memory_set(
93
478k
       internal_split_string,
94
478k
       0,
95
478k
       sizeof( libcsplit_internal_narrow_split_string_t ) ) == NULL )
96
0
  {
97
0
    libcerror_error_set(
98
0
     error,
99
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
100
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
101
0
     "%s: unable to clear split string.",
102
0
     function );
103
104
0
    memory_free(
105
0
     internal_split_string );
106
107
0
    return( -1 );
108
0
  }
109
478k
  if( ( string != NULL )
110
478k
   && ( string_size > 0 ) )
111
478k
  {
112
478k
    internal_split_string->string = narrow_string_allocate(
113
478k
                                     string_size );
114
115
478k
    if( internal_split_string->string == NULL )
116
0
    {
117
0
      libcerror_error_set(
118
0
       error,
119
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
120
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
121
0
       "%s: unable to create string.",
122
0
       function );
123
124
0
      goto on_error;
125
0
    }
126
478k
    if( memory_copy(
127
478k
         internal_split_string->string,
128
478k
         string,
129
478k
         sizeof( char ) * ( string_size - 1 ) ) == NULL )
130
0
    {
131
0
      libcerror_error_set(
132
0
       error,
133
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
134
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
135
0
       "%s: unable to copy string.",
136
0
       function );
137
138
0
      goto on_error;
139
0
    }
140
478k
    internal_split_string->string[ string_size - 1 ] = 0;
141
478k
    internal_split_string->string_size               = string_size;
142
478k
  }
143
478k
  if( number_of_segments > 0 )
144
478k
  {
145
478k
    internal_split_string->segments = (char **) memory_allocate(
146
478k
                                                 sizeof( char * ) * number_of_segments );
147
148
478k
    if( internal_split_string->segments == NULL )
149
0
    {
150
0
      libcerror_error_set(
151
0
       error,
152
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
153
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
154
0
       "%s: unable to create segments.",
155
0
       function );
156
157
0
      goto on_error;
158
0
    }
159
478k
    if( memory_set(
160
478k
         internal_split_string->segments,
161
478k
         0,
162
478k
         sizeof( char * ) * number_of_segments ) == NULL )
163
0
    {
164
0
      libcerror_error_set(
165
0
       error,
166
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
167
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
168
0
       "%s: unable to clear segments.",
169
0
       function );
170
171
0
      goto on_error;
172
0
    }
173
478k
    internal_split_string->segment_sizes = (size_t *) memory_allocate(
174
478k
                                                       sizeof( size_t ) * number_of_segments );
175
176
478k
    if( internal_split_string->segment_sizes == NULL )
177
0
    {
178
0
      libcerror_error_set(
179
0
       error,
180
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
181
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
182
0
       "%s: unable to create segment sizes.",
183
0
       function );
184
185
0
      goto on_error;
186
0
    }
187
478k
    if( memory_set(
188
478k
         internal_split_string->segment_sizes,
189
478k
         0,
190
478k
         sizeof( size_t ) * number_of_segments ) == NULL )
191
0
    {
192
0
      libcerror_error_set(
193
0
       error,
194
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
195
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
196
0
       "%s: unable to clear segment sizes.",
197
0
       function );
198
199
0
      goto on_error;
200
0
    }
201
478k
  }
202
478k
  internal_split_string->number_of_segments = number_of_segments;
203
204
478k
  *split_string = (libcsplit_narrow_split_string_t *) internal_split_string;
205
206
478k
  return( 1 );
207
208
0
on_error:
209
0
  if( internal_split_string != NULL )
210
0
  {
211
0
    if( internal_split_string->segment_sizes != NULL )
212
0
    {
213
0
      memory_free(
214
0
       internal_split_string->segment_sizes );
215
0
    }
216
0
    if( internal_split_string->segments != NULL )
217
0
    {
218
0
      memory_free(
219
0
       internal_split_string->segments );
220
0
    }
221
0
    if( internal_split_string->string != NULL )
222
0
    {
223
0
      memory_free(
224
0
       internal_split_string->string );
225
0
    }
226
0
    memory_free(
227
0
     internal_split_string );
228
0
  }
229
0
  return( -1 );
230
478k
}
231
232
/* Frees a split string
233
 * Returns 1 if successful or -1 on error
234
 */
235
int libcsplit_narrow_split_string_free(
236
     libcsplit_narrow_split_string_t **split_string,
237
     libcerror_error_t **error )
238
478k
{
239
478k
  libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
240
478k
  static char *function                                           = "libcsplit_narrow_split_string_free";
241
242
478k
  if( split_string == NULL )
243
0
  {
244
0
    libcerror_error_set(
245
0
     error,
246
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
247
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
248
0
     "%s: invalid split string.",
249
0
     function );
250
251
0
    return( -1 );
252
0
  }
253
478k
  if( *split_string != NULL )
254
478k
  {
255
478k
    internal_split_string = (libcsplit_internal_narrow_split_string_t *) *split_string;
256
478k
    *split_string         = NULL;
257
258
478k
    if( internal_split_string->string != NULL )
259
478k
    {
260
478k
      memory_free(
261
478k
       internal_split_string->string );
262
478k
    }
263
478k
    if( internal_split_string->segments != NULL )
264
478k
    {
265
478k
      memory_free(
266
478k
       internal_split_string->segments );
267
478k
    }
268
478k
    if( internal_split_string->segment_sizes != NULL )
269
478k
    {
270
478k
      memory_free(
271
478k
       internal_split_string->segment_sizes );
272
478k
    }
273
478k
    memory_free(
274
478k
     internal_split_string );
275
478k
  }
276
478k
  return( 1 );
277
478k
}
278
279
/* Retrieves the string
280
 * Returns 1 if successful or -1 on error
281
 */
282
int libcsplit_narrow_split_string_get_string(
283
     libcsplit_narrow_split_string_t *split_string,
284
     char **string,
285
     size_t *string_size,
286
     libcerror_error_t **error )
287
478k
{
288
478k
  libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
289
478k
  static char *function                                           = "libcsplit_narrow_split_string_get_string";
290
291
478k
  if( split_string == NULL )
292
0
  {
293
0
    libcerror_error_set(
294
0
     error,
295
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
296
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
297
0
     "%s: invalid split string.",
298
0
     function );
299
300
0
    return( -1 );
301
0
  }
302
478k
  internal_split_string = (libcsplit_internal_narrow_split_string_t *) split_string;
303
304
478k
  if( string == NULL )
305
0
  {
306
0
    libcerror_error_set(
307
0
     error,
308
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
309
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
310
0
     "%s: invalid string.",
311
0
     function );
312
313
0
    return( -1 );
314
0
  }
315
478k
  if( string_size == NULL )
316
0
  {
317
0
    libcerror_error_set(
318
0
     error,
319
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
320
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
321
0
     "%s: invalid string size.",
322
0
     function );
323
324
0
    return( -1 );
325
0
  }
326
478k
  *string      = internal_split_string->string;
327
478k
  *string_size = internal_split_string->string_size;
328
329
478k
  return( 1 );
330
478k
}
331
332
/* Retrieves the number of segments
333
 * Returns 1 if successful or -1 on error
334
 */
335
int libcsplit_narrow_split_string_get_number_of_segments(
336
     libcsplit_narrow_split_string_t *split_string,
337
     int *number_of_segments,
338
     libcerror_error_t **error )
339
478k
{
340
478k
  libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
341
478k
  static char *function                                           = "libcsplit_narrow_split_string_get_number_of_segments";
342
343
478k
  if( split_string == NULL )
344
20
  {
345
20
    libcerror_error_set(
346
20
     error,
347
20
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
348
20
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
349
20
     "%s: invalid split string.",
350
20
     function );
351
352
20
    return( -1 );
353
20
  }
354
478k
  internal_split_string = (libcsplit_internal_narrow_split_string_t *) split_string;
355
356
478k
  if( number_of_segments == NULL )
357
0
  {
358
0
    libcerror_error_set(
359
0
     error,
360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
362
0
     "%s: invalid number of segments.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
478k
  *number_of_segments = internal_split_string->number_of_segments;
368
369
478k
  return( 1 );
370
478k
}
371
372
/* Retrieves a specific segment
373
 * Returns 1 if successful or -1 on error
374
 */
375
int libcsplit_narrow_split_string_get_segment_by_index(
376
     libcsplit_narrow_split_string_t *split_string,
377
     int segment_index,
378
     char **string_segment,
379
     size_t *string_segment_size,
380
     libcerror_error_t **error )
381
57.8M
{
382
57.8M
  libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
383
57.8M
  static char *function                                           = "libcsplit_narrow_split_string_get_segment_by_index";
384
385
57.8M
  if( split_string == NULL )
386
0
  {
387
0
    libcerror_error_set(
388
0
     error,
389
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
390
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
391
0
     "%s: invalid split string.",
392
0
     function );
393
394
0
    return( -1 );
395
0
  }
396
57.8M
  internal_split_string = (libcsplit_internal_narrow_split_string_t *) split_string;
397
398
57.8M
  if( ( segment_index < 0 )
399
57.8M
   || ( segment_index >= internal_split_string->number_of_segments ) )
400
0
  {
401
0
    libcerror_error_set(
402
0
     error,
403
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
404
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
405
0
     "%s: invalid segment index value out of bounds.",
406
0
     function );
407
408
0
    return( -1 );
409
0
  }
410
57.8M
  if( string_segment == NULL )
411
0
  {
412
0
    libcerror_error_set(
413
0
     error,
414
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
415
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
416
0
     "%s: invalid string segment.",
417
0
     function );
418
419
0
    return( -1 );
420
0
  }
421
57.8M
  if( string_segment_size == NULL )
422
0
  {
423
0
    libcerror_error_set(
424
0
     error,
425
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
426
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
427
0
     "%s: invalid string segment size.",
428
0
     function );
429
430
0
    return( -1 );
431
0
  }
432
57.8M
  *string_segment      = internal_split_string->segments[ segment_index ];
433
57.8M
  *string_segment_size = internal_split_string->segment_sizes[ segment_index ];
434
435
57.8M
  return( 1 );
436
57.8M
}
437
438
/* Sets a specific segment
439
 * Returns 1 if successful or -1 on error
440
 */
441
int libcsplit_narrow_split_string_set_segment_by_index(
442
     libcsplit_narrow_split_string_t *split_string,
443
     int segment_index,
444
     char *string_segment,
445
     size_t string_segment_size,
446
     libcerror_error_t **error )
447
59.1M
{
448
59.1M
  libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
449
59.1M
  static char *function                                           = "libcsplit_narrow_split_string_set_segment_by_index";
450
59.1M
  size_t string_segment_offset                                    = 0;
451
452
59.1M
  if( split_string == NULL )
453
0
  {
454
0
    libcerror_error_set(
455
0
     error,
456
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
457
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
458
0
     "%s: invalid split string.",
459
0
     function );
460
461
0
    return( -1 );
462
0
  }
463
59.1M
  internal_split_string = (libcsplit_internal_narrow_split_string_t *) split_string;
464
465
59.1M
  if( ( segment_index < 0 )
466
59.1M
   || ( segment_index >= internal_split_string->number_of_segments ) )
467
0
  {
468
0
    libcerror_error_set(
469
0
     error,
470
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
471
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
472
0
     "%s: invalid segment index value out of bounds.",
473
0
     function );
474
475
0
    return( -1 );
476
0
  }
477
59.1M
  if( string_segment_size > (size_t) SSIZE_MAX )
478
0
  {
479
0
    libcerror_error_set(
480
0
     error,
481
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
482
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
483
0
     "%s: invalid string segment size value exceeds maximum.",
484
0
     function );
485
486
0
    return( -1 );
487
0
  }
488
59.1M
  if( string_segment == NULL )
489
0
  {
490
0
    if( string_segment_size != 0 )
491
0
    {
492
0
      libcerror_error_set(
493
0
       error,
494
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
495
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
496
0
       "%s: invalid string segment size value out of bounds.",
497
0
       function );
498
499
0
      return( -1 );
500
0
    }
501
0
  }
502
59.1M
  else
503
59.1M
  {
504
59.1M
    if( string_segment < internal_split_string->string )
505
0
    {
506
0
      libcerror_error_set(
507
0
       error,
508
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
509
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
510
0
       "%s: invalid string segment value out of bounds.",
511
0
       function );
512
513
0
      return( -1 );
514
0
    }
515
59.1M
    string_segment_offset = (size_t) ( string_segment - internal_split_string->string );
516
517
59.1M
    if( string_segment_offset >= internal_split_string->string_size )
518
0
    {
519
0
      libcerror_error_set(
520
0
       error,
521
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
522
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
523
0
       "%s: invalid string segment value out of bounds.",
524
0
       function );
525
526
0
      return( -1 );
527
0
    }
528
59.1M
    string_segment_offset += string_segment_size;
529
530
59.1M
    if( string_segment_offset > internal_split_string->string_size )
531
0
    {
532
0
      libcerror_error_set(
533
0
       error,
534
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
535
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
536
0
       "%s: invalid string segment value out of bounds.",
537
0
       function );
538
539
0
      return( -1 );
540
0
    }
541
59.1M
  }
542
59.1M
  internal_split_string->segments[ segment_index ]      = string_segment;
543
59.1M
  internal_split_string->segment_sizes[ segment_index ] = string_segment_size;
544
545
59.1M
  return( 1 );
546
59.1M
}
547