Coverage Report

Created: 2024-02-25 07:19

/src/libesedb/libesedb/libesedb_compression.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Compression 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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libesedb_compression.h"
28
#include "libesedb_libcerror.h"
29
#include "libesedb_libcnotify.h"
30
#include "libesedb_libfwnt.h"
31
#include "libesedb_libuna.h"
32
33
/* Retrieves the uncompressed size of the 7-bit compressed data
34
 * Returns 1 on success or -1 on error
35
 */
36
int libesedb_compression_7bit_decompress_get_size(
37
     const uint8_t *compressed_data,
38
     size_t compressed_data_size,
39
     size_t *uncompressed_data_size,
40
     libcerror_error_t **error )
41
0
{
42
0
  static char *function = "libesedb_compression_7bit_decompress_get_size";
43
44
0
  if( compressed_data == 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 compressed data.",
51
0
     function );
52
53
0
    return( -1 );
54
0
  }
55
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
61
0
     "%s: invalid compressed data size value exceeds maximum.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
0
  if( compressed_data_size < 1 )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
71
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
72
0
     "%s: compressed data size value too small.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
0
  if( uncompressed_data_size == NULL )
78
0
  {
79
0
    libcerror_error_set(
80
0
     error,
81
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
82
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
83
0
     "%s: invalid uncompressed data size.",
84
0
     function );
85
86
0
    return( -1 );
87
0
  }
88
0
  if( compressed_data[ 0 ] == 0x18 )
89
0
  {
90
0
    libcerror_error_set(
91
0
     error,
92
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
93
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
94
0
     "%s: unsupported leading byte: 0x%02" PRIx8 ".",
95
0
     function,
96
0
     compressed_data[ 0 ] );
97
98
0
    return( -1 );
99
0
  }
100
0
  *uncompressed_data_size = ( ( compressed_data_size - 1 ) * 8 ) / 7;
101
102
0
  return( 1 );
103
0
}
104
105
/* Decompresses 7-bit compressed data
106
 * Returns 1 on success or -1 on error
107
 */
108
int libesedb_compression_7bit_decompress(
109
     const uint8_t *compressed_data,
110
     size_t compressed_data_size,
111
     uint8_t *uncompressed_data,
112
     size_t uncompressed_data_size,
113
     libcerror_error_t **error )
114
0
{
115
0
  static char *function          = "libesedb_compression_7bit_decompress";
116
0
  size_t compressed_data_index   = 0;
117
0
  size_t uncompressed_data_index = 0;
118
0
  uint16_t value_16bit           = 0;
119
0
  uint8_t bit_index              = 0;
120
121
0
  if( compressed_data == NULL )
122
0
  {
123
0
    libcerror_error_set(
124
0
     error,
125
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
126
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
127
0
     "%s: invalid compressed data.",
128
0
     function );
129
130
0
    return( -1 );
131
0
  }
132
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
133
0
  {
134
0
    libcerror_error_set(
135
0
     error,
136
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
137
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
138
0
     "%s: invalid compressed data size value exceeds maximum.",
139
0
     function );
140
141
0
    return( -1 );
142
0
  }
143
0
  if( compressed_data_size < 1 )
144
0
  {
145
0
    libcerror_error_set(
146
0
     error,
147
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
148
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
149
0
     "%s: compressed data size value too small.",
150
0
     function );
151
152
0
    return( -1 );
153
0
  }
154
0
  if( uncompressed_data == NULL )
155
0
  {
156
0
    libcerror_error_set(
157
0
     error,
158
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
159
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
160
0
     "%s: invalid uncompressed data.",
161
0
     function );
162
163
0
    return( -1 );
164
0
  }
165
0
  if( uncompressed_data_size > (size_t) SSIZE_MAX )
166
0
  {
167
0
    libcerror_error_set(
168
0
     error,
169
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
170
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
171
0
     "%s: invalid uncompressed data size value exceeds maximum.",
172
0
     function );
173
174
0
    return( -1 );
175
0
  }
176
0
  if( uncompressed_data_size < ( ( ( compressed_data_size - 1 ) * 8 ) / 7 ) )
177
0
  {
178
0
    libcerror_error_set(
179
0
     error,
180
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
181
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
182
0
     "%s: uncompressed data size value too small.",
183
0
     function );
184
185
0
    return( -1 );
186
0
  }
187
0
  if( compressed_data[ 0 ] == 0x18 )
188
0
  {
189
0
    libcerror_error_set(
190
0
     error,
191
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
192
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
193
0
     "%s: unsupported leading byte: 0x%02" PRIx8 ".",
194
0
     function,
195
0
     compressed_data[ 0 ] );
196
197
0
    return( -1 );
198
0
  }
199
0
  for( compressed_data_index = 1;
200
0
       compressed_data_index < compressed_data_size;
201
0
       compressed_data_index++ )
202
0
  {
203
0
    value_16bit |= (uint16_t) compressed_data[ compressed_data_index ] << bit_index;
204
205
0
    uncompressed_data[ uncompressed_data_index++ ] = (uint8_t) ( value_16bit & 0x7f );
206
207
0
    value_16bit >>= 7;
208
209
0
    bit_index++;
210
211
0
    if( bit_index == 7 )
212
0
    {
213
0
      uncompressed_data[ uncompressed_data_index++ ] = (uint8_t) ( value_16bit & 0x7f );
214
215
0
      value_16bit >>= 7;
216
217
0
      bit_index = 0;
218
0
    }
219
0
  }
220
0
  if( value_16bit != 0 )
221
0
  {
222
0
    libcerror_error_set(
223
0
     error,
224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
225
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
226
0
     "%s: unsupported remainder: 0x%02" PRIx16 ".",
227
0
     function,
228
0
     value_16bit );
229
230
0
    return( -1 );
231
0
  }
232
0
  return( 1 );
233
0
}
234
235
/* Retrieves the uncompressed size of LZXPRESS compressed data
236
 * Returns 1 on success or -1 on error
237
 */
238
int libesedb_compression_lzxpress_decompress_get_size(
239
     const uint8_t *compressed_data,
240
     size_t compressed_data_size,
241
     size_t *uncompressed_data_size,
242
     libcerror_error_t **error )
243
0
{
244
0
  static char *function = "libesedb_compression_lzxpress_decompress_get_size";
245
246
0
  if( compressed_data == NULL )
247
0
  {
248
0
    libcerror_error_set(
249
0
     error,
250
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
251
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
252
0
     "%s: invalid compressed data.",
253
0
     function );
254
255
0
    return( -1 );
256
0
  }
257
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
258
0
  {
259
0
    libcerror_error_set(
260
0
     error,
261
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
262
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
263
0
     "%s: invalid compressed data size value exceeds maximum.",
264
0
     function );
265
266
0
    return( -1 );
267
0
  }
268
0
  if( compressed_data_size < 3 )
269
0
  {
270
0
    libcerror_error_set(
271
0
     error,
272
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
273
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
274
0
     "%s: compressed data size value too small.",
275
0
     function );
276
277
0
    return( -1 );
278
0
  }
279
0
  if( uncompressed_data_size == NULL )
280
0
  {
281
0
    libcerror_error_set(
282
0
     error,
283
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
284
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
285
0
     "%s: invalid uncompressed data size.",
286
0
     function );
287
288
0
    return( -1 );
289
0
  }
290
0
  if( compressed_data[ 0 ] != 0x18 )
291
0
  {
292
0
    libcerror_error_set(
293
0
     error,
294
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
295
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
296
0
     "%s: unsupported leading byte: 0x%02" PRIx8 ".",
297
0
     function,
298
0
     compressed_data[ 0 ] );
299
300
0
    return( -1 );
301
0
  }
302
0
  byte_stream_copy_to_uint16_little_endian(
303
0
   &( compressed_data[ 1 ] ),
304
0
   *uncompressed_data_size );
305
306
0
  return( 1 );
307
0
}
308
309
/* Decompresses LZXPRESS compressed data
310
 * Returns 1 on success or -1 on error
311
 */
312
int libesedb_compression_lzxpress_decompress(
313
     const uint8_t *compressed_data,
314
     size_t compressed_data_size,
315
     uint8_t *uncompressed_data,
316
     size_t uncompressed_data_size,
317
     libcerror_error_t **error )
318
0
{
319
0
  static char *function = "libesedb_compression_lzxpress_decompress";
320
321
0
  if( compressed_data == NULL )
322
0
  {
323
0
    libcerror_error_set(
324
0
     error,
325
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
326
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
327
0
     "%s: invalid compressed data.",
328
0
     function );
329
330
0
    return( -1 );
331
0
  }
332
0
  if( compressed_data_size < 3 )
333
0
  {
334
0
    libcerror_error_set(
335
0
     error,
336
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
337
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
338
0
     "%s: compressed data size value too small.",
339
0
     function );
340
341
0
    return( -1 );
342
0
  }
343
0
  if( compressed_data[ 0 ] != 0x18 )
344
0
  {
345
0
    libcerror_error_set(
346
0
     error,
347
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
348
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
349
0
     "%s: unsupported leading byte: 0x%02" PRIx8 ".",
350
0
     function,
351
0
     compressed_data[ 0 ] );
352
353
0
    return( -1 );
354
0
  }
355
0
  if( libfwnt_lzxpress_decompress(
356
0
       &( compressed_data[ 3 ] ),
357
0
       compressed_data_size - 3,
358
0
       uncompressed_data,
359
0
       &uncompressed_data_size,
360
0
       error ) != 1 )
361
0
  {
362
0
    libcerror_error_set(
363
0
     error,
364
0
     LIBCERROR_ERROR_DOMAIN_COMPRESSION,
365
0
     LIBCERROR_COMPRESSION_ERROR_DECOMPRESS_FAILED,
366
0
     "%s: unable to decompress LZXPRESS compressed data.",
367
0
     function );
368
369
0
    return( -1 );
370
0
  }
371
0
  return( 1 );
372
0
}
373
374
/* Retrieves the uncompressed size of the compressed data
375
 * Returns 1 on success or -1 on error
376
 */
377
int libesedb_compression_decompress_get_size(
378
     const uint8_t *compressed_data,
379
     size_t compressed_data_size,
380
     size_t *uncompressed_data_size,
381
     libcerror_error_t **error )
382
0
{
383
0
  static char *function = "libesedb_compression_decompress_get_size";
384
0
  int result            = 0;
385
386
0
  if( compressed_data == NULL )
387
0
  {
388
0
    libcerror_error_set(
389
0
     error,
390
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
391
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
392
0
     "%s: invalid compressed data.",
393
0
     function );
394
395
0
    return( -1 );
396
0
  }
397
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
398
0
  {
399
0
    libcerror_error_set(
400
0
     error,
401
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
402
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
403
0
     "%s: invalid compressed data size value exceeds maximum.",
404
0
     function );
405
406
0
    return( -1 );
407
0
  }
408
0
  if( compressed_data_size < 1 )
409
0
  {
410
0
    libcerror_error_set(
411
0
     error,
412
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
413
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
414
0
     "%s: compressed data size value too small.",
415
0
     function );
416
417
0
    return( -1 );
418
0
  }
419
0
  if( compressed_data[ 0 ] == 0x18 )
420
0
  {
421
0
    result = libesedb_compression_lzxpress_decompress_get_size(
422
0
              compressed_data,
423
0
              compressed_data_size,
424
0
              uncompressed_data_size,
425
0
              error );
426
0
  }
427
0
  else
428
0
  {
429
0
    result = libesedb_compression_7bit_decompress_get_size(
430
0
              compressed_data,
431
0
              compressed_data_size,
432
0
              uncompressed_data_size,
433
0
              error );
434
0
  }
435
0
  if( result != 1 )
436
0
  {
437
0
    libcerror_error_set(
438
0
     error,
439
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
440
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
441
0
     "%s: unable retrieve uncompressed data size.",
442
0
     function );
443
444
0
    return( -1 );
445
0
  }
446
0
  return( 1 );
447
0
}
448
449
/* Decompresses compressed data
450
 * Returns 1 on success or -1 on error
451
 */
452
int libesedb_compression_decompress(
453
     const uint8_t *compressed_data,
454
     size_t compressed_data_size,
455
     uint8_t *uncompressed_data,
456
     size_t uncompressed_data_size,
457
     libcerror_error_t **error )
458
0
{
459
0
  static char *function = "libesedb_compression_decompress";
460
0
  int result            = 0;
461
462
0
  if( compressed_data == NULL )
463
0
  {
464
0
    libcerror_error_set(
465
0
     error,
466
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
467
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
468
0
     "%s: invalid compressed data.",
469
0
     function );
470
471
0
    return( -1 );
472
0
  }
473
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
474
0
  {
475
0
    libcerror_error_set(
476
0
     error,
477
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
478
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
479
0
     "%s: invalid compressed data size value exceeds maximum.",
480
0
     function );
481
482
0
    return( -1 );
483
0
  }
484
0
  if( compressed_data_size < 1 )
485
0
  {
486
0
    libcerror_error_set(
487
0
     error,
488
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
489
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
490
0
     "%s: compressed data size value too small.",
491
0
     function );
492
493
0
    return( -1 );
494
0
  }
495
0
  if( compressed_data[ 0 ] == 0x18 )
496
0
  {
497
0
    result = libesedb_compression_lzxpress_decompress(
498
0
              compressed_data,
499
0
              compressed_data_size,
500
0
              uncompressed_data,
501
0
              uncompressed_data_size,
502
0
              error );
503
0
  }
504
0
  else
505
0
  {
506
0
    result = libesedb_compression_7bit_decompress(
507
0
              compressed_data,
508
0
              compressed_data_size,
509
0
              uncompressed_data,
510
0
              uncompressed_data_size,
511
0
              error );
512
0
  }
513
0
  if( result != 1 )
514
0
  {
515
0
    libcerror_error_set(
516
0
     error,
517
0
     LIBCERROR_ERROR_DOMAIN_COMPRESSION,
518
0
     LIBCERROR_COMPRESSION_ERROR_DECOMPRESS_FAILED,
519
0
     "%s: unable decompressed data.",
520
0
     function );
521
522
0
    return( -1 );
523
0
  }
524
0
  return( 1 );
525
0
}
526
527
/* Retrieves the UTF-8 string size of compressed data
528
 * Returns 1 on success or -1 on error
529
 */
530
int libesedb_compression_get_utf8_string_size(
531
     const uint8_t *compressed_data,
532
     size_t compressed_data_size,
533
     size_t *utf8_string_size,
534
     libcerror_error_t **error )
535
0
{
536
0
  uint8_t *uncompressed_data    = NULL;
537
0
  static char *function         = "libesedb_compression_get_utf8_string_size";
538
0
  size_t uncompressed_data_size = 0;
539
0
  int result                    = 0;
540
541
0
  if( compressed_data == NULL )
542
0
  {
543
0
    libcerror_error_set(
544
0
     error,
545
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
546
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
547
0
     "%s: invalid compressed data.",
548
0
     function );
549
550
0
    return( -1 );
551
0
  }
552
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
553
0
  {
554
0
    libcerror_error_set(
555
0
     error,
556
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
557
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
558
0
     "%s: invalid compressed data size value exceeds maximum.",
559
0
     function );
560
561
0
    return( -1 );
562
0
  }
563
0
  if( compressed_data_size < 1 )
564
0
  {
565
0
    libcerror_error_set(
566
0
     error,
567
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
568
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
569
0
     "%s: compressed data size value too small.",
570
0
     function );
571
572
0
    return( -1 );
573
0
  }
574
0
  if( compressed_data[ 0 ] == 0x18 )
575
0
  {
576
0
    result = libesedb_compression_lzxpress_decompress_get_size(
577
0
              compressed_data,
578
0
              compressed_data_size,
579
0
              &uncompressed_data_size,
580
0
              error );
581
0
  }
582
0
  else
583
0
  {
584
0
    result = libesedb_compression_7bit_decompress_get_size(
585
0
              compressed_data,
586
0
              compressed_data_size,
587
0
              &uncompressed_data_size,
588
0
              error );
589
0
  }
590
0
  if( result != 1 )
591
0
  {
592
0
    libcerror_error_set(
593
0
     error,
594
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
595
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
596
0
     "%s: unable retrieve uncompressed data size.",
597
0
     function );
598
599
0
    goto on_error;
600
0
  }
601
0
  if( ( uncompressed_data_size == 0 )
602
0
   || ( uncompressed_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
603
0
  {
604
0
    libcerror_error_set(
605
0
     error,
606
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
607
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
608
0
     "%s: invalid uncompressed data size value out of bounds.",
609
0
     function );
610
611
0
    goto on_error;
612
0
  }
613
0
  uncompressed_data = (uint8_t *) memory_allocate(
614
0
           sizeof( uint8_t ) * uncompressed_data_size );
615
616
0
  if( uncompressed_data == NULL )
617
0
  {
618
0
    libcerror_error_set(
619
0
     error,
620
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
621
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
622
0
     "%s: unable to create uncompressed data.",
623
0
     function );
624
625
0
    goto on_error;
626
0
  }
627
0
  if( compressed_data[ 0 ] == 0x18 )
628
0
  {
629
0
    result = libesedb_compression_lzxpress_decompress(
630
0
              compressed_data,
631
0
              compressed_data_size,
632
0
              uncompressed_data,
633
0
              uncompressed_data_size,
634
0
              error );
635
0
  }
636
0
  else
637
0
  {
638
0
    result = libesedb_compression_7bit_decompress(
639
0
              compressed_data,
640
0
              compressed_data_size,
641
0
              uncompressed_data,
642
0
              uncompressed_data_size,
643
0
              error );
644
0
  }
645
0
  if( result != 1 )
646
0
  {
647
0
    libcerror_error_set(
648
0
     error,
649
0
     LIBCERROR_ERROR_DOMAIN_COMPRESSION,
650
0
     LIBCERROR_COMPRESSION_ERROR_DECOMPRESS_FAILED,
651
0
     "%s: unable decompressed data.",
652
0
     function );
653
654
0
    goto on_error;
655
0
  }
656
0
  result = 0;
657
658
0
  if( ( ( uncompressed_data_size % 2 ) == 0 )
659
0
   && ( ( compressed_data[ 0 ] == 0x18 )
660
0
    ||  ( ( compressed_data[ 0 ] & 0x10 ) == 0 ) ) )
661
0
  {
662
0
    result = libuna_utf8_string_size_from_utf16_stream(
663
0
        uncompressed_data,
664
0
        uncompressed_data_size,
665
0
        LIBUNA_ENDIAN_LITTLE,
666
0
        utf8_string_size,
667
0
        error );
668
669
0
    if( result != 1 )
670
0
    {
671
0
      libcerror_error_set(
672
0
       error,
673
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
674
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
675
0
       "%s: unable to determine UTF-8 string size of UTF-16 stream.",
676
0
       function );
677
678
#if defined( HAVE_DEBUG_OUTPUT )
679
      if( ( error != NULL )
680
       && ( *error != NULL ) )
681
      {
682
        libcnotify_print_error_backtrace(
683
         *error );
684
      }
685
#endif
686
0
      libcerror_error_free(
687
0
       error );
688
0
    }
689
0
  }
690
0
  if( result != 1 )
691
0
  {
692
0
    result = libuna_utf8_string_size_from_utf8_stream(
693
0
        uncompressed_data,
694
0
        uncompressed_data_size,
695
0
        utf8_string_size,
696
0
        error );
697
698
0
    if( result != 1 )
699
0
    {
700
0
      libcerror_error_set(
701
0
       error,
702
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
703
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
704
0
       "%s: unable to determine UTF-8 string size of UTF-8 stream.",
705
0
       function );
706
707
0
      goto on_error;
708
0
    }
709
0
  }
710
0
  memory_free(
711
0
   uncompressed_data );
712
713
0
  uncompressed_data = NULL;
714
715
0
  return( 1 );
716
717
0
on_error:
718
0
  if( uncompressed_data != NULL )
719
0
  {
720
0
    memory_free(
721
0
     uncompressed_data );
722
0
  }
723
0
  return( -1 );
724
0
}
725
726
/* Copies compressed data to an UTF-8 string
727
 * Returns 1 on success or -1 on error
728
 */
729
int libesedb_compression_copy_to_utf8_string(
730
     const uint8_t *compressed_data,
731
     size_t compressed_data_size,
732
     uint8_t *utf8_string,
733
     size_t utf8_string_size,
734
     libcerror_error_t **error )
735
0
{
736
0
  uint8_t *uncompressed_data    = NULL;
737
0
  static char *function         = "libesedb_compression_copy_to_utf8_string";
738
0
  size_t uncompressed_data_size = 0;
739
0
  int result                    = 0;
740
741
0
  if( compressed_data == NULL )
742
0
  {
743
0
    libcerror_error_set(
744
0
     error,
745
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
746
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
747
0
     "%s: invalid compressed data.",
748
0
     function );
749
750
0
    return( -1 );
751
0
  }
752
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
753
0
  {
754
0
    libcerror_error_set(
755
0
     error,
756
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
757
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
758
0
     "%s: invalid compressed data size value exceeds maximum.",
759
0
     function );
760
761
0
    return( -1 );
762
0
  }
763
0
  if( compressed_data_size < 1 )
764
0
  {
765
0
    libcerror_error_set(
766
0
     error,
767
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
768
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
769
0
     "%s: compressed data size value too small.",
770
0
     function );
771
772
0
    return( -1 );
773
0
  }
774
0
  if( compressed_data[ 0 ] == 0x18 )
775
0
  {
776
0
    result = libesedb_compression_lzxpress_decompress_get_size(
777
0
              compressed_data,
778
0
              compressed_data_size,
779
0
              &uncompressed_data_size,
780
0
              error );
781
0
  }
782
0
  else
783
0
  {
784
0
    result = libesedb_compression_7bit_decompress_get_size(
785
0
              compressed_data,
786
0
              compressed_data_size,
787
0
              &uncompressed_data_size,
788
0
              error );
789
0
  }
790
0
  if( result != 1 )
791
0
  {
792
0
    libcerror_error_set(
793
0
     error,
794
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
795
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
796
0
     "%s: unable retrieve uncompressed data size.",
797
0
     function );
798
799
0
    goto on_error;
800
0
  }
801
0
  if( ( uncompressed_data_size == 0 )
802
0
   || ( uncompressed_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
803
0
  {
804
0
    libcerror_error_set(
805
0
     error,
806
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
807
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
808
0
     "%s: invalid uncompressed data size value out of bounds.",
809
0
     function );
810
811
0
    goto on_error;
812
0
  }
813
0
  uncompressed_data = (uint8_t *) memory_allocate(
814
0
           sizeof( uint8_t ) * uncompressed_data_size );
815
816
0
  if( uncompressed_data == NULL )
817
0
  {
818
0
    libcerror_error_set(
819
0
     error,
820
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
821
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
822
0
     "%s: unable to create uncompressed data.",
823
0
     function );
824
825
0
    goto on_error;
826
0
  }
827
0
  if( compressed_data[ 0 ] == 0x18 )
828
0
  {
829
0
    result = libesedb_compression_lzxpress_decompress(
830
0
              compressed_data,
831
0
              compressed_data_size,
832
0
              uncompressed_data,
833
0
              uncompressed_data_size,
834
0
              error );
835
0
  }
836
0
  else
837
0
  {
838
0
    result = libesedb_compression_7bit_decompress(
839
0
              compressed_data,
840
0
              compressed_data_size,
841
0
              uncompressed_data,
842
0
              uncompressed_data_size,
843
0
              error );
844
0
  }
845
0
  if( result != 1 )
846
0
  {
847
0
    libcerror_error_set(
848
0
     error,
849
0
     LIBCERROR_ERROR_DOMAIN_COMPRESSION,
850
0
     LIBCERROR_COMPRESSION_ERROR_DECOMPRESS_FAILED,
851
0
     "%s: unable decompressed data.",
852
0
     function );
853
854
0
    goto on_error;
855
0
  }
856
0
  result = 0;
857
858
0
  if( ( ( uncompressed_data_size % 2 ) == 0 )
859
0
   && ( ( compressed_data[ 0 ] == 0x18 )
860
0
    ||  ( ( compressed_data[ 0 ] & 0x10 ) == 0 ) ) )
861
0
  {
862
0
    result = libuna_utf8_string_copy_from_utf16_stream(
863
0
        utf8_string,
864
0
        utf8_string_size,
865
0
        uncompressed_data,
866
0
        uncompressed_data_size,
867
0
        LIBUNA_ENDIAN_LITTLE,
868
0
        error );
869
870
0
    if( result != 1 )
871
0
    {
872
0
      libcerror_error_set(
873
0
       error,
874
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
875
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
876
0
       "%s: unable to copy UTF-16 stream to UTF-8 string.",
877
0
       function );
878
879
#if defined( HAVE_DEBUG_OUTPUT )
880
      if( ( error != NULL )
881
       && ( *error != NULL ) )
882
      {
883
        libcnotify_print_error_backtrace(
884
         *error );
885
      }
886
#endif
887
0
      libcerror_error_free(
888
0
       error );
889
0
    }
890
0
  }
891
0
  if( result != 1 )
892
0
  {
893
0
    result = libuna_utf8_string_copy_from_utf8_stream(
894
0
        utf8_string,
895
0
        utf8_string_size,
896
0
        uncompressed_data,
897
0
        uncompressed_data_size,
898
0
        error );
899
900
0
    if( result != 1 )
901
0
    {
902
0
      libcerror_error_set(
903
0
       error,
904
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
905
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
906
0
       "%s: unable to copy UTF-8 stream to UTF-8 string.",
907
0
       function );
908
909
0
      goto on_error;
910
0
    }
911
0
  }
912
0
  memory_free(
913
0
   uncompressed_data );
914
915
0
  uncompressed_data = NULL;
916
917
0
  return( 1 );
918
919
0
on_error:
920
0
  if( uncompressed_data != NULL )
921
0
  {
922
0
    memory_free(
923
0
     uncompressed_data );
924
0
  }
925
0
  return( -1 );
926
0
}
927
928
/* Retrieves the UTF-16 string size of compressed data
929
 * Returns 1 on success or -1 on error
930
 */
931
int libesedb_compression_get_utf16_string_size(
932
     const uint8_t *compressed_data,
933
     size_t compressed_data_size,
934
     size_t *utf16_string_size,
935
     libcerror_error_t **error )
936
0
{
937
0
  uint8_t *uncompressed_data    = NULL;
938
0
  static char *function         = "libesedb_compression_get_utf16_string_size";
939
0
  size_t uncompressed_data_size = 0;
940
0
  int result                    = 0;
941
942
0
  if( compressed_data == NULL )
943
0
  {
944
0
    libcerror_error_set(
945
0
     error,
946
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
947
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
948
0
     "%s: invalid compressed data.",
949
0
     function );
950
951
0
    return( -1 );
952
0
  }
953
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
954
0
  {
955
0
    libcerror_error_set(
956
0
     error,
957
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
958
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
959
0
     "%s: invalid compressed data size value exceeds maximum.",
960
0
     function );
961
962
0
    return( -1 );
963
0
  }
964
0
  if( compressed_data_size < 1 )
965
0
  {
966
0
    libcerror_error_set(
967
0
     error,
968
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
969
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
970
0
     "%s: compressed data size value too small.",
971
0
     function );
972
973
0
    return( -1 );
974
0
  }
975
0
  if( compressed_data[ 0 ] == 0x18 )
976
0
  {
977
0
    result = libesedb_compression_lzxpress_decompress_get_size(
978
0
              compressed_data,
979
0
              compressed_data_size,
980
0
              &uncompressed_data_size,
981
0
              error );
982
0
  }
983
0
  else
984
0
  {
985
0
    result = libesedb_compression_7bit_decompress_get_size(
986
0
              compressed_data,
987
0
              compressed_data_size,
988
0
              &uncompressed_data_size,
989
0
              error );
990
0
  }
991
0
  if( result != 1 )
992
0
  {
993
0
    libcerror_error_set(
994
0
     error,
995
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
996
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
997
0
     "%s: unable retrieve uncompressed data size.",
998
0
     function );
999
1000
0
    goto on_error;
1001
0
  }
1002
0
  if( ( uncompressed_data_size == 0 )
1003
0
   || ( uncompressed_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
1004
0
  {
1005
0
    libcerror_error_set(
1006
0
     error,
1007
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1008
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1009
0
     "%s: invalid uncompressed data size value out of bounds.",
1010
0
     function );
1011
1012
0
    goto on_error;
1013
0
  }
1014
0
  uncompressed_data = (uint8_t *) memory_allocate(
1015
0
           sizeof( uint8_t ) * uncompressed_data_size );
1016
1017
0
  if( uncompressed_data == NULL )
1018
0
  {
1019
0
    libcerror_error_set(
1020
0
     error,
1021
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1022
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1023
0
     "%s: unable to create uncompressed data.",
1024
0
     function );
1025
1026
0
    goto on_error;
1027
0
  }
1028
0
  if( compressed_data[ 0 ] == 0x18 )
1029
0
  {
1030
0
    result = libesedb_compression_lzxpress_decompress(
1031
0
              compressed_data,
1032
0
              compressed_data_size,
1033
0
              uncompressed_data,
1034
0
              uncompressed_data_size,
1035
0
              error );
1036
0
  }
1037
0
  else
1038
0
  {
1039
0
    result = libesedb_compression_7bit_decompress(
1040
0
              compressed_data,
1041
0
              compressed_data_size,
1042
0
              uncompressed_data,
1043
0
              uncompressed_data_size,
1044
0
              error );
1045
0
  }
1046
0
  if( result != 1 )
1047
0
  {
1048
0
    libcerror_error_set(
1049
0
     error,
1050
0
     LIBCERROR_ERROR_DOMAIN_COMPRESSION,
1051
0
     LIBCERROR_COMPRESSION_ERROR_DECOMPRESS_FAILED,
1052
0
     "%s: unable decompressed data.",
1053
0
     function );
1054
1055
0
    goto on_error;
1056
0
  }
1057
0
  result = 0;
1058
1059
0
  if( ( ( uncompressed_data_size % 2 ) == 0 )
1060
0
   && ( ( compressed_data[ 0 ] == 0x18 )
1061
0
    ||  ( ( compressed_data[ 0 ] & 0x10 ) == 0 ) ) )
1062
0
  {
1063
0
    result = libuna_utf16_string_size_from_utf16_stream(
1064
0
        uncompressed_data,
1065
0
        uncompressed_data_size,
1066
0
        LIBUNA_ENDIAN_LITTLE,
1067
0
        utf16_string_size,
1068
0
        error );
1069
1070
0
    if( result != 1 )
1071
0
    {
1072
0
      libcerror_error_set(
1073
0
       error,
1074
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1075
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1076
0
       "%s: unable to determine UTF-16 string size of UTF-16 stream.",
1077
0
       function );
1078
1079
#if defined( HAVE_DEBUG_OUTPUT )
1080
      if( ( error != NULL )
1081
       && ( *error != NULL ) )
1082
      {
1083
        libcnotify_print_error_backtrace(
1084
         *error );
1085
      }
1086
#endif
1087
0
      libcerror_error_free(
1088
0
       error );
1089
0
    }
1090
0
  }
1091
0
  if( result != 1 )
1092
0
  {
1093
0
    result = libuna_utf16_string_size_from_utf8_stream(
1094
0
        uncompressed_data,
1095
0
        uncompressed_data_size,
1096
0
        utf16_string_size,
1097
0
        error );
1098
1099
0
    if( result != 1 )
1100
0
    {
1101
0
      libcerror_error_set(
1102
0
       error,
1103
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1104
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1105
0
       "%s: unable to determine UTF-16 string size of UTF-8 stream.",
1106
0
       function );
1107
1108
0
      goto on_error;
1109
0
    }
1110
0
  }
1111
0
  memory_free(
1112
0
   uncompressed_data );
1113
1114
0
  uncompressed_data = NULL;
1115
1116
0
  return( 1 );
1117
1118
0
on_error:
1119
0
  if( uncompressed_data != NULL )
1120
0
  {
1121
0
    memory_free(
1122
0
     uncompressed_data );
1123
0
  }
1124
0
  return( -1 );
1125
0
}
1126
1127
/* Copies compressed data to an UTF-16 string
1128
 * Returns 1 on success or -1 on error
1129
 */
1130
int libesedb_compression_copy_to_utf16_string(
1131
     const uint8_t *compressed_data,
1132
     size_t compressed_data_size,
1133
     uint16_t *utf16_string,
1134
     size_t utf16_string_size,
1135
     libcerror_error_t **error )
1136
0
{
1137
0
  uint8_t *uncompressed_data    = NULL;
1138
0
  static char *function         = "libesedb_compression_copy_to_utf16_string";
1139
0
  size_t uncompressed_data_size = 0;
1140
0
  int result                    = 0;
1141
1142
0
  if( compressed_data == NULL )
1143
0
  {
1144
0
    libcerror_error_set(
1145
0
     error,
1146
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1147
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1148
0
     "%s: invalid compressed data.",
1149
0
     function );
1150
1151
0
    return( -1 );
1152
0
  }
1153
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
1154
0
  {
1155
0
    libcerror_error_set(
1156
0
     error,
1157
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1158
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1159
0
     "%s: invalid compressed data size value exceeds maximum.",
1160
0
     function );
1161
1162
0
    return( -1 );
1163
0
  }
1164
0
  if( compressed_data_size < 1 )
1165
0
  {
1166
0
    libcerror_error_set(
1167
0
     error,
1168
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1169
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1170
0
     "%s: compressed data size value too small.",
1171
0
     function );
1172
1173
0
    return( -1 );
1174
0
  }
1175
0
  if( compressed_data[ 0 ] == 0x18 )
1176
0
  {
1177
0
    result = libesedb_compression_lzxpress_decompress_get_size(
1178
0
              compressed_data,
1179
0
              compressed_data_size,
1180
0
              &uncompressed_data_size,
1181
0
              error );
1182
0
  }
1183
0
  else
1184
0
  {
1185
0
    result = libesedb_compression_7bit_decompress_get_size(
1186
0
              compressed_data,
1187
0
              compressed_data_size,
1188
0
              &uncompressed_data_size,
1189
0
              error );
1190
0
  }
1191
0
  if( result != 1 )
1192
0
  {
1193
0
    libcerror_error_set(
1194
0
     error,
1195
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1196
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1197
0
     "%s: unable retrieve uncompressed data size.",
1198
0
     function );
1199
1200
0
    goto on_error;
1201
0
  }
1202
0
  if( ( uncompressed_data_size == 0 )
1203
0
   || ( uncompressed_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
1204
0
  {
1205
0
    libcerror_error_set(
1206
0
     error,
1207
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1208
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1209
0
     "%s: invalid uncompressed data size value out of bounds.",
1210
0
     function );
1211
1212
0
    goto on_error;
1213
0
  }
1214
0
  uncompressed_data = (uint8_t *) memory_allocate(
1215
0
           sizeof( uint8_t ) * uncompressed_data_size );
1216
1217
0
  if( uncompressed_data == NULL )
1218
0
  {
1219
0
    libcerror_error_set(
1220
0
     error,
1221
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1222
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1223
0
     "%s: unable to create uncompressed data.",
1224
0
     function );
1225
1226
0
    goto on_error;
1227
0
  }
1228
0
  if( compressed_data[ 0 ] == 0x18 )
1229
0
  {
1230
0
    result = libesedb_compression_lzxpress_decompress(
1231
0
              compressed_data,
1232
0
              compressed_data_size,
1233
0
              uncompressed_data,
1234
0
              uncompressed_data_size,
1235
0
              error );
1236
0
  }
1237
0
  else
1238
0
  {
1239
0
    result = libesedb_compression_7bit_decompress(
1240
0
              compressed_data,
1241
0
              compressed_data_size,
1242
0
              uncompressed_data,
1243
0
              uncompressed_data_size,
1244
0
              error );
1245
0
  }
1246
0
  if( result != 1 )
1247
0
  {
1248
0
    libcerror_error_set(
1249
0
     error,
1250
0
     LIBCERROR_ERROR_DOMAIN_COMPRESSION,
1251
0
     LIBCERROR_COMPRESSION_ERROR_DECOMPRESS_FAILED,
1252
0
     "%s: unable decompressed data.",
1253
0
     function );
1254
1255
0
    goto on_error;
1256
0
  }
1257
0
  result = 0;
1258
1259
0
  if( ( ( uncompressed_data_size % 2 ) == 0 )
1260
0
   && ( ( compressed_data[ 0 ] == 0x18 )
1261
0
    ||  ( ( compressed_data[ 0 ] & 0x10 ) == 0 ) ) )
1262
0
  {
1263
0
    result = libuna_utf16_string_copy_from_utf16_stream(
1264
0
        utf16_string,
1265
0
        utf16_string_size,
1266
0
        uncompressed_data,
1267
0
        uncompressed_data_size,
1268
0
        LIBUNA_ENDIAN_LITTLE,
1269
0
        error );
1270
1271
0
    if( result != 1 )
1272
0
    {
1273
0
      libcerror_error_set(
1274
0
       error,
1275
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1276
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1277
0
       "%s: unable to copy UTF-16 stream to UTF-16 string.",
1278
0
       function );
1279
1280
#if defined( HAVE_DEBUG_OUTPUT )
1281
      if( ( error != NULL )
1282
       && ( *error != NULL ) )
1283
      {
1284
        libcnotify_print_error_backtrace(
1285
         *error );
1286
      }
1287
#endif
1288
0
      libcerror_error_free(
1289
0
       error );
1290
0
    }
1291
0
  }
1292
0
  if( result != 1 )
1293
0
  {
1294
0
    result = libuna_utf16_string_copy_from_utf8_stream(
1295
0
        utf16_string,
1296
0
        utf16_string_size,
1297
0
        uncompressed_data,
1298
0
        uncompressed_data_size,
1299
0
        error );
1300
1301
0
    if( result != 1 )
1302
0
    {
1303
0
      libcerror_error_set(
1304
0
       error,
1305
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1306
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1307
0
       "%s: unable to copy UTF-16 stream to UTF-8 string.",
1308
0
       function );
1309
1310
0
      goto on_error;
1311
0
    }
1312
0
  }
1313
0
  memory_free(
1314
0
   uncompressed_data );
1315
1316
0
  uncompressed_data = NULL;
1317
1318
0
  return( 1 );
1319
1320
0
on_error:
1321
0
  if( uncompressed_data != NULL )
1322
0
  {
1323
0
    memory_free(
1324
0
     uncompressed_data );
1325
0
  }
1326
0
  return( -1 );
1327
0
}
1328