Coverage Report

Created: 2025-10-14 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libpff/libpff/libpff_table_header.c
Line
Count
Source
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
7.03k
{
42
7.03k
  static char *function = "libpff_table_header_initialize";
43
44
7.03k
  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
7.03k
  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
7.03k
  *table_header = memory_allocate_structure(
67
7.03k
                   libpff_table_header_t );
68
69
7.03k
  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
7.03k
  if( memory_set(
81
7.03k
       *table_header,
82
7.03k
       0,
83
7.03k
       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
7.03k
  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
7.03k
}
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
7.03k
{
114
7.03k
  static char *function = "libpff_table_header_free";
115
116
7.03k
  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
7.03k
  if( *table_header != NULL )
128
7.03k
  {
129
7.03k
    if( ( *table_header )->column_definitions_data != NULL )
130
2.60k
    {
131
2.60k
      memory_free(
132
2.60k
       ( *table_header )->column_definitions_data );
133
2.60k
    }
134
7.03k
    memory_free(
135
7.03k
     *table_header );
136
137
7.03k
    *table_header = NULL;
138
7.03k
  }
139
7.03k
  return( 1 );
140
7.03k
}
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.75k
{
151
4.75k
  static char *function = "libpff_table_header_read_data";
152
153
4.75k
  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.75k
  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.75k
  if( ( data_size < sizeof( pff_table_t ) )
176
4.75k
   || ( 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.75k
  if( ( (pff_table_t *) data )->signature != 0xec )
200
192
  {
201
192
    libcerror_error_set(
202
192
     error,
203
192
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
204
192
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
205
192
     "%s: unsupported table signature: 0x%02" PRIx8 ".",
206
192
     function,
207
192
     ( (pff_table_t *) data )->signature );
208
209
192
    return( -1 );
210
192
  }
211
4.56k
  table_header->type = ( (pff_table_t *) data )->type;
212
213
4.56k
  byte_stream_copy_to_uint32_little_endian(
214
4.56k
   ( (pff_table_t *) data )->value_reference,
215
4.56k
   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.56k
  if( ( table_header->type != 0x6c )
240
4.51k
   && ( table_header->type != 0x7c )
241
1.77k
   && ( table_header->type != 0x8c )
242
1.63k
   && ( table_header->type != 0x9c )
243
1.58k
   && ( table_header->type != 0xa5 )
244
1.34k
   && ( table_header->type != 0xac )
245
1.28k
   && ( table_header->type != 0xbc ) )
246
134
  {
247
134
    libcerror_error_set(
248
134
     error,
249
134
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
250
134
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
251
134
     "%s: unsupported table type: 0x%02" PRIx8 ".",
252
134
     function,
253
134
     table_header->type );
254
255
134
    return( -1 );
256
134
  }
257
4.43k
  return( 1 );
258
4.56k
}
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
26
{
269
26
  static char *function = "libpff_table_header_read_6c_data";
270
271
26
  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
26
  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
26
  if( data_size != 8 )
294
18
  {
295
18
    libcerror_error_set(
296
18
     error,
297
18
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
298
18
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
299
18
     "%s: unsupported data size: %" PRIzd ".",
300
18
     function,
301
18
     data_size );
302
303
18
    return( -1 );
304
18
  }
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
8
  byte_stream_copy_to_uint32_little_endian(
320
8
   data,
321
8
   table_header->b5_table_header_reference );
322
323
8
  byte_stream_copy_to_uint32_little_endian(
324
8
   &( data[ 4 ] ),
325
8
   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
8
  return( 1 );
347
26
}
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.70k
{
358
2.70k
  static char *function               = "libpff_table_header_read_7c_data";
359
2.70k
  size_t column_definitions_data_size = 0;
360
2.70k
  size_t data_offset                  = 0;
361
362
#if defined( HAVE_DEBUG_OUTPUT )
363
  uint16_t value_16bit                = 0;
364
#endif
365
366
2.70k
  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.70k
  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.70k
  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.70k
  if( ( data_size < sizeof( pff_table_header_7c_t ) )
400
2.68k
   || ( data_size > SSIZE_MAX ) )
401
13
  {
402
13
    libcerror_error_set(
403
13
     error,
404
13
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
405
13
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
406
13
     "%s: unsupported data size value out of bounds.",
407
13
     function );
408
409
13
    return( -1 );
410
13
  }
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.68k
  if( ( (pff_table_header_7c_t *) data )->type != 0x7c )
424
31
  {
425
31
    libcerror_error_set(
426
31
     error,
427
31
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
428
31
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
429
31
     "%s: unsupported table header type: 0x%02x.",
430
31
     function,
431
31
     ( (pff_table_header_7c_t *) data )->type );
432
433
31
    goto on_error;
434
31
  }
435
2.65k
  byte_stream_copy_to_uint16_little_endian(
436
2.65k
   ( (pff_table_header_7c_t *) data )->values_array_end_offset_cell_existence_block,
437
2.65k
   table_header->values_array_entry_size );
438
439
2.65k
  byte_stream_copy_to_uint32_little_endian(
440
2.65k
   ( (pff_table_header_7c_t *) data )->b5_table_header_reference,
441
2.65k
   table_header->b5_table_header_reference );
442
443
2.65k
  byte_stream_copy_to_uint32_little_endian(
444
2.65k
   ( (pff_table_header_7c_t *) data )->values_array_reference,
445
2.65k
   table_header->values_array_reference );
446
447
2.65k
  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.65k
  data_offset += sizeof( pff_table_header_7c_t );
519
520
2.65k
  column_definitions_data_size = data_size - sizeof( pff_table_header_7c_t );
521
522
2.65k
  if( ( column_definitions_data_size == 0 )
523
2.65k
   || ( column_definitions_data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
524
3
  {
525
3
    libcerror_error_set(
526
3
     error,
527
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
528
3
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
529
3
     "%s: invalid column definitions data size value out of bounds.",
530
3
     function );
531
532
3
    goto on_error;
533
3
  }
534
  /* Read the column definitions in the 7c table header
535
   */
536
2.65k
  if( (size_t) table_header->number_of_column_definitions != ( column_definitions_data_size / sizeof( pff_table_column_definition_7c_t ) ) )
537
48
  {
538
48
    libcerror_error_set(
539
48
     error,
540
48
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
541
48
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
542
48
     "%s: mismatch in number of the column definitions and data size.",
543
48
     function );
544
545
48
    goto on_error;
546
48
  }
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.60k
  table_header->column_definitions_data = (uint8_t *) memory_allocate(
563
2.60k
                                                       column_definitions_data_size );
564
565
2.60k
  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.60k
  if( memory_copy(
577
2.60k
       table_header->column_definitions_data,
578
2.60k
       &( data[ data_offset ] ),
579
2.60k
       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.60k
  table_header->column_definitions_data_size = column_definitions_data_size;
591
592
2.60k
  return( 1 );
593
594
82
on_error:
595
82
  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
82
  table_header->column_definitions_data_size = 0;
603
604
82
  return( -1 );
605
2.60k
}
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
10
{
616
10
  static char *function = "libpff_table_header_read_9c_data";
617
618
10
  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
10
  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
10
  if( data_size != 4 )
641
7
  {
642
7
    libcerror_error_set(
643
7
     error,
644
7
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
645
7
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
646
7
     "%s: unsupported data size: %" PRIzd ".",
647
7
     function,
648
7
     data_size );
649
650
7
    return( -1 );
651
7
  }
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
3
  byte_stream_copy_to_uint32_little_endian(
667
3
   data,
668
3
   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
3
  return( 1 );
683
10
}
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
28
{
694
28
  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
28
  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
28
  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
28
  if( ( data_size < sizeof( pff_table_header_ac_t ) )
723
23
   || ( data_size > SSIZE_MAX ) )
724
5
  {
725
5
    libcerror_error_set(
726
5
     error,
727
5
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
728
5
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
729
5
     "%s: unsupported data size value out of bounds.",
730
5
     function );
731
732
5
    return( -1 );
733
5
  }
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
23
  if( ( (pff_table_header_ac_t *) data )->type != 0xac )
747
19
  {
748
19
    libcerror_error_set(
749
19
     error,
750
19
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
751
19
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
752
19
     "%s: unsupported table header type: 0x%02x.",
753
19
     function,
754
19
     ( (pff_table_header_ac_t *) data )->type );
755
756
19
    return( -1 );
757
19
  }
758
4
  byte_stream_copy_to_uint16_little_endian(
759
4
   ( (pff_table_header_ac_t *) data )->values_array_end_offset_cell_existence_block,
760
4
   table_header->values_array_entry_size );
761
762
4
  byte_stream_copy_to_uint32_little_endian(
763
4
   ( (pff_table_header_ac_t *) data )->b5_table_header_reference,
764
4
   table_header->b5_table_header_reference );
765
766
4
  byte_stream_copy_to_uint32_little_endian(
767
4
   ( (pff_table_header_ac_t *) data )->values_array_reference,
768
4
   table_header->values_array_reference );
769
770
4
  byte_stream_copy_to_uint16_little_endian(
771
4
   ( (pff_table_header_ac_t *) data )->number_of_column_definitions,
772
4
   table_header->number_of_column_definitions );
773
774
4
  byte_stream_copy_to_uint32_little_endian(
775
4
   ( (pff_table_header_ac_t *) data )->column_definitions_reference,
776
4
   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
4
  return( 1 );
868
23
}
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.73k
{
879
3.73k
  static char *function = "libpff_table_header_read_b5_data";
880
881
3.73k
  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.73k
  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.73k
  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.70k
  if( ( (pff_table_header_b5_t *) data )->type != 0xb5 )
928
29
  {
929
29
    libcerror_error_set(
930
29
     error,
931
29
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
932
29
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
933
29
     "%s: unsupported table header type: 0x%02x.",
934
29
     function,
935
29
     ( (pff_table_header_b5_t *) data )->type );
936
937
29
    return( -1 );
938
29
  }
939
3.67k
  table_header->record_entry_identifier_size = ( (pff_table_header_b5_t *) data )->record_entry_identifier_size;
940
3.67k
  table_header->record_entry_value_size      = ( (pff_table_header_b5_t *) data )->record_entry_value_size;
941
3.67k
  table_header->record_entries_level         = ( (pff_table_header_b5_t *) data )->record_entries_level;
942
943
3.67k
  byte_stream_copy_to_uint32_little_endian(
944
3.67k
   ( (pff_table_header_b5_t *) data )->record_entries_reference,
945
3.67k
   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.67k
  return( 1 );
983
3.70k
}
984