Coverage Report

Created: 2024-02-25 07:20

/src/libpff/libpff/libpff_table_header.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Table header 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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libpff_debug.h"
28
#include "libpff_libcerror.h"
29
#include "libpff_libcnotify.h"
30
#include "libpff_table_header.h"
31
32
#include "pff_table.h"
33
34
/* Creates a table header
35
 * Make sure the value table_header is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libpff_table_header_initialize(
39
     libpff_table_header_t **table_header,
40
     libcerror_error_t **error )
41
6.78k
{
42
6.78k
  static char *function = "libpff_table_header_initialize";
43
44
6.78k
  if( table_header == 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 table_header.",
51
0
     function );
52
53
0
    return( -1 );
54
0
  }
55
6.78k
  if( *table_header != 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 table header value already set.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
6.78k
  *table_header = memory_allocate_structure(
67
6.78k
                   libpff_table_header_t );
68
69
6.78k
  if( *table_header == NULL )
70
0
  {
71
0
    libcerror_error_set(
72
0
     error,
73
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
74
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
75
0
     "%s: unable to create table header.",
76
0
     function );
77
78
0
    goto on_error;
79
0
  }
80
6.78k
  if( memory_set(
81
6.78k
       *table_header,
82
6.78k
       0,
83
6.78k
       sizeof( libpff_table_header_t ) ) == NULL )
84
0
  {
85
0
    libcerror_error_set(
86
0
     error,
87
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
88
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
89
0
     "%s: unable to clear table header.",
90
0
     function );
91
92
0
    goto on_error;
93
0
  }
94
6.78k
  return( 1 );
95
96
0
on_error:
97
0
  if( *table_header != NULL )
98
0
  {
99
0
    memory_free(
100
0
     *table_header );
101
102
0
    *table_header = NULL;
103
0
  }
104
0
  return( -1 );
105
6.78k
}
106
107
/* Frees a table header
108
 * Returns 1 if successful or -1 on error
109
 */
110
int libpff_table_header_free(
111
     libpff_table_header_t **table_header,
112
     libcerror_error_t **error )
113
6.78k
{
114
6.78k
  static char *function = "libpff_table_header_free";
115
116
6.78k
  if( table_header == NULL )
117
0
  {
118
0
    libcerror_error_set(
119
0
     error,
120
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
121
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
122
0
     "%s: invalid table header.",
123
0
     function );
124
125
0
    return( -1 );
126
0
  }
127
6.78k
  if( *table_header != NULL )
128
6.78k
  {
129
6.78k
    if( ( *table_header )->column_definitions_data != NULL )
130
2.30k
    {
131
2.30k
      memory_free(
132
2.30k
       ( *table_header )->column_definitions_data );
133
2.30k
    }
134
6.78k
    memory_free(
135
6.78k
     *table_header );
136
137
6.78k
    *table_header = NULL;
138
6.78k
  }
139
6.78k
  return( 1 );
140
6.78k
}
141
142
/* Reads the table header data
143
 * Returns 1 if successful or -1 on error
144
 */
145
int libpff_table_header_read_data(
146
     libpff_table_header_t *table_header,
147
     const uint8_t *data,
148
     size_t data_size,
149
     libcerror_error_t **error )
150
4.64k
{
151
4.64k
  static char *function = "libpff_table_header_read_data";
152
153
4.64k
  if( table_header == NULL )
154
0
  {
155
0
    libcerror_error_set(
156
0
     error,
157
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
158
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
159
0
     "%s: invalid table header.",
160
0
     function );
161
162
0
    return( -1 );
163
0
  }
164
4.64k
  if( data == NULL )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
169
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
170
0
     "%s: invalid data.",
171
0
     function );
172
173
0
    return( -1 );
174
0
  }
175
4.64k
  if( ( data_size < sizeof( pff_table_t ) )
176
4.64k
   || ( data_size > SSIZE_MAX ) )
177
0
  {
178
0
    libcerror_error_set(
179
0
     error,
180
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
181
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
182
0
     "%s: unsupported data size value out of bounds.",
183
0
     function );
184
185
0
    return( -1 );
186
0
  }
187
#if defined( HAVE_DEBUG_OUTPUT )
188
  if( libcnotify_verbose != 0 )
189
  {
190
    libcnotify_printf(
191
     "%s: table header data:\n",
192
     function );
193
    libcnotify_print_data(
194
     data,
195
     sizeof( pff_table_t ),
196
     0 );
197
  }
198
#endif
199
4.64k
  if( ( (pff_table_t *) data )->signature != 0xec )
200
152
  {
201
152
    libcerror_error_set(
202
152
     error,
203
152
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
204
152
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
205
152
     "%s: unsupported table signature: 0x%02" PRIx8 ".",
206
152
     function,
207
152
     ( (pff_table_t *) data )->signature );
208
209
152
    return( -1 );
210
152
  }
211
4.49k
  table_header->type = ( (pff_table_t *) data )->type;
212
213
4.49k
  byte_stream_copy_to_uint32_little_endian(
214
4.49k
   ( (pff_table_t *) data )->value_reference,
215
4.49k
   table_header->table_value_reference );
216
217
#if defined( HAVE_DEBUG_OUTPUT )
218
  if( libcnotify_verbose != 0 )
219
  {
220
    libcnotify_printf(
221
     "%s: table signature\t\t\t\t: 0x%02" PRIx8 "\n",
222
     function,
223
     ( (pff_table_t *) data )->signature );
224
225
    libcnotify_printf(
226
     "%s: table type\t\t\t\t: 0x%02" PRIx8 "\n",
227
     function,
228
     table_header->type );
229
230
    libcnotify_printf(
231
     "%s: table value reference\t\t\t: 0x%08" PRIx32 " (%s)\n",
232
     function,
233
     table_header->table_value_reference,
234
     libpff_debug_get_node_identifier_type(
235
      (uint8_t) ( table_header->table_value_reference & 0x0000001fUL ) ) );
236
  }
237
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
238
239
4.49k
  if( ( table_header->type != 0x6c )
240
4.49k
   && ( table_header->type != 0x7c )
241
4.49k
   && ( table_header->type != 0x8c )
242
4.49k
   && ( table_header->type != 0x9c )
243
4.49k
   && ( table_header->type != 0xa5 )
244
4.49k
   && ( table_header->type != 0xac )
245
4.49k
   && ( table_header->type != 0xbc ) )
246
138
  {
247
138
    libcerror_error_set(
248
138
     error,
249
138
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
250
138
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
251
138
     "%s: unsupported table type: 0x%02" PRIx8 ".",
252
138
     function,
253
138
     table_header->type );
254
255
138
    return( -1 );
256
138
  }
257
4.35k
  return( 1 );
258
4.49k
}
259
260
/* Reads the 6c table header data
261
 * Returns 1 if successful or -1 on error
262
 */
263
int libpff_table_header_read_6c_data(
264
     libpff_table_header_t *table_header,
265
     const uint8_t *data,
266
     size_t data_size,
267
     libcerror_error_t **error )
268
23
{
269
23
  static char *function = "libpff_table_header_read_6c_data";
270
271
23
  if( table_header == NULL )
272
0
  {
273
0
    libcerror_error_set(
274
0
     error,
275
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
276
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
277
0
     "%s: invalid table header.",
278
0
     function );
279
280
0
    return( -1 );
281
0
  }
282
23
  if( data == NULL )
283
0
  {
284
0
    libcerror_error_set(
285
0
     error,
286
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
287
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
288
0
     "%s: invalid data.",
289
0
     function );
290
291
0
    return( -1 );
292
0
  }
293
23
  if( data_size != 8 )
294
20
  {
295
20
    libcerror_error_set(
296
20
     error,
297
20
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
298
20
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
299
20
     "%s: unsupported data size: %" PRIzd ".",
300
20
     function,
301
20
     data_size );
302
303
20
    return( -1 );
304
20
  }
305
#if defined( HAVE_DEBUG_OUTPUT )
306
  if( libcnotify_verbose != 0 )
307
  {
308
    libcnotify_printf(
309
     "%s: 6c table header data:\n",
310
     function );
311
    libcnotify_print_data(
312
     data,
313
     data_size,
314
     0 );
315
  }
316
#endif
317
  /* The 6c table header contains no type indicator
318
   */
319
3
  byte_stream_copy_to_uint32_little_endian(
320
3
   data,
321
3
   table_header->b5_table_header_reference );
322
323
3
  byte_stream_copy_to_uint32_little_endian(
324
3
   &( data[ 4 ] ),
325
3
   table_header->values_array_reference );
326
327
#if defined( HAVE_DEBUG_OUTPUT )
328
  if( libcnotify_verbose != 0 )
329
  {
330
    libcnotify_printf(
331
     "%s: b5 table header reference\t\t: 0x%08" PRIx32 " (%s)\n",
332
     function,
333
     table_header->b5_table_header_reference,
334
     libpff_debug_get_node_identifier_type(
335
      (uint8_t) ( table_header->b5_table_header_reference & 0x0000001fUL ) ) );
336
337
    libcnotify_printf(
338
     "%s: values array reference\t\t: 0x%08" PRIx32 " (%s)\n",
339
     function,
340
     table_header->values_array_reference,
341
     libpff_debug_get_node_identifier_type(
342
      (uint8_t) ( table_header->values_array_reference & 0x0000001fUL ) ) );
343
  }
344
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
345
346
3
  return( 1 );
347
23
}
348
349
/* Reads the 7c table header data
350
 * Returns 1 if successful or -1 on error
351
 */
352
int libpff_table_header_read_7c_data(
353
     libpff_table_header_t *table_header,
354
     const uint8_t *data,
355
     size_t data_size,
356
     libcerror_error_t **error )
357
2.37k
{
358
2.37k
  static char *function               = "libpff_table_header_read_7c_data";
359
2.37k
  size_t column_definitions_data_size = 0;
360
2.37k
  size_t data_offset                  = 0;
361
362
#if defined( HAVE_DEBUG_OUTPUT )
363
  uint16_t value_16bit                = 0;
364
#endif
365
366
2.37k
  if( table_header == NULL )
367
0
  {
368
0
    libcerror_error_set(
369
0
     error,
370
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
371
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
372
0
     "%s: invalid table header.",
373
0
     function );
374
375
0
    return( -1 );
376
0
  }
377
2.37k
  if( table_header->column_definitions_data != NULL )
378
0
  {
379
0
    libcerror_error_set(
380
0
     error,
381
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
382
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
383
0
     "%s: invalid table header - column definitions data value already set.",
384
0
     function );
385
386
0
    return( -1 );
387
0
  }
388
2.37k
  if( data == NULL )
389
0
  {
390
0
    libcerror_error_set(
391
0
     error,
392
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
393
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
394
0
     "%s: invalid data.",
395
0
     function );
396
397
0
    return( -1 );
398
0
  }
399
2.37k
  if( ( data_size < sizeof( pff_table_header_7c_t ) )
400
2.37k
   || ( data_size > SSIZE_MAX ) )
401
16
  {
402
16
    libcerror_error_set(
403
16
     error,
404
16
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
405
16
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
406
16
     "%s: unsupported data size value out of bounds.",
407
16
     function );
408
409
16
    return( -1 );
410
16
  }
411
#if defined( HAVE_DEBUG_OUTPUT )
412
  if( libcnotify_verbose != 0 )
413
  {
414
    libcnotify_printf(
415
     "%s: 7c table header data:\n",
416
     function );
417
    libcnotify_print_data(
418
     data,
419
     sizeof( pff_table_header_7c_t ),
420
     0 );
421
  }
422
#endif
423
2.36k
  if( ( (pff_table_header_7c_t *) data )->type != 0x7c )
424
36
  {
425
36
    libcerror_error_set(
426
36
     error,
427
36
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
428
36
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
429
36
     "%s: unsupported table header type: 0x%02x.",
430
36
     function,
431
36
     ( (pff_table_header_7c_t *) data )->type );
432
433
36
    goto on_error;
434
36
  }
435
2.32k
  byte_stream_copy_to_uint16_little_endian(
436
2.32k
   ( (pff_table_header_7c_t *) data )->values_array_end_offset_cell_existence_block,
437
2.32k
   table_header->values_array_entry_size );
438
439
2.32k
  byte_stream_copy_to_uint32_little_endian(
440
2.32k
   ( (pff_table_header_7c_t *) data )->b5_table_header_reference,
441
2.32k
   table_header->b5_table_header_reference );
442
443
2.32k
  byte_stream_copy_to_uint32_little_endian(
444
2.32k
   ( (pff_table_header_7c_t *) data )->values_array_reference,
445
2.32k
   table_header->values_array_reference );
446
447
2.32k
  table_header->number_of_column_definitions = (int) ( (pff_table_header_7c_t *) data )->number_of_column_definitions;
448
449
#if defined( HAVE_DEBUG_OUTPUT )
450
  if( libcnotify_verbose != 0 )
451
  {
452
    libcnotify_printf(
453
     "%s: table header type\t\t\t\t: 0x%02" PRIx8 "\n",
454
     function,
455
     ( (pff_table_header_7c_t *) data )->type );
456
457
    libcnotify_printf(
458
     "%s: number of column definitions\t\t\t: %d\n",
459
     function,
460
     table_header->number_of_column_definitions );
461
462
    byte_stream_copy_to_uint16_little_endian(
463
     ( (pff_table_header_7c_t *) data )->values_array_end_offset_32bit_values,
464
     value_16bit );
465
    libcnotify_printf(
466
     "%s: values array end offset 32-bit values\t\t: %" PRIu16 "\n",
467
     function,
468
     value_16bit );
469
470
    byte_stream_copy_to_uint16_little_endian(
471
     ( (pff_table_header_7c_t *) data )->values_array_end_offset_16bit_values,
472
     value_16bit );
473
    libcnotify_printf(
474
     "%s: values array end offset 16-bit values\t\t: %" PRIu16 "\n",
475
     function,
476
     value_16bit );
477
478
    byte_stream_copy_to_uint16_little_endian(
479
     ( (pff_table_header_7c_t *) data )->values_array_end_offset_8bit_values,
480
     value_16bit );
481
    libcnotify_printf(
482
     "%s: values array end offset 8-bit values\t\t: %" PRIu16 "\n",
483
     function,
484
     value_16bit );
485
486
    byte_stream_copy_to_uint16_little_endian(
487
     ( (pff_table_header_7c_t *) data )->values_array_end_offset_cell_existence_block,
488
     value_16bit );
489
    libcnotify_printf(
490
     "%s: values array end offset cell existence block\t: %" PRIu16 "\n",
491
     function,
492
     value_16bit );
493
494
    libcnotify_printf(
495
     "%s: b5 table header reference\t\t\t: 0x%08" PRIx32 " (%s)\n",
496
     function,
497
     table_header->b5_table_header_reference,
498
     libpff_debug_get_node_identifier_type(
499
      (uint8_t) ( table_header->b5_table_header_reference & 0x0000001fUL ) ) );
500
501
    libcnotify_printf(
502
     "%s: values array reference\t\t\t: 0x%08" PRIx32 " (%s)\n",
503
     function,
504
     table_header->values_array_reference,
505
     libpff_debug_get_node_identifier_type(
506
      (uint8_t) ( table_header->values_array_reference & 0x0000001fUL ) ) );
507
508
    libcnotify_printf(
509
     "%s: unknown1:\n",
510
     function );
511
    libcnotify_print_data(
512
     ( (pff_table_header_7c_t *) data )->unknown1,
513
     4,
514
     0 );
515
  }
516
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
517
518
2.32k
  data_offset += sizeof( pff_table_header_7c_t );
519
520
2.32k
  column_definitions_data_size = data_size - sizeof( pff_table_header_7c_t );
521
522
2.32k
  if( ( column_definitions_data_size == 0 )
523
2.32k
   || ( column_definitions_data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
524
4
  {
525
4
    libcerror_error_set(
526
4
     error,
527
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
528
4
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
529
4
     "%s: invalid column definitions data size value out of bounds.",
530
4
     function );
531
532
4
    goto on_error;
533
4
  }
534
  /* Read the column definitions in the 7c table header
535
   */
536
2.32k
  if( (size_t) table_header->number_of_column_definitions != ( column_definitions_data_size / sizeof( pff_table_column_definition_7c_t ) ) )
537
23
  {
538
23
    libcerror_error_set(
539
23
     error,
540
23
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
541
23
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
542
23
     "%s: mismatch in number of the column definitions and data size.",
543
23
     function );
544
545
23
    goto on_error;
546
23
  }
547
#if defined( HAVE_DEBUG_OUTPUT )
548
  if( libcnotify_verbose != 0 )
549
  {
550
    libcnotify_printf(
551
     "%s: column definitions data:\n",
552
     function );
553
    libcnotify_print_data(
554
     &( data[ data_offset ] ),
555
     column_definitions_data_size,
556
     0 );
557
  }
558
#endif
559
  /* Copy the column definitions data otherwise the data block can cache out
560
   * while processing
561
   */
562
2.30k
  table_header->column_definitions_data = (uint8_t *) memory_allocate(
563
2.30k
                                                       column_definitions_data_size );
564
565
2.30k
  if( table_header->column_definitions_data == NULL )
566
0
  {
567
0
    libcerror_error_set(
568
0
     error,
569
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
570
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
571
0
     "%s: unable to create column definitions data.",
572
0
     function );
573
574
0
    goto on_error;
575
0
  }
576
2.30k
  if( memory_copy(
577
2.30k
       table_header->column_definitions_data,
578
2.30k
       &( data[ data_offset ] ),
579
2.30k
       column_definitions_data_size ) == NULL )
580
0
  {
581
0
    libcerror_error_set(
582
0
     error,
583
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
584
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
585
0
     "%s: unable to copy column definitions data.",
586
0
     function );
587
588
0
    goto on_error;
589
0
  }
590
2.30k
  table_header->column_definitions_data_size = column_definitions_data_size;
591
592
2.30k
  return( 1 );
593
594
63
on_error:
595
63
  if( table_header->column_definitions_data != NULL )
596
0
  {
597
0
    memory_free(
598
0
     table_header->column_definitions_data );
599
600
0
    table_header->column_definitions_data = NULL;
601
0
  }
602
63
  table_header->column_definitions_data_size = 0;
603
604
63
  return( -1 );
605
2.30k
}
606
607
/* Reads the 9c table header data
608
 * Returns 1 if successful or -1 on error
609
 */
610
int libpff_table_header_read_9c_data(
611
     libpff_table_header_t *table_header,
612
     const uint8_t *data,
613
     size_t data_size,
614
     libcerror_error_t **error )
615
24
{
616
24
  static char *function = "libpff_table_header_read_9c_data";
617
618
24
  if( table_header == NULL )
619
0
  {
620
0
    libcerror_error_set(
621
0
     error,
622
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
623
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
624
0
     "%s: invalid table header.",
625
0
     function );
626
627
0
    return( -1 );
628
0
  }
629
24
  if( data == NULL )
630
0
  {
631
0
    libcerror_error_set(
632
0
     error,
633
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
634
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
635
0
     "%s: invalid data.",
636
0
     function );
637
638
0
    return( -1 );
639
0
  }
640
24
  if( data_size != 4 )
641
22
  {
642
22
    libcerror_error_set(
643
22
     error,
644
22
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
645
22
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
646
22
     "%s: unsupported data size: %" PRIzd ".",
647
22
     function,
648
22
     data_size );
649
650
22
    return( -1 );
651
22
  }
652
#if defined( HAVE_DEBUG_OUTPUT )
653
  if( libcnotify_verbose != 0 )
654
  {
655
    libcnotify_printf(
656
     "%s: 9c table header data:\n",
657
     function );
658
    libcnotify_print_data(
659
     data,
660
     data_size,
661
     0 );
662
  }
663
#endif
664
  /* The 9c table header contains no type indicator
665
   */
666
2
  byte_stream_copy_to_uint32_little_endian(
667
2
   data,
668
2
   table_header->b5_table_header_reference );
669
670
#if defined( HAVE_DEBUG_OUTPUT )
671
  if( libcnotify_verbose != 0 )
672
  {
673
    libcnotify_printf(
674
     "%s: b5 table header reference\t\t: 0x%08" PRIx32 " (%s)\n",
675
     function,
676
     table_header->b5_table_header_reference,
677
     libpff_debug_get_node_identifier_type(
678
      (uint8_t) ( table_header->b5_table_header_reference & 0x0000001fUL ) ) );
679
  }
680
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
681
682
2
  return( 1 );
683
24
}
684
685
/* Reads the ac table header data
686
 * Returns 1 if successful or -1 on error
687
 */
688
int libpff_table_header_read_ac_data(
689
     libpff_table_header_t *table_header,
690
     const uint8_t *data,
691
     size_t data_size,
692
     libcerror_error_t **error )
693
65
{
694
65
  static char *function = "libpff_table_header_read_ac_data";
695
696
#if defined( HAVE_DEBUG_OUTPUT )
697
  uint16_t value_16bit  = 0;
698
#endif
699
700
65
  if( table_header == NULL )
701
0
  {
702
0
    libcerror_error_set(
703
0
     error,
704
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
705
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
706
0
     "%s: invalid table header.",
707
0
     function );
708
709
0
    return( -1 );
710
0
  }
711
65
  if( data == NULL )
712
0
  {
713
0
    libcerror_error_set(
714
0
     error,
715
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
716
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
717
0
     "%s: invalid data.",
718
0
     function );
719
720
0
    return( -1 );
721
0
  }
722
65
  if( ( data_size < sizeof( pff_table_header_ac_t ) )
723
65
   || ( data_size > SSIZE_MAX ) )
724
18
  {
725
18
    libcerror_error_set(
726
18
     error,
727
18
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
728
18
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
729
18
     "%s: unsupported data size value out of bounds.",
730
18
     function );
731
732
18
    return( -1 );
733
18
  }
734
#if defined( HAVE_DEBUG_OUTPUT )
735
  if( libcnotify_verbose != 0 )
736
  {
737
    libcnotify_printf(
738
     "%s: ac table header data:\n",
739
     function );
740
    libcnotify_print_data(
741
     data,
742
     sizeof( pff_table_header_ac_t ),
743
     0 );
744
  }
745
#endif
746
47
  if( ( (pff_table_header_ac_t *) data )->type != 0xac )
747
42
  {
748
42
    libcerror_error_set(
749
42
     error,
750
42
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
751
42
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
752
42
     "%s: unsupported table header type: 0x%02x.",
753
42
     function,
754
42
     ( (pff_table_header_ac_t *) data )->type );
755
756
42
    return( -1 );
757
42
  }
758
5
  byte_stream_copy_to_uint16_little_endian(
759
5
   ( (pff_table_header_ac_t *) data )->values_array_end_offset_cell_existence_block,
760
5
   table_header->values_array_entry_size );
761
762
5
  byte_stream_copy_to_uint32_little_endian(
763
5
   ( (pff_table_header_ac_t *) data )->b5_table_header_reference,
764
5
   table_header->b5_table_header_reference );
765
766
5
  byte_stream_copy_to_uint32_little_endian(
767
5
   ( (pff_table_header_ac_t *) data )->values_array_reference,
768
5
   table_header->values_array_reference );
769
770
5
  byte_stream_copy_to_uint16_little_endian(
771
5
   ( (pff_table_header_ac_t *) data )->number_of_column_definitions,
772
5
   table_header->number_of_column_definitions );
773
774
5
  byte_stream_copy_to_uint32_little_endian(
775
5
   ( (pff_table_header_ac_t *) data )->column_definitions_reference,
776
5
   table_header->column_definitions_reference );
777
778
#if defined( HAVE_DEBUG_OUTPUT )
779
  if( libcnotify_verbose != 0 )
780
  {
781
    libcnotify_printf(
782
     "%s: table header type\t\t\t\t: 0x%02" PRIx8 "\n",
783
     function,
784
     ( (pff_table_header_ac_t *) data )->type );
785
786
    libcnotify_printf(
787
     "%s: padding1\t\t\t\t\t: 0x%02" PRIx8 "\n",
788
     function,
789
     ( (pff_table_header_ac_t *) data )->padding1 );
790
791
    byte_stream_copy_to_uint16_little_endian(
792
     ( (pff_table_header_ac_t *) data )->values_array_end_offset_32bit_values,
793
     value_16bit );
794
    libcnotify_printf(
795
     "%s: values array end offset 32-bit values\t\t: %" PRIu16 "\n",
796
     function,
797
     value_16bit );
798
799
    byte_stream_copy_to_uint16_little_endian(
800
     ( (pff_table_header_ac_t *) data )->values_array_end_offset_16bit_values,
801
     value_16bit );
802
    libcnotify_printf(
803
     "%s: values array end offset 16-bit values\t\t: %" PRIu16 "\n",
804
     function,
805
     value_16bit );
806
807
    byte_stream_copy_to_uint16_little_endian(
808
     ( (pff_table_header_ac_t *) data )->values_array_end_offset_8bit_values,
809
     value_16bit );
810
    libcnotify_printf(
811
     "%s: values array end offset 8-bit values\t\t: %" PRIu16 "\n",
812
     function,
813
     value_16bit );
814
815
    byte_stream_copy_to_uint16_little_endian(
816
     ( (pff_table_header_ac_t *) data )->values_array_end_offset_cell_existence_block,
817
     value_16bit );
818
    libcnotify_printf(
819
     "%s: values array end offset cell existence block\t: %" PRIu16 "\n",
820
     function,
821
     value_16bit );
822
823
    libcnotify_printf(
824
     "%s: b5 table header reference\t\t\t: 0x%08" PRIx32 " (%s)\n",
825
     function,
826
     table_header->b5_table_header_reference,
827
     libpff_debug_get_node_identifier_type(
828
      (uint8_t) ( table_header->b5_table_header_reference & 0x0000001fUL ) ) );
829
830
    libcnotify_printf(
831
     "%s: values array reference\t\t\t: 0x%08" PRIx32 " (%s)\n",
832
     function,
833
     table_header->values_array_reference,
834
     libpff_debug_get_node_identifier_type(
835
      (uint8_t) ( table_header->values_array_reference & 0x0000001fUL ) ) );
836
837
    libcnotify_printf(
838
     "%s: padding2:\n",
839
     function );
840
    libcnotify_print_data(
841
     ( (pff_table_header_ac_t *) data )->padding2,
842
     4,
843
     0 );
844
845
    libcnotify_printf(
846
     "%s: number of column definitions\t\t\t: %d\n",
847
     function,
848
     table_header->number_of_column_definitions );
849
850
    libcnotify_printf(
851
     "%s: column definitions reference\t\t\t: 0x%08" PRIx32 " (%s)\n",
852
     function,
853
     table_header->column_definitions_reference,
854
     libpff_debug_get_node_identifier_type(
855
      (uint8_t) ( table_header->column_definitions_reference & 0x0000001fUL ) ) );
856
857
    libcnotify_printf(
858
     "%s: unknown2:\n",
859
     function );
860
    libcnotify_print_data(
861
     ( (pff_table_header_ac_t *) data )->unknown2,
862
     12,
863
     0 );
864
  }
865
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
866
867
5
  return( 1 );
868
47
}
869
870
/* Reads the b5 table header data
871
 * Returns 1 if successful or -1 on error
872
 */
873
int libpff_table_header_read_b5_data(
874
     libpff_table_header_t *table_header,
875
     const uint8_t *data,
876
     size_t data_size,
877
     libcerror_error_t **error )
878
3.63k
{
879
3.63k
  static char *function = "libpff_table_header_read_b5_data";
880
881
3.63k
  if( table_header == NULL )
882
0
  {
883
0
    libcerror_error_set(
884
0
     error,
885
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
886
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
887
0
     "%s: invalid table header.",
888
0
     function );
889
890
0
    return( -1 );
891
0
  }
892
3.63k
  if( data == NULL )
893
0
  {
894
0
    libcerror_error_set(
895
0
     error,
896
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
897
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
898
0
     "%s: invalid data.",
899
0
     function );
900
901
0
    return( -1 );
902
0
  }
903
3.63k
  if( data_size != sizeof( pff_table_header_b5_t ) )
904
30
  {
905
30
    libcerror_error_set(
906
30
     error,
907
30
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
908
30
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
909
30
     "%s: unsupported data size: %" PRIzd ".",
910
30
     function,
911
30
     data_size );
912
913
30
    return( -1 );
914
30
  }
915
#if defined( HAVE_DEBUG_OUTPUT )
916
  if( libcnotify_verbose != 0 )
917
  {
918
    libcnotify_printf(
919
     "%s: b5 table header data:\n",
920
     function );
921
    libcnotify_print_data(
922
     data,
923
     sizeof( pff_table_header_b5_t ),
924
     0 );
925
  }
926
#endif
927
3.60k
  if( ( (pff_table_header_b5_t *) data )->type != 0xb5 )
928
22
  {
929
22
    libcerror_error_set(
930
22
     error,
931
22
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
932
22
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
933
22
     "%s: unsupported table header type: 0x%02x.",
934
22
     function,
935
22
     ( (pff_table_header_b5_t *) data )->type );
936
937
22
    return( -1 );
938
22
  }
939
3.58k
  table_header->record_entry_identifier_size = ( (pff_table_header_b5_t *) data )->record_entry_identifier_size;
940
3.58k
  table_header->record_entry_value_size      = ( (pff_table_header_b5_t *) data )->record_entry_value_size;
941
3.58k
  table_header->record_entries_level         = ( (pff_table_header_b5_t *) data )->record_entries_level;
942
943
3.58k
  byte_stream_copy_to_uint32_little_endian(
944
3.58k
   ( (pff_table_header_b5_t *) data )->record_entries_reference,
945
3.58k
   table_header->record_entries_reference );
946
947
#if defined( HAVE_DEBUG_OUTPUT )
948
  if( libcnotify_verbose != 0 )
949
  {
950
    libcnotify_printf(
951
     "%s: table header type\t\t\t: 0x%02" PRIx8 "\n",
952
     function,
953
     ( (pff_table_header_b5_t *) data )->type );
954
955
    libcnotify_printf(
956
     "%s: record entry identifier size\t\t: %" PRIu8 "\n",
957
     function,
958
     table_header->record_entry_identifier_size );
959
960
    libcnotify_printf(
961
     "%s: record entry value size\t\t: %" PRIu8 "\n",
962
     function,
963
     table_header->record_entry_value_size );
964
965
    libcnotify_printf(
966
     "%s: record entries level\t\t\t: %" PRIu8 "\n",
967
     function,
968
     ( (pff_table_header_b5_t *) data )->record_entries_level );
969
970
    libcnotify_printf(
971
     "%s: record entries reference\t\t: 0x%08" PRIx32 " (%s)\n",
972
     function,
973
     table_header->record_entries_reference,
974
     libpff_debug_get_node_identifier_type(
975
      (uint8_t) ( table_header->record_entries_reference & 0x0000001fUL ) ) );
976
977
    libcnotify_printf(
978
     "\n" );
979
  }
980
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
981
982
3.58k
  return( 1 );
983
3.60k
}
984