Coverage Report

Created: 2025-06-13 07:22

/src/libfshfs/libfshfs/libfshfs_allocation_block_stream.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Allocation block stream functions
3
 *
4
 * Copyright (C) 2009-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 <types.h>
24
25
#include "libfshfs_allocation_block_stream.h"
26
#include "libfshfs_block_data_handle.h"
27
#include "libfshfs_buffer_data_handle.h"
28
#include "libfshfs_compressed_data_handle.h"
29
#include "libfshfs_compressed_data_header.h"
30
#include "libfshfs_extent.h"
31
#include "libfshfs_io_handle.h"
32
#include "libfshfs_libcdata.h"
33
#include "libfshfs_libfdata.h"
34
35
/* Creates an allocation block stream from a buffer of data
36
 * Make sure the value allocation_block_stream is referencing, is set to NULL
37
 * Returns 1 if successful or -1 on error
38
 */
39
int libfshfs_allocation_block_stream_initialize_from_data(
40
     libfdata_stream_t **allocation_block_stream,
41
     const uint8_t *data,
42
     size_t data_size,
43
     libcerror_error_t **error )
44
0
{
45
0
  libfdata_stream_t *safe_allocation_block_stream = NULL;
46
0
  libfshfs_buffer_data_handle_t *data_handle      = NULL;
47
0
  static char *function                           = "libfshfs_allocation_block_stream_initialize_from_data";
48
0
  int segment_index                               = 0;
49
50
0
  if( allocation_block_stream == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid allocation block stream.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
0
  if( libfshfs_buffer_data_handle_initialize(
62
0
       &data_handle,
63
0
       data,
64
0
       data_size,
65
0
       error ) != 1 )
66
0
  {
67
0
    libcerror_error_set(
68
0
     error,
69
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
70
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
71
0
     "%s: unable to create buffer data handle.",
72
0
     function );
73
74
0
    goto on_error;
75
0
  }
76
0
  if( libfdata_stream_initialize(
77
0
       &safe_allocation_block_stream,
78
0
       (intptr_t *) data_handle,
79
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfshfs_buffer_data_handle_free,
80
0
       NULL,
81
0
       NULL,
82
0
       (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libfshfs_buffer_data_handle_read_segment_data,
83
0
       NULL,
84
0
       (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libfshfs_buffer_data_handle_seek_segment_offset,
85
0
       LIBFDATA_DATA_HANDLE_FLAG_MANAGED,
86
0
       error ) != 1 )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
91
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
92
0
     "%s: unable to create allocation block stream.",
93
0
     function );
94
95
0
    goto on_error;
96
0
  }
97
0
  data_handle = NULL;
98
99
0
  if( libfdata_stream_append_segment(
100
0
       safe_allocation_block_stream,
101
0
       &segment_index,
102
0
       0,
103
0
       0,
104
0
       (size64_t) data_size,
105
0
       0,
106
0
       error ) != 1 )
107
0
  {
108
0
    libcerror_error_set(
109
0
     error,
110
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
111
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
112
0
     "%s: unable to append allocation block stream segment.",
113
0
     function );
114
115
0
    goto on_error;
116
0
  }
117
0
  *allocation_block_stream = safe_allocation_block_stream;
118
119
0
  return( 1 );
120
121
0
on_error:
122
0
  if( safe_allocation_block_stream != NULL )
123
0
  {
124
0
    libfdata_stream_free(
125
0
     &safe_allocation_block_stream,
126
0
     NULL );
127
0
  }
128
0
  if( data_handle != NULL )
129
0
  {
130
0
    libfshfs_buffer_data_handle_free(
131
0
     &data_handle,
132
0
     NULL );
133
0
  }
134
0
  return( -1 );
135
0
}
136
137
/* Creates an allocation block stream from a fork descriptor
138
 * Make sure the value allocation_block is referencing, is set to NULL
139
 * Returns 1 if successful or -1 on error
140
 */
141
int libfshfs_allocation_block_stream_initialize_from_fork_descriptor(
142
     libfdata_stream_t **allocation_block_stream,
143
     libfshfs_io_handle_t *io_handle,
144
     libfshfs_fork_descriptor_t *fork_descriptor,
145
     libcerror_error_t **error )
146
408
{
147
408
  libfdata_stream_t *safe_allocation_block_stream = NULL;
148
408
  static char *function                           = "libfshfs_allocation_block_stream_initialize_from_fork_descriptor";
149
408
  size64_t segment_size                           = 0;
150
408
  off64_t segment_offset                          = 0;
151
408
  int extent_index                                = 0;
152
408
  int result                                      = 0;
153
408
  int segment_index                               = 0;
154
155
408
  if( allocation_block_stream == NULL )
156
0
  {
157
0
    libcerror_error_set(
158
0
     error,
159
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
160
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
161
0
     "%s: invalid allocation block stream.",
162
0
     function );
163
164
0
    return( -1 );
165
0
  }
166
408
  if( io_handle == NULL )
167
0
  {
168
0
    libcerror_error_set(
169
0
     error,
170
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
171
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
172
0
     "%s: invalid IO handle.",
173
0
     function );
174
175
0
    return( -1 );
176
0
  }
177
408
  if( io_handle->block_size == 0 )
178
0
  {
179
0
    libcerror_error_set(
180
0
     error,
181
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
182
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
183
0
     "%s: invalid IO handle - block size value out of bounds.",
184
0
     function );
185
186
0
    return( -1 );
187
0
  }
188
408
  if( fork_descriptor == NULL )
189
0
  {
190
0
    libcerror_error_set(
191
0
     error,
192
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
193
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
194
0
     "%s: invalid fork descriptor.",
195
0
     function );
196
197
0
    return( -1 );
198
0
  }
199
408
  result = libfshfs_fork_descriptor_has_extents_overflow(
200
408
            fork_descriptor,
201
408
            error );
202
203
408
  if( result == -1 )
204
0
  {
205
0
    libcerror_error_set(
206
0
     error,
207
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
208
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
209
0
     "%s: unable to determine if fork descriptor has extents overflow.",
210
0
     function );
211
212
0
    goto on_error;
213
0
  }
214
408
  else if( result != 0 )
215
12
  {
216
12
    libcerror_error_set(
217
12
     error,
218
12
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
219
12
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
220
12
     "%s: unsupported fork descriptor has extents overflow.",
221
12
     function );
222
223
12
    goto on_error;
224
12
  }
225
396
  if( libfdata_stream_initialize(
226
396
       &safe_allocation_block_stream,
227
396
       NULL,
228
396
       NULL,
229
396
       NULL,
230
396
       NULL,
231
396
       (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libfshfs_block_data_handle_read_segment_data,
232
396
       NULL,
233
396
       (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libfshfs_block_data_handle_seek_segment_offset,
234
396
       0,
235
396
       error ) != 1 )
236
0
  {
237
0
    libcerror_error_set(
238
0
     error,
239
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
240
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
241
0
     "%s: unable to create allocation block stream.",
242
0
     function );
243
244
0
    goto on_error;
245
0
  }
246
396
  for( extent_index = 0;
247
2.35k
       extent_index < 8;
248
1.96k
       extent_index++ )
249
2.20k
  {
250
2.20k
    segment_offset = fork_descriptor->extents[ extent_index ][ 0 ];
251
2.20k
    segment_size   = fork_descriptor->extents[ extent_index ][ 1 ];
252
253
2.20k
    if( ( segment_offset == 0 )
254
2.20k
     || ( segment_size == 0 ) )
255
194
    {
256
194
      break;
257
194
    }
258
2.01k
    if( segment_offset > ( (off64_t) INT64_MAX / io_handle->block_size ) )
259
10
    {
260
10
      libcerror_error_set(
261
10
       error,
262
10
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
263
10
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
264
10
       "%s: invalid segment offset value out of bounds.",
265
10
       function );
266
267
10
      goto on_error;
268
10
    }
269
2.00k
    if( segment_size > ( (size64_t) UINT64_MAX / io_handle->block_size ) )
270
0
    {
271
0
      libcerror_error_set(
272
0
       error,
273
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
274
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
275
0
       "%s: invalid segment size value out of bounds.",
276
0
       function );
277
278
0
      goto on_error;
279
0
    }
280
2.00k
    segment_offset *= io_handle->block_size;
281
2.00k
    segment_size   *= io_handle->block_size;
282
283
2.00k
    if( libfdata_stream_append_segment(
284
2.00k
         safe_allocation_block_stream,
285
2.00k
         &segment_index,
286
2.00k
         0,
287
2.00k
         segment_offset,
288
2.00k
         segment_size,
289
2.00k
         0,
290
2.00k
         error ) != 1 )
291
44
    {
292
44
      libcerror_error_set(
293
44
       error,
294
44
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
295
44
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
296
44
       "%s: unable to append extent: %d allocation block stream segment.",
297
44
       function,
298
44
       extent_index );
299
300
44
      goto on_error;
301
44
    }
302
2.00k
  }
303
342
  if( libfdata_stream_set_mapped_size(
304
342
       safe_allocation_block_stream,
305
342
       (size64_t) fork_descriptor->size,
306
342
       error ) != 1 )
307
38
  {
308
38
    libcerror_error_set(
309
38
     error,
310
38
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
311
38
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
312
38
     "%s: unable to set mapped size of allocation block stream.",
313
38
     function );
314
315
38
    goto on_error;
316
38
  }
317
304
  *allocation_block_stream = safe_allocation_block_stream;
318
319
304
  return( 1 );
320
321
104
on_error:
322
104
  if( safe_allocation_block_stream != NULL )
323
92
  {
324
92
    libfdata_stream_free(
325
92
     &safe_allocation_block_stream,
326
92
     NULL );
327
92
  }
328
104
  return( -1 );
329
342
}
330
331
/* Creates an allocation block stream from extents
332
 * Make sure the value allocation_block_stream is referencing, is set to NULL
333
 * Returns 1 if successful or -1 on error
334
 */
335
int libfshfs_allocation_block_stream_initialize_from_extents(
336
     libfdata_stream_t **allocation_block_stream,
337
     libfshfs_io_handle_t *io_handle,
338
     libcdata_array_t *extents,
339
     size64_t data_size,
340
     libcerror_error_t **error )
341
388
{
342
388
  libfdata_stream_t *safe_allocation_block_stream = NULL;
343
388
  libfshfs_extent_t *extent                       = NULL;
344
388
  static char *function                           = "libfshfs_allocation_block_stream_initialize_from_extents";
345
388
  size64_t segment_size                           = 0;
346
388
  off64_t segment_offset                          = 0;
347
388
  int extent_index                                = 0;
348
388
  int number_of_extents                           = 0;
349
388
  int segment_index                               = 0;
350
351
388
  if( allocation_block_stream == NULL )
352
0
  {
353
0
    libcerror_error_set(
354
0
     error,
355
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
356
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
357
0
     "%s: invalid allocation block stream.",
358
0
     function );
359
360
0
    return( -1 );
361
0
  }
362
388
  if( io_handle == NULL )
363
0
  {
364
0
    libcerror_error_set(
365
0
     error,
366
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
367
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
368
0
     "%s: invalid IO handle.",
369
0
     function );
370
371
0
    return( -1 );
372
0
  }
373
388
  if( io_handle->block_size == 0 )
374
0
  {
375
0
    libcerror_error_set(
376
0
     error,
377
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
378
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
379
0
     "%s: invalid IO handle - block size value out of bounds.",
380
0
     function );
381
382
0
    return( -1 );
383
0
  }
384
388
  if( libcdata_array_get_number_of_entries(
385
388
       extents,
386
388
       &number_of_extents,
387
388
       error ) != 1 )
388
0
  {
389
0
    libcerror_error_set(
390
0
     error,
391
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
392
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
393
0
     "%s: unable to retrieve number of extents.",
394
0
     function );
395
396
0
    goto on_error;
397
0
  }
398
388
  if( libfdata_stream_initialize(
399
388
       &safe_allocation_block_stream,
400
388
       NULL,
401
388
       NULL,
402
388
       NULL,
403
388
       NULL,
404
388
       (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libfshfs_block_data_handle_read_segment_data,
405
388
       NULL,
406
388
       (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libfshfs_block_data_handle_seek_segment_offset,
407
388
       0,
408
388
       error ) != 1 )
409
0
  {
410
0
    libcerror_error_set(
411
0
     error,
412
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
413
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
414
0
     "%s: unable to create allocation block stream.",
415
0
     function );
416
417
0
    goto on_error;
418
0
  }
419
388
  for( extent_index = 0;
420
1.54k
       extent_index < number_of_extents;
421
1.15k
       extent_index++ )
422
1.23k
  {
423
1.23k
    if( libcdata_array_get_entry_by_index(
424
1.23k
         extents,
425
1.23k
         extent_index,
426
1.23k
         (intptr_t **) &extent,
427
1.23k
         error ) != 1 )
428
0
    {
429
0
      libcerror_error_set(
430
0
       error,
431
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
432
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
433
0
       "%s: unable to retrieve extent: %d.",
434
0
       function,
435
0
       extent_index );
436
437
0
      goto on_error;
438
0
    }
439
1.23k
    if( extent == NULL )
440
0
    {
441
0
      libcerror_error_set(
442
0
       error,
443
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
444
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
445
0
       "%s: missing extent: %d.",
446
0
       function,
447
0
       extent_index );
448
449
0
      goto on_error;
450
0
    }
451
1.23k
    if( ( extent->block_number == 0 )
452
1.23k
     || ( extent->block_number > ( (uint64_t) INT64_MAX / io_handle->block_size ) ) )
453
12
    {
454
12
      libcerror_error_set(
455
12
       error,
456
12
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
457
12
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
458
12
       "%s: invalid extent - invalid block number value out of bounds.",
459
12
       function );
460
461
12
      goto on_error;
462
12
    }
463
1.22k
    if( ( extent->number_of_blocks == 0 )
464
1.22k
     || ( extent->number_of_blocks > ( (uint64_t) UINT64_MAX / io_handle->block_size ) ) )
465
0
    {
466
0
      libcerror_error_set(
467
0
       error,
468
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
469
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
470
0
       "%s: invalid extent - invalid number of blocks value out of bounds.",
471
0
       function );
472
473
0
      goto on_error;
474
0
    }
475
1.22k
    segment_offset = (off64_t) extent->block_number * io_handle->block_size;
476
1.22k
    segment_size   = (size64_t) extent->number_of_blocks * io_handle->block_size;
477
478
1.22k
    if( libfdata_stream_append_segment(
479
1.22k
         safe_allocation_block_stream,
480
1.22k
         &segment_index,
481
1.22k
         0,
482
1.22k
         segment_offset,
483
1.22k
         segment_size,
484
1.22k
         0,
485
1.22k
         error ) != 1 )
486
69
    {
487
69
      libcerror_error_set(
488
69
       error,
489
69
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
490
69
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
491
69
       "%s: unable to append extent: %d allocation block stream segment.",
492
69
       function,
493
69
       extent_index );
494
495
69
      goto on_error;
496
69
    }
497
1.22k
  }
498
307
  if( libfdata_stream_set_mapped_size(
499
307
       safe_allocation_block_stream,
500
307
       data_size,
501
307
       error ) != 1 )
502
208
  {
503
208
    libcerror_error_set(
504
208
     error,
505
208
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
506
208
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
507
208
     "%s: unable to set mapped size of allocation block stream.",
508
208
     function );
509
510
208
    goto on_error;
511
208
  }
512
99
  *allocation_block_stream = safe_allocation_block_stream;
513
514
99
  return( 1 );
515
516
289
on_error:
517
289
  if( safe_allocation_block_stream != NULL )
518
289
  {
519
289
    libfdata_stream_free(
520
289
     &safe_allocation_block_stream,
521
289
     NULL );
522
289
  }
523
289
  return( -1 );
524
307
}
525
526
/* Creates an allocation block stream from a compressed stream
527
 * Make sure the value allocation_block_stream is referencing, is set to NULL
528
 * Returns 1 if successful or -1 on error
529
 */
530
int libfshfs_allocation_block_stream_initialize_from_compressed_stream(
531
     libfdata_stream_t **allocation_block_stream,
532
     libfdata_stream_t *compressed_allocation_block_stream,
533
     size64_t uncompressed_data_size,
534
     int compression_method,
535
     libcerror_error_t **error )
536
0
{
537
0
  libfdata_stream_t *safe_allocation_block_stream = NULL;
538
0
  libfshfs_compressed_data_handle_t *data_handle  = NULL;
539
0
  static char *function                           = "libfshfs_allocation_block_stream_initialize_from_compressed_stream";
540
0
  int segment_index                               = 0;
541
542
0
  if( allocation_block_stream == NULL )
543
0
  {
544
0
    libcerror_error_set(
545
0
     error,
546
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
547
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
548
0
     "%s: invalid allocation block stream.",
549
0
     function );
550
551
0
    return( -1 );
552
0
  }
553
0
  if( libfshfs_compressed_data_handle_initialize(
554
0
       &data_handle,
555
0
       compressed_allocation_block_stream,
556
0
       uncompressed_data_size,
557
0
       compression_method,
558
0
       error ) != 1 )
559
0
  {
560
0
    libcerror_error_set(
561
0
     error,
562
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
563
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
564
0
     "%s: unable to create compressed data handle.",
565
0
     function );
566
567
0
    goto on_error;
568
0
  }
569
0
  if( libfdata_stream_initialize(
570
0
       &safe_allocation_block_stream,
571
0
       (intptr_t *) data_handle,
572
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfshfs_compressed_data_handle_free,
573
0
       NULL,
574
0
       NULL,
575
0
       (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libfshfs_compressed_data_handle_read_segment_data,
576
0
       NULL,
577
0
       (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libfshfs_compressed_data_handle_seek_segment_offset,
578
0
       LIBFDATA_DATA_HANDLE_FLAG_MANAGED,
579
0
       error ) != 1 )
580
0
  {
581
0
    libcerror_error_set(
582
0
     error,
583
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
584
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
585
0
     "%s: unable to create allocation block stream.",
586
0
     function );
587
588
0
    goto on_error;
589
0
  }
590
0
  data_handle = NULL;
591
592
0
  if( libfdata_stream_append_segment(
593
0
       safe_allocation_block_stream,
594
0
       &segment_index,
595
0
       0,
596
0
       0,
597
0
       uncompressed_data_size,
598
0
       LIBFDATA_RANGE_FLAG_IS_COMPRESSED,
599
0
       error ) != 1 )
600
0
  {
601
0
    libcerror_error_set(
602
0
     error,
603
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
604
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
605
0
     "%s: unable to append data as allocation block stream segment.",
606
0
     function );
607
608
0
    goto on_error;
609
0
  }
610
0
  *allocation_block_stream = safe_allocation_block_stream;
611
612
0
  return( 1 );
613
614
0
on_error:
615
0
  if( safe_allocation_block_stream != NULL )
616
0
  {
617
0
    libfdata_stream_free(
618
0
     &safe_allocation_block_stream,
619
0
     NULL );
620
0
  }
621
0
  if( data_handle != NULL )
622
0
  {
623
0
    libfshfs_compressed_data_handle_free(
624
0
     &data_handle,
625
0
     NULL );
626
0
  }
627
0
  return( -1 );
628
0
}
629