Coverage Report

Created: 2024-02-25 07:20

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