Coverage Report

Created: 2026-07-25 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libewf/libewf/libewf_lef_subject.c
Line
Count
Source
1
/*
2
 * Logical Evidence File (LEF) subject functions
3
 *
4
 * Copyright (C) 2006-2026, 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 "libewf_definitions.h"
27
#include "libewf_lef_subject.h"
28
#include "libewf_libcerror.h"
29
#include "libewf_libcnotify.h"
30
#include "libewf_libfvalue.h"
31
#include "libewf_serialized_string.h"
32
33
/* Creates a subject
34
 * Make sure the value lef_subject is referencing, is set to NULL
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libewf_lef_subject_initialize(
38
     libewf_lef_subject_t **lef_subject,
39
     libcerror_error_t **error )
40
0
{
41
0
  static char *function = "libewf_lef_subject_initialize";
42
43
0
  if( lef_subject == NULL )
44
0
  {
45
0
    libcerror_error_set(
46
0
     error,
47
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49
0
     "%s: invalid subject.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
0
  if( *lef_subject != NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
59
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
60
0
     "%s: invalid subject value already set.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
0
  *lef_subject = memory_allocate_structure(
66
0
                  libewf_lef_subject_t );
67
68
0
  if( *lef_subject == NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
73
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
74
0
     "%s: unable to create subject.",
75
0
     function );
76
77
0
    goto on_error;
78
0
  }
79
0
  if( memory_set(
80
0
       *lef_subject,
81
0
       0,
82
0
       sizeof( libewf_lef_subject_t ) ) == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
88
0
     "%s: unable to clear subject.",
89
0
     function );
90
91
0
    memory_free(
92
0
     *lef_subject );
93
94
0
    *lef_subject = NULL;
95
96
0
    return( -1 );
97
0
  }
98
0
  if( libewf_serialized_string_initialize(
99
0
       &( ( *lef_subject)->name ),
100
0
       error ) != 1 )
101
0
  {
102
0
    libcerror_error_set(
103
0
     error,
104
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
105
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
106
0
     "%s: unable to create name string.",
107
0
     function );
108
109
0
    goto on_error;
110
0
  }
111
0
  return( 1 );
112
113
0
on_error:
114
0
  if( *lef_subject != NULL )
115
0
  {
116
0
    memory_free(
117
0
     *lef_subject );
118
119
0
    *lef_subject = NULL;
120
0
  }
121
0
  return( -1 );
122
0
}
123
124
/* Frees a subject
125
 * Returns 1 if successful or -1 on error
126
 */
127
int libewf_lef_subject_free(
128
     libewf_lef_subject_t **lef_subject,
129
     libcerror_error_t **error )
130
0
{
131
0
  static char *function = "libewf_lef_subject_free";
132
0
  int result            = 1;
133
134
0
  if( lef_subject == NULL )
135
0
  {
136
0
    libcerror_error_set(
137
0
     error,
138
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
139
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
140
0
     "%s: invalid subject.",
141
0
     function );
142
143
0
    return( -1 );
144
0
  }
145
0
  if( *lef_subject != NULL )
146
0
  {
147
0
    if( ( *lef_subject )->name != NULL )
148
0
    {
149
0
      if( libewf_serialized_string_free(
150
0
           &( ( *lef_subject )->name ),
151
0
           error ) != 1 )
152
0
      {
153
0
        libcerror_error_set(
154
0
         error,
155
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
156
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
157
0
         "%s: unable to free name string.",
158
0
         function );
159
160
0
        result = -1;
161
0
      }
162
0
    }
163
0
    memory_free(
164
0
     *lef_subject );
165
166
0
    *lef_subject = NULL;
167
0
  }
168
0
  return( result );
169
0
}
170
171
/* Clones the subject
172
 * Returns 1 if successful or -1 on error
173
 */
174
int libewf_lef_subject_clone(
175
     libewf_lef_subject_t **destination_lef_subject,
176
     libewf_lef_subject_t *source_lef_subject,
177
     libcerror_error_t **error )
178
0
{
179
0
  static char *function = "libewf_lef_subject_clone";
180
181
0
  if( destination_lef_subject == NULL )
182
0
  {
183
0
    libcerror_error_set(
184
0
     error,
185
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
186
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
187
0
     "%s: invalid destination subject.",
188
0
     function );
189
190
0
    return( -1 );
191
0
  }
192
0
  if( *destination_lef_subject != NULL )
193
0
  {
194
0
    libcerror_error_set(
195
0
     error,
196
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
197
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
198
0
     "%s: invalid destination subject value already set.",
199
0
     function );
200
201
0
    return( -1 );
202
0
  }
203
0
  if( source_lef_subject == NULL )
204
0
  {
205
0
    *destination_lef_subject = NULL;
206
207
0
    return( 1 );
208
0
  }
209
0
  *destination_lef_subject = memory_allocate_structure(
210
0
                              libewf_lef_subject_t );
211
212
0
  if( *destination_lef_subject == NULL )
213
0
  {
214
0
    libcerror_error_set(
215
0
     error,
216
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
217
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
218
0
     "%s: unable to create destination subject.",
219
0
     function );
220
221
0
    goto on_error;
222
0
  }
223
0
  if( memory_copy(
224
0
       *destination_lef_subject,
225
0
       source_lef_subject,
226
0
       sizeof( libewf_lef_subject_t ) ) == NULL )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
231
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
232
0
     "%s: unable to copy source to destination subject.",
233
0
     function );
234
235
0
    memory_free(
236
0
     *destination_lef_subject );
237
238
0
    *destination_lef_subject = NULL;
239
240
0
    return( -1 );
241
0
  }
242
0
  ( *destination_lef_subject )->name = NULL;
243
244
0
  if( libewf_serialized_string_clone(
245
0
       &( ( *destination_lef_subject )->name ),
246
0
       source_lef_subject->name,
247
0
       error ) != 1 )
248
0
  {
249
0
    libcerror_error_set(
250
0
     error,
251
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
252
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
253
0
     "%s: unable to clone destination name string.",
254
0
     function );
255
256
0
    goto on_error;
257
0
  }
258
0
  return( 1 );
259
260
0
on_error:
261
0
  if( *destination_lef_subject != NULL )
262
0
  {
263
0
    libewf_lef_subject_free(
264
0
     destination_lef_subject,
265
0
     NULL );
266
0
  }
267
0
  return( -1 );
268
0
}
269
270
/* Reads a subject
271
 * Returns 1 if successful or -1 on error
272
 */
273
int libewf_lef_subject_read_data(
274
     libewf_lef_subject_t *lef_subject,
275
     libfvalue_split_utf8_string_t *types,
276
     const uint8_t *data,
277
     size_t data_size,
278
     libcerror_error_t **error )
279
0
{
280
0
  libfvalue_split_utf8_string_t *values = NULL;
281
0
  uint8_t *type_string                  = NULL;
282
0
  uint8_t *value_string                 = NULL;
283
0
  static char *function                 = "libewf_lef_subject_read_data";
284
0
  size_t type_string_size               = 0;
285
0
  size_t value_string_size              = 0;
286
0
  int number_of_types                   = 0;
287
0
  int number_of_values                  = 0;
288
0
  int value_index                       = 0;
289
290
0
  if( lef_subject == 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 subject.",
297
0
     function );
298
299
0
    return( -1 );
300
0
  }
301
0
  if( libfvalue_split_utf8_string_get_number_of_segments(
302
0
       types,
303
0
       &number_of_types,
304
0
       error ) != 1 )
305
0
  {
306
0
    libcerror_error_set(
307
0
     error,
308
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
309
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
310
0
     "%s: unable to retrieve number of types",
311
0
     function );
312
313
0
    goto on_error;
314
0
  }
315
0
  if( libfvalue_utf8_string_split(
316
0
       data,
317
0
       data_size,
318
0
       (uint8_t) '\t',
319
0
       &values,
320
0
       error ) != 1 )
321
0
  {
322
0
    libcerror_error_set(
323
0
     error,
324
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
325
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
326
0
     "%s: unable to split data into string values.",
327
0
     function );
328
329
0
    goto on_error;
330
0
  }
331
0
  if( libfvalue_split_utf8_string_get_number_of_segments(
332
0
       values,
333
0
       &number_of_values,
334
0
       error ) != 1 )
335
0
  {
336
0
    libcerror_error_set(
337
0
     error,
338
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
339
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
340
0
     "%s: unable to retrieve number of values",
341
0
     function );
342
343
0
    goto on_error;
344
0
  }
345
0
  if( number_of_types != number_of_values )
346
0
  {
347
0
    libcerror_error_set(
348
0
     error,
349
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
350
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
351
0
     "%s: mismatch in number of types and values.",
352
0
     function );
353
354
0
    goto on_error;
355
0
  }
356
0
  for( value_index = 0;
357
0
       value_index < number_of_types;
358
0
       value_index++ )
359
0
  {
360
0
    if( libfvalue_split_utf8_string_get_segment_by_index(
361
0
         types,
362
0
         value_index,
363
0
         &type_string,
364
0
         &type_string_size,
365
0
         error ) != 1 )
366
0
    {
367
0
      libcerror_error_set(
368
0
       error,
369
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
370
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
371
0
       "%s: unable to retrieve type string: %d.",
372
0
       function,
373
0
       value_index );
374
375
0
      goto on_error;
376
0
    }
377
0
    if( ( type_string == NULL )
378
0
     || ( type_string_size < 2 )
379
0
     || ( type_string[ 0 ] == 0 ) )
380
0
    {
381
0
      libcerror_error_set(
382
0
       error,
383
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
384
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
385
0
       "%s: missing type string: %d.",
386
0
       function,
387
0
       value_index );
388
389
0
      goto on_error;
390
0
    }
391
0
    if( value_index >= number_of_values )
392
0
    {
393
0
      value_string      = NULL;
394
0
      value_string_size = 0;
395
0
    }
396
0
    else
397
0
    {
398
0
      if( libfvalue_split_utf8_string_get_segment_by_index(
399
0
           values,
400
0
           value_index,
401
0
           &value_string,
402
0
           &value_string_size,
403
0
           error ) != 1 )
404
0
      {
405
0
        libcerror_error_set(
406
0
         error,
407
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
408
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
409
0
         "%s: unable to retrieve value string: %d.",
410
0
         function,
411
0
         value_index );
412
413
0
        goto on_error;
414
0
      }
415
0
      if( ( value_string == NULL )
416
0
       || ( value_string_size < 2 )
417
0
       || ( value_string[ 0 ] == 0 ) )
418
0
      {
419
0
        value_string      = NULL;
420
0
        value_string_size = 0;
421
0
      }
422
0
    }
423
#if defined( HAVE_DEBUG_OUTPUT )
424
    if( libcnotify_verbose != 0 )
425
    {
426
      libcnotify_printf(
427
       "%s: type: %3s with value\t\t:",
428
       function,
429
       (char *) type_string );
430
431
      if( value_string != NULL )
432
      {
433
        libcnotify_printf(
434
         " %s",
435
         (char *) value_string );
436
      }
437
      libcnotify_printf(
438
       "\n" );
439
    }
440
#endif
441
0
    if( ( value_string == NULL )
442
0
     || ( value_string_size == 0 ) )
443
0
    {
444
      /* Ignore empty values
445
       */
446
0
    }
447
0
    else if( type_string_size == 2 )
448
0
    {
449
0
      if( type_string[ 0 ] == (uint8_t) 'n' )
450
0
      {
451
0
        if( libewf_serialized_string_read_data(
452
0
             lef_subject->name,
453
0
             value_string,
454
0
             value_string_size - 1,
455
0
             LIBEWF_VALUE_DATA_TYPE_UTF8,
456
0
             error ) != 1 )
457
0
        {
458
0
          libcerror_error_set(
459
0
           error,
460
0
           LIBCERROR_ERROR_DOMAIN_IO,
461
0
           LIBCERROR_IO_ERROR_READ_FAILED,
462
0
           "%s: unable to read name string.",
463
0
           function );
464
465
0
          goto on_error;
466
0
        }
467
0
      }
468
0
    }
469
0
  }
470
#if defined( HAVE_DEBUG_OUTPUT )
471
  if( libcnotify_verbose != 0 )
472
  {
473
    libcnotify_printf(
474
     "\n" );
475
  }
476
#endif
477
0
  if( libfvalue_split_utf8_string_free(
478
0
       &values,
479
0
       error ) != 1 )
480
0
  {
481
0
    libcerror_error_set(
482
0
     error,
483
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
484
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
485
0
     "%s: unable to free split values.",
486
0
     function );
487
488
0
    goto on_error;
489
0
  }
490
0
  return( 1 );
491
492
0
on_error:
493
0
  if( values != NULL )
494
0
  {
495
0
    libfvalue_split_utf8_string_free(
496
0
     &values,
497
0
     NULL );
498
0
  }
499
0
  return( -1 );
500
0
}
501
502
/* Retrieves the identifier
503
 * Returns 1 if successful or -1 on error
504
 */
505
int libewf_lef_subject_get_identifier(
506
     libewf_lef_subject_t *lef_subject,
507
     uint32_t *identifier,
508
     libcerror_error_t **error )
509
0
{
510
0
  static char *function = "libewf_lef_subject_get_identifier";
511
512
0
  if( lef_subject == NULL )
513
0
  {
514
0
    libcerror_error_set(
515
0
     error,
516
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
517
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
518
0
     "%s: invalid subject.",
519
0
     function );
520
521
0
    return( -1 );
522
0
  }
523
0
  if( identifier == NULL )
524
0
  {
525
0
    libcerror_error_set(
526
0
     error,
527
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
528
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
529
0
     "%s: invalid identifier.",
530
0
     function );
531
532
0
    return( -1 );
533
0
  }
534
0
  *identifier = lef_subject->identifier;
535
536
0
  return( 1 );
537
0
}
538
539
/* Retrieves the size of the UTF-8 encoded name value
540
 * The returned size includes the end of string character
541
 * Returns 1 if successful or -1 on error
542
 */
543
int libewf_lef_subject_get_utf8_name_size(
544
     libewf_lef_subject_t *lef_subject,
545
     size_t *utf8_string_size,
546
     libcerror_error_t **error )
547
0
{
548
0
  static char *function = "libewf_lef_subject_get_utf8_name_size";
549
0
  int result            = 0;
550
551
0
  if( lef_subject == NULL )
552
0
  {
553
0
    libcerror_error_set(
554
0
     error,
555
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
556
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
557
0
     "%s: invalid subject.",
558
0
     function );
559
560
0
    return( -1 );
561
0
  }
562
0
  result = libewf_serialized_string_get_utf8_string_size(
563
0
            lef_subject->name,
564
0
            utf8_string_size,
565
0
            error );
566
567
0
  if( result == -1 )
568
0
  {
569
0
    libcerror_error_set(
570
0
     error,
571
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
572
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
573
0
     "%s: unable to retrieve name UTF-8 string size.",
574
0
     function );
575
576
0
    return( -1 );
577
0
  }
578
0
  return( 1 );
579
0
}
580
581
/* Retrieves the UTF-8 encoded name value
582
 * The size should include the end of string character
583
 * Returns 1 if successful or -1 on error
584
 */
585
int libewf_lef_subject_get_utf8_name(
586
     libewf_lef_subject_t *lef_subject,
587
     uint8_t *utf8_string,
588
     size_t utf8_string_size,
589
     libcerror_error_t **error )
590
0
{
591
0
  static char *function = "libewf_lef_subject_get_utf8_name";
592
0
  int result            = 0;
593
594
0
  if( lef_subject == NULL )
595
0
  {
596
0
    libcerror_error_set(
597
0
     error,
598
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
599
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
600
0
     "%s: invalid subject.",
601
0
     function );
602
603
0
    return( -1 );
604
0
  }
605
0
  result = libewf_serialized_string_get_utf8_string(
606
0
            lef_subject->name,
607
0
            utf8_string,
608
0
            utf8_string_size,
609
0
            error );
610
611
0
  if( result == -1 )
612
0
  {
613
0
    libcerror_error_set(
614
0
     error,
615
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
616
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
617
0
     "%s: unable to copy name to UTF-8 string.",
618
0
     function );
619
620
0
    return( -1 );
621
0
  }
622
0
  return( 1 );
623
0
}
624
625
/* Retrieves the size of the UTF-16 encoded name value
626
 * The returned size includes the end of string character
627
 * Returns 1 if successful or -1 on error
628
 */
629
int libewf_lef_subject_get_utf16_name_size(
630
     libewf_lef_subject_t *lef_subject,
631
     size_t *utf16_string_size,
632
     libcerror_error_t **error )
633
0
{
634
0
  static char *function = "libewf_lef_subject_get_utf16_name_size";
635
0
  int result            = 0;
636
637
0
  if( lef_subject == NULL )
638
0
  {
639
0
    libcerror_error_set(
640
0
     error,
641
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
642
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
643
0
     "%s: invalid subject.",
644
0
     function );
645
646
0
    return( -1 );
647
0
  }
648
0
  result = libewf_serialized_string_get_utf16_string_size(
649
0
            lef_subject->name,
650
0
            utf16_string_size,
651
0
            error );
652
653
0
  if( result == -1 )
654
0
  {
655
0
    libcerror_error_set(
656
0
     error,
657
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
658
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
659
0
     "%s: unable to retrieve name UTF-16 string size.",
660
0
     function );
661
662
0
    return( -1 );
663
0
  }
664
0
  return( 1 );
665
0
}
666
667
/* Retrieves the UTF-16 encoded name value
668
 * The size should include the end of string character
669
 * Returns 1 if successful or -1 on error
670
 */
671
int libewf_lef_subject_get_utf16_name(
672
     libewf_lef_subject_t *lef_subject,
673
     uint16_t *utf16_string,
674
     size_t utf16_string_size,
675
     libcerror_error_t **error )
676
0
{
677
0
  static char *function = "libewf_lef_subject_get_utf16_name";
678
0
  int result            = 0;
679
680
0
  if( lef_subject == NULL )
681
0
  {
682
0
    libcerror_error_set(
683
0
     error,
684
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
685
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
686
0
     "%s: invalid subject.",
687
0
     function );
688
689
0
    return( -1 );
690
0
  }
691
0
  result = libewf_serialized_string_get_utf16_string(
692
0
            lef_subject->name,
693
0
            utf16_string,
694
0
            utf16_string_size,
695
0
            error );
696
697
0
  if( result == -1 )
698
0
  {
699
0
    libcerror_error_set(
700
0
     error,
701
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
702
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
703
0
     "%s: unable to copy name to UTF-16 string.",
704
0
     function );
705
706
0
    return( -1 );
707
0
  }
708
0
  return( 1 );
709
0
}
710