Coverage Report

Created: 2024-02-25 07:20

/src/libevtx/libfvalue/libfvalue_binary_data.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Binary data value functions
3
 *
4
 * Copyright (C) 2010-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 "libfvalue_binary_data.h"
28
#include "libfvalue_definitions.h"
29
#include "libfvalue_libcerror.h"
30
#include "libfvalue_libuna.h"
31
32
/* Creates a binary data
33
 * Make sure the value binary_data is referencing, is set to NULL
34
 * Returns 1 if successful or -1 on error
35
 */
36
int libfvalue_binary_data_initialize(
37
     libfvalue_binary_data_t **binary_data,
38
     libcerror_error_t **error )
39
0
{
40
0
  static char *function = "libfvalue_binary_data_initialize";
41
42
0
  if( binary_data == NULL )
43
0
  {
44
0
    libcerror_error_set(
45
0
     error,
46
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
47
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
48
0
     "%s: invalid binary data.",
49
0
     function );
50
51
0
    return( -1 );
52
0
  }
53
0
  if( *binary_data != NULL )
54
0
  {
55
0
    libcerror_error_set(
56
0
     error,
57
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
58
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
59
0
     "%s: invalid binary data value already set.",
60
0
     function );
61
62
0
    return( -1 );
63
0
  }
64
0
  *binary_data = memory_allocate_structure(
65
0
                  libfvalue_binary_data_t );
66
67
0
  if( *binary_data == NULL )
68
0
  {
69
0
    libcerror_error_set(
70
0
     error,
71
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
72
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
73
0
     "%s: unable to create binary data.",
74
0
     function );
75
76
0
    goto on_error;
77
0
  }
78
0
  if( memory_set(
79
0
       *binary_data,
80
0
       0,
81
0
       sizeof( libfvalue_binary_data_t ) ) == NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
86
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
87
0
     "%s: unable to clear binary data.",
88
0
     function );
89
90
0
    goto on_error;
91
0
  }
92
0
  return( 1 );
93
94
0
on_error:
95
0
  if( *binary_data != NULL )
96
0
  {
97
0
    memory_free(
98
0
     *binary_data );
99
100
0
    *binary_data = NULL;
101
0
  }
102
0
  return( -1 );
103
0
}
104
105
/* Frees a binary data
106
 * Returns 1 if successful or -1 on error
107
 */
108
int libfvalue_binary_data_free(
109
     libfvalue_binary_data_t **binary_data,
110
     libcerror_error_t **error )
111
0
{
112
0
  static char *function = "libfvalue_binary_data_free";
113
114
0
  if( binary_data == NULL )
115
0
  {
116
0
    libcerror_error_set(
117
0
     error,
118
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
119
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
120
0
     "%s: invalid binary data.",
121
0
     function );
122
123
0
    return( -1 );
124
0
  }
125
0
  if( *binary_data != NULL )
126
0
  {
127
0
    memory_free(
128
0
     *binary_data );
129
130
0
    *binary_data = NULL;
131
0
  }
132
0
  return( 1 );
133
0
}
134
135
/* Clones a binary data
136
 * Returns 1 if successful or -1 on error
137
 */
138
int libfvalue_binary_data_clone(
139
     libfvalue_binary_data_t **destination_binary_data,
140
     libfvalue_binary_data_t *source_binary_data,
141
     libcerror_error_t **error )
142
0
{
143
0
  static char *function = "libfvalue_binary_data_clone";
144
145
0
  if( destination_binary_data == NULL )
146
0
  {
147
0
    libcerror_error_set(
148
0
     error,
149
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
150
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
151
0
     "%s: invalid destination binary data.",
152
0
     function );
153
154
0
    return( -1 );
155
0
  }
156
0
  if( *destination_binary_data != NULL )
157
0
  {
158
0
    libcerror_error_set(
159
0
     error,
160
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
161
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
162
0
     "%s: destination binary data already set.",
163
0
     function );
164
165
0
    return( -1 );
166
0
  }
167
0
  if( source_binary_data == NULL )
168
0
  {
169
0
    *destination_binary_data = NULL;
170
171
0
    return( 1 );
172
0
  }
173
0
  *destination_binary_data = memory_allocate_structure(
174
0
                              libfvalue_binary_data_t );
175
176
0
  if( *destination_binary_data == NULL )
177
0
  {
178
0
    libcerror_error_set(
179
0
     error,
180
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
181
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
182
0
     "%s: unable to create destination binary data.",
183
0
     function );
184
185
0
    goto on_error;
186
0
  }
187
0
  if( memory_copy(
188
0
       *destination_binary_data,
189
0
       source_binary_data,
190
0
       sizeof( libfvalue_binary_data_t ) ) == NULL )
191
0
  {
192
0
    libcerror_error_set(
193
0
     error,
194
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
195
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
196
0
     "%s: unable to copy binary data.",
197
0
     function );
198
199
0
    goto on_error;
200
0
  }
201
0
  return( 1 );
202
203
0
on_error:
204
0
  if( *destination_binary_data != NULL )
205
0
  {
206
0
    memory_free(
207
0
     *destination_binary_data );
208
209
0
    *destination_binary_data = NULL;
210
0
  }
211
0
  return( -1 );
212
0
}
213
214
/* Copies the binary data from a byte stream
215
 * Returns 1 if successful or -1 on error
216
 */
217
int libfvalue_binary_data_copy_from_byte_stream(
218
     libfvalue_binary_data_t *binary_data,
219
     const uint8_t *byte_stream,
220
     size_t byte_stream_size,
221
     int encoding,
222
     libcerror_error_t **error )
223
0
{
224
0
  static char *function = "libfvalue_binary_data_copy_from_byte_stream";
225
226
0
  if( binary_data == NULL )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
231
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
232
0
     "%s: invalid binary data.",
233
0
     function );
234
235
0
    return( -1 );
236
0
  }
237
0
  if( byte_stream == NULL )
238
0
  {
239
0
    if( byte_stream_size != 0 )
240
0
    {
241
0
      libcerror_error_set(
242
0
       error,
243
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
244
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
245
0
       "%s: invalid byte stream size value out of bounds.",
246
0
       function );
247
248
0
      return( -1 );
249
0
    }
250
0
  }
251
0
  else
252
0
  {
253
0
    if( byte_stream_size > (size_t) SSIZE_MAX )
254
0
    {
255
0
      libcerror_error_set(
256
0
       error,
257
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
258
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
259
0
       "%s: invalid byte stream size value exceeds maximum.",
260
0
       function );
261
262
0
      return( -1 );
263
0
    }
264
0
  }
265
0
  if( encoding != 0 )
266
0
  {
267
0
    libcerror_error_set(
268
0
     error,
269
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
270
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
271
0
     "%s: unsupported encoding.",
272
0
     function );
273
274
0
    return( -1 );
275
0
  }
276
0
  binary_data->data      = byte_stream;
277
0
  binary_data->data_size = byte_stream_size;
278
279
0
  return( 1 );
280
0
}
281
282
/* Retrieves the size of an UTF-8 formatted string of the binary data
283
 * Returns 1 if successful or -1 on error
284
 */
285
int libfvalue_binary_data_get_utf8_string_size(
286
     libfvalue_binary_data_t *binary_data,
287
     size_t *utf8_string_size,
288
     uint32_t string_format_flags,
289
     libcerror_error_t **error )
290
0
{
291
0
  static char *function       = "libfvalue_binary_data_get_utf8_string_size";
292
0
  uint32_t format_flags       = 0;
293
0
  uint32_t string_format_type = 0;
294
0
  uint32_t supported_flags    = 0;
295
296
0
  if( binary_data == NULL )
297
0
  {
298
0
    libcerror_error_set(
299
0
     error,
300
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
301
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
302
0
     "%s: invalid binary data.",
303
0
     function );
304
305
0
    return( -1 );
306
0
  }
307
0
  if( utf8_string_size == NULL )
308
0
  {
309
0
    libcerror_error_set(
310
0
     error,
311
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
312
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
313
0
     "%s: invalid UTF-8 string size.",
314
0
     function );
315
316
0
    return( -1 );
317
0
  }
318
0
  supported_flags = 0x000000ffUL
319
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
320
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
321
322
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
323
0
  {
324
0
    libcerror_error_set(
325
0
     error,
326
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
327
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
328
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
329
0
     function,
330
0
     string_format_flags );
331
332
0
    return( -1 );
333
0
  }
334
0
  string_format_type = string_format_flags & 0x000000ffUL;
335
336
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
337
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
338
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
339
0
  {
340
0
    libcerror_error_set(
341
0
     error,
342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
343
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
344
0
     "%s: unsupported string format type.",
345
0
     function );
346
347
0
    return( -1 );
348
0
  }
349
0
  *utf8_string_size = 0;
350
351
0
  if( ( binary_data->data != NULL )
352
0
   && ( binary_data->data_size != 0 ) )
353
0
  {
354
0
    switch( string_format_type )
355
0
    {
356
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
357
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
358
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
359
360
0
        if( libuna_base16_stream_size_from_byte_stream(
361
0
             binary_data->data,
362
0
             binary_data->data_size,
363
0
             utf8_string_size,
364
0
             format_flags,
365
0
             error ) != 1 )
366
0
        {
367
0
          libcerror_error_set(
368
0
           error,
369
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
370
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
371
0
           "%s: unable to determine size of UTF-8 string of base16 formatted binary data.",
372
0
           function );
373
374
0
          return( -1 );
375
0
        }
376
0
        break;
377
378
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
379
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
380
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
381
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
382
383
0
        if( libuna_base32_stream_size_from_byte_stream(
384
0
             binary_data->data,
385
0
             binary_data->data_size,
386
0
             utf8_string_size,
387
0
             format_flags,
388
0
             error ) != 1 )
389
0
        {
390
0
          libcerror_error_set(
391
0
           error,
392
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
393
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
394
0
           "%s: unable to determine size of UTF-8 string of base32 formatted binary data.",
395
0
           function );
396
397
0
          return( -1 );
398
0
        }
399
0
        break;
400
401
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
402
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
403
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
404
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
405
406
0
        if( libuna_base64_stream_size_from_byte_stream(
407
0
             binary_data->data,
408
0
             binary_data->data_size,
409
0
             utf8_string_size,
410
0
             format_flags,
411
0
             error ) != 1 )
412
0
        {
413
0
          libcerror_error_set(
414
0
           error,
415
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
416
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
417
0
           "%s: unable to determine size of UTF-8 string of base64 formatted binary data.",
418
0
           function );
419
420
0
          return( -1 );
421
0
        }
422
0
        break;
423
0
    }
424
0
  }
425
  /* Add space for the end-of-string character
426
   */
427
0
  *utf8_string_size += 1;
428
429
0
  return( 1 );
430
0
}
431
432
/* Copies the binary data to an UTF-8 encoded string
433
 * Returns 1 if successful or -1 on error
434
 */
435
int libfvalue_binary_data_copy_to_utf8_string_with_index(
436
     libfvalue_binary_data_t *binary_data,
437
     uint8_t *utf8_string,
438
     size_t utf8_string_size,
439
     size_t *utf8_string_index,
440
     uint32_t string_format_flags,
441
     libcerror_error_t **error )
442
0
{
443
0
  static char *function       = "libfvalue_binary_data_copy_to_utf8_string_with_index";
444
0
  uint32_t format_flags       = 0;
445
0
  uint32_t string_format_type = 0;
446
0
  uint32_t supported_flags    = 0;
447
448
0
  if( binary_data == NULL )
449
0
  {
450
0
    libcerror_error_set(
451
0
     error,
452
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
453
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
454
0
     "%s: invalid binary data.",
455
0
     function );
456
457
0
    return( -1 );
458
0
  }
459
0
  if( utf8_string == NULL )
460
0
  {
461
0
    libcerror_error_set(
462
0
     error,
463
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
464
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
465
0
     "%s: invalid UTF-8 string.",
466
0
     function );
467
468
0
    return( -1 );
469
0
  }
470
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
471
0
  {
472
0
    libcerror_error_set(
473
0
     error,
474
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
475
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
476
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
477
0
     function );
478
479
0
    return( -1 );
480
0
  }
481
0
  if( utf8_string_index == NULL )
482
0
  {
483
0
    libcerror_error_set(
484
0
     error,
485
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
486
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
487
0
     "%s: invalid UTF-8 string index.",
488
0
     function );
489
490
0
    return( -1 );
491
0
  }
492
0
  if( *utf8_string_index >= utf8_string_size )
493
0
  {
494
0
    libcerror_error_set(
495
0
     error,
496
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
497
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
498
0
     "%s: UTF-8 string is too small.",
499
0
     function );
500
501
0
    return( -1 );
502
0
  }
503
0
  supported_flags = 0x000000ffUL
504
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
505
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
506
507
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
508
0
  {
509
0
    libcerror_error_set(
510
0
     error,
511
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
512
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
513
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
514
0
     function,
515
0
     string_format_flags );
516
517
0
    return( -1 );
518
0
  }
519
0
  string_format_type = string_format_flags & 0x000000ffUL;
520
521
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
522
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
523
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
524
0
  {
525
0
    libcerror_error_set(
526
0
     error,
527
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
528
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
529
0
     "%s: unsupported string format type.",
530
0
     function );
531
532
0
    return( -1 );
533
0
  }
534
0
  if( ( binary_data->data != NULL )
535
0
   && ( binary_data->data_size != 0 ) )
536
0
  {
537
0
    switch( string_format_type )
538
0
    {
539
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
540
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
541
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
542
543
0
        if( libuna_base16_stream_with_index_copy_from_byte_stream(
544
0
             utf8_string,
545
0
             utf8_string_size,
546
0
             utf8_string_index,
547
0
             binary_data->data,
548
0
             binary_data->data_size,
549
0
             format_flags,
550
0
             error ) != 1 )
551
0
        {
552
0
          libcerror_error_set(
553
0
           error,
554
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
555
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
556
0
           "%s: unable to copy base16 formatted binary data to UTF-8 string.",
557
0
           function );
558
559
0
          return( -1 );
560
0
        }
561
0
        break;
562
563
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
564
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
565
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
566
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
567
568
0
        if( libuna_base32_stream_with_index_copy_from_byte_stream(
569
0
             utf8_string,
570
0
             utf8_string_size,
571
0
             utf8_string_index,
572
0
             binary_data->data,
573
0
             binary_data->data_size,
574
0
             format_flags,
575
0
             error ) != 1 )
576
0
        {
577
0
          libcerror_error_set(
578
0
           error,
579
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
580
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
581
0
           "%s: unable to copy base32 formatted binary data to UTF-8 string.",
582
0
           function );
583
584
0
          return( -1 );
585
0
        }
586
0
        break;
587
588
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
589
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
590
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
591
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
592
593
0
        if( libuna_base64_stream_with_index_copy_from_byte_stream(
594
0
             utf8_string,
595
0
             utf8_string_size,
596
0
             utf8_string_index,
597
0
             binary_data->data,
598
0
             binary_data->data_size,
599
0
             format_flags,
600
0
             error ) != 1 )
601
0
        {
602
0
          libcerror_error_set(
603
0
           error,
604
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
605
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
606
0
           "%s: unable to copy base64 formatted binary data to UTF-8 string.",
607
0
           function );
608
609
0
          return( -1 );
610
0
        }
611
0
        break;
612
0
    }
613
0
  }
614
0
  utf8_string[ *utf8_string_index ] = 0;
615
616
0
  *utf8_string_index += 1;
617
618
0
  return( 1 );
619
0
}
620
621
/* Retrieves the size of an UTF-16 formatted string of the binary data
622
 * Returns 1 if successful or -1 on error
623
 */
624
int libfvalue_binary_data_get_utf16_string_size(
625
     libfvalue_binary_data_t *binary_data,
626
     size_t *utf16_string_size,
627
     uint32_t string_format_flags,
628
     libcerror_error_t **error )
629
0
{
630
0
  static char *function       = "libfvalue_binary_data_get_utf16_string_size";
631
0
  uint32_t format_flags       = 0;
632
0
  uint32_t string_format_type = 0;
633
0
  uint32_t supported_flags    = 0;
634
635
0
  if( binary_data == NULL )
636
0
  {
637
0
    libcerror_error_set(
638
0
     error,
639
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
640
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
641
0
     "%s: invalid binary data.",
642
0
     function );
643
644
0
    return( -1 );
645
0
  }
646
0
  if( utf16_string_size == NULL )
647
0
  {
648
0
    libcerror_error_set(
649
0
     error,
650
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
651
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
652
0
     "%s: invalid UTF-16 string size.",
653
0
     function );
654
655
0
    return( -1 );
656
0
  }
657
0
  supported_flags = 0x000000ffUL
658
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
659
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
660
661
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
662
0
  {
663
0
    libcerror_error_set(
664
0
     error,
665
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
666
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
667
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
668
0
     function,
669
0
     string_format_flags );
670
671
0
    return( -1 );
672
0
  }
673
0
  string_format_type = string_format_flags & 0x000000ffUL;
674
675
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
676
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
677
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
678
0
  {
679
0
    libcerror_error_set(
680
0
     error,
681
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
682
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
683
0
     "%s: unsupported string format type.",
684
0
     function );
685
686
0
    return( -1 );
687
0
  }
688
0
  *utf16_string_size = 0;
689
690
0
  if( ( binary_data->data != NULL )
691
0
   && ( binary_data->data_size != 0 ) )
692
0
  {
693
0
    switch( string_format_type )
694
0
    {
695
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
696
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
697
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
698
699
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
700
0
        {
701
0
          format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
702
0
        }
703
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
704
0
        {
705
0
          format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
706
0
        }
707
0
        else
708
0
        {
709
0
          libcerror_error_set(
710
0
           error,
711
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
712
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
713
0
           "%s: unsupported host byte order.",
714
0
           function );
715
716
0
          return( -1 );
717
0
        }
718
0
        if( libuna_base16_stream_size_from_byte_stream(
719
0
             binary_data->data,
720
0
             binary_data->data_size,
721
0
             utf16_string_size,
722
0
             format_flags,
723
0
             error ) != 1 )
724
0
        {
725
0
          libcerror_error_set(
726
0
           error,
727
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
728
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
729
0
           "%s: unable to determine size of UTF-16 string of base16 formatted binary data.",
730
0
           function );
731
732
0
          return( -1 );
733
0
        }
734
0
        break;
735
736
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
737
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
738
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
739
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
740
741
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
742
0
        {
743
0
          format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
744
0
        }
745
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
746
0
        {
747
0
          format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
748
0
        }
749
0
        else
750
0
        {
751
0
          libcerror_error_set(
752
0
           error,
753
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
754
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
755
0
           "%s: unsupported host byte order.",
756
0
           function );
757
758
0
          return( -1 );
759
0
        }
760
0
        if( libuna_base32_stream_size_from_byte_stream(
761
0
             binary_data->data,
762
0
             binary_data->data_size,
763
0
             utf16_string_size,
764
0
             format_flags,
765
0
             error ) != 1 )
766
0
        {
767
0
          libcerror_error_set(
768
0
           error,
769
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
770
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
771
0
           "%s: unable to determine size of UTF-16 string of base32 formatted binary data.",
772
0
           function );
773
774
0
          return( -1 );
775
0
        }
776
0
        break;
777
778
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
779
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
780
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
781
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
782
783
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
784
0
        {
785
0
          format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
786
0
        }
787
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
788
0
        {
789
0
          format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
790
0
        }
791
0
        else
792
0
        {
793
0
          libcerror_error_set(
794
0
           error,
795
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
796
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
797
0
           "%s: unsupported host byte order.",
798
0
           function );
799
800
0
          return( -1 );
801
0
        }
802
0
        if( libuna_base64_stream_size_from_byte_stream(
803
0
             binary_data->data,
804
0
             binary_data->data_size,
805
0
             utf16_string_size,
806
0
             format_flags,
807
0
             error ) != 1 )
808
0
        {
809
0
          libcerror_error_set(
810
0
           error,
811
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
812
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
813
0
           "%s: unable to determine size of UTF-16 string of base64 formatted binary data.",
814
0
           function );
815
816
0
          return( -1 );
817
0
        }
818
0
        break;
819
0
    }
820
    /* The size returned is the size of the byte stream and the size needed
821
     * should be the number of characters
822
     */
823
0
    *utf16_string_size /= sizeof( uint16_t );
824
0
  }
825
  /* Add space for the end-of-string character
826
   */
827
0
  *utf16_string_size += 1;
828
829
0
  return( 1 );
830
0
}
831
832
/* Copies the binary data to an UTF-16 encoded string
833
 * Returns 1 if successful or -1 on error
834
 */
835
int libfvalue_binary_data_copy_to_utf16_string_with_index(
836
     libfvalue_binary_data_t *binary_data,
837
     uint16_t *utf16_string,
838
     size_t utf16_string_size,
839
     size_t *utf16_string_index,
840
     uint32_t string_format_flags,
841
     libcerror_error_t **error )
842
0
{
843
0
  static char *function       = "libfvalue_binary_data_copy_to_utf16_string_with_index";
844
0
  size_t string_index         = 0;
845
0
  size_t string_size          = 0;
846
0
  uint32_t format_flags       = 0;
847
0
  uint32_t string_format_type = 0;
848
0
  uint32_t supported_flags    = 0;
849
850
0
  if( binary_data == NULL )
851
0
  {
852
0
    libcerror_error_set(
853
0
     error,
854
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
855
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
856
0
     "%s: invalid binary data.",
857
0
     function );
858
859
0
    return( -1 );
860
0
  }
861
0
  if( utf16_string == NULL )
862
0
  {
863
0
    libcerror_error_set(
864
0
     error,
865
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
866
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
867
0
     "%s: invalid UTF-16 string.",
868
0
     function );
869
870
0
    return( -1 );
871
0
  }
872
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
873
0
  {
874
0
    libcerror_error_set(
875
0
     error,
876
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
877
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
878
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
879
0
     function );
880
881
0
    return( -1 );
882
0
  }
883
0
  if( utf16_string_index == NULL )
884
0
  {
885
0
    libcerror_error_set(
886
0
     error,
887
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
888
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
889
0
     "%s: invalid UTF-16 string index.",
890
0
     function );
891
892
0
    return( -1 );
893
0
  }
894
0
  if( *utf16_string_index >= utf16_string_size )
895
0
  {
896
0
    libcerror_error_set(
897
0
     error,
898
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
899
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
900
0
     "%s: UTF-16 string is too small.",
901
0
     function );
902
903
0
    return( -1 );
904
0
  }
905
0
  supported_flags = 0x000000ffUL
906
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
907
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
908
909
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
910
0
  {
911
0
    libcerror_error_set(
912
0
     error,
913
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
914
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
915
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
916
0
     function,
917
0
     string_format_flags );
918
919
0
    return( -1 );
920
0
  }
921
0
  string_format_type = string_format_flags & 0x000000ffUL;
922
923
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
924
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
925
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
926
0
  {
927
0
    libcerror_error_set(
928
0
     error,
929
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
930
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
931
0
     "%s: unsupported string format type.",
932
0
     function );
933
934
0
    return( -1 );
935
0
  }
936
0
  if( ( binary_data->data != NULL )
937
0
   && ( binary_data->data_size != 0 ) )
938
0
  {
939
0
    string_index = *utf16_string_index * sizeof( uint16_t );
940
0
    string_size  = utf16_string_size * sizeof( uint16_t );
941
942
0
    switch( string_format_type )
943
0
    {
944
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
945
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
946
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
947
948
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
949
0
        {
950
0
          format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
951
0
        }
952
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
953
0
        {
954
0
          format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
955
0
        }
956
0
        else
957
0
        {
958
0
          libcerror_error_set(
959
0
           error,
960
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
961
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
962
0
           "%s: unsupported host byte order.",
963
0
           function );
964
965
0
          return( -1 );
966
0
        }
967
0
        if( libuna_base16_stream_with_index_copy_from_byte_stream(
968
0
             (uint8_t *) utf16_string,
969
0
             string_size,
970
0
             &string_index,
971
0
             binary_data->data,
972
0
             binary_data->data_size,
973
0
             format_flags,
974
0
             error ) != 1 )
975
0
        {
976
0
          libcerror_error_set(
977
0
           error,
978
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
979
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
980
0
           "%s: unable to copy base16 formatted binary data to UTF-16 string.",
981
0
           function );
982
983
0
          return( -1 );
984
0
        }
985
0
        break;
986
987
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
988
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
989
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
990
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
991
992
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
993
0
        {
994
0
          format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
995
0
        }
996
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
997
0
        {
998
0
          format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
999
0
        }
1000
0
        else
1001
0
        {
1002
0
          libcerror_error_set(
1003
0
           error,
1004
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1005
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1006
0
           "%s: unsupported host byte order.",
1007
0
           function );
1008
1009
0
          return( -1 );
1010
0
        }
1011
0
        if( libuna_base32_stream_with_index_copy_from_byte_stream(
1012
0
             (uint8_t *) utf16_string,
1013
0
             string_size,
1014
0
             &string_index,
1015
0
             binary_data->data,
1016
0
             binary_data->data_size,
1017
0
             format_flags,
1018
0
             error ) != 1 )
1019
0
        {
1020
0
          libcerror_error_set(
1021
0
           error,
1022
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1023
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1024
0
           "%s: unable to copy base32 formatted binary data to UTF-16 string.",
1025
0
           function );
1026
1027
0
          return( -1 );
1028
0
        }
1029
0
        break;
1030
1031
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
1032
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
1033
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
1034
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
1035
1036
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
1037
0
        {
1038
0
          format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
1039
0
        }
1040
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
1041
0
        {
1042
0
          format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
1043
0
        }
1044
0
        else
1045
0
        {
1046
0
          libcerror_error_set(
1047
0
           error,
1048
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1049
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1050
0
           "%s: unsupported host byte order.",
1051
0
           function );
1052
1053
0
          return( -1 );
1054
0
        }
1055
0
        if( libuna_base64_stream_with_index_copy_from_byte_stream(
1056
0
             (uint8_t *) utf16_string,
1057
0
             string_size,
1058
0
             &string_index,
1059
0
             binary_data->data,
1060
0
             binary_data->data_size,
1061
0
             format_flags,
1062
0
             error ) != 1 )
1063
0
        {
1064
0
          libcerror_error_set(
1065
0
           error,
1066
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1067
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1068
0
           "%s: unable to copy base64 formatted binary data to UTF-16 string.",
1069
0
           function );
1070
1071
0
          return( -1 );
1072
0
        }
1073
0
        break;
1074
0
    }
1075
0
    *utf16_string_index = string_index / sizeof( uint16_t );
1076
0
  }
1077
0
  utf16_string[ *utf16_string_index ] = 0;
1078
1079
0
  *utf16_string_index += 1;
1080
1081
0
  return( 1 );
1082
0
}
1083
1084
/* Retrieves the size of an UTF-32 formatted string of the binary data
1085
 * Returns 1 if successful or -1 on error
1086
 */
1087
int libfvalue_binary_data_get_utf32_string_size(
1088
     libfvalue_binary_data_t *binary_data,
1089
     size_t *utf32_string_size,
1090
     uint32_t string_format_flags,
1091
     libcerror_error_t **error )
1092
0
{
1093
0
  static char *function       = "libfvalue_binary_data_get_utf32_string_size";
1094
0
  uint32_t format_flags       = 0;
1095
0
  uint32_t string_format_type = 0;
1096
0
  uint32_t supported_flags    = 0;
1097
1098
0
  if( binary_data == NULL )
1099
0
  {
1100
0
    libcerror_error_set(
1101
0
     error,
1102
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1103
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1104
0
     "%s: invalid binary data.",
1105
0
     function );
1106
1107
0
    return( -1 );
1108
0
  }
1109
0
  if( utf32_string_size == NULL )
1110
0
  {
1111
0
    libcerror_error_set(
1112
0
     error,
1113
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1114
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1115
0
     "%s: invalid UTF-32 string size.",
1116
0
     function );
1117
1118
0
    return( -1 );
1119
0
  }
1120
0
  supported_flags = 0x000000ffUL
1121
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
1122
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
1123
1124
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1125
0
  {
1126
0
    libcerror_error_set(
1127
0
     error,
1128
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1129
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1130
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1131
0
     function,
1132
0
     string_format_flags );
1133
1134
0
    return( -1 );
1135
0
  }
1136
0
  string_format_type = string_format_flags & 0x000000ffUL;
1137
1138
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
1139
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
1140
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
1141
0
  {
1142
0
    libcerror_error_set(
1143
0
     error,
1144
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1145
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1146
0
     "%s: unsupported string format type.",
1147
0
     function );
1148
1149
0
    return( -1 );
1150
0
  }
1151
0
  *utf32_string_size = 0;
1152
1153
0
  if( ( binary_data->data != NULL )
1154
0
   && ( binary_data->data_size != 0 ) )
1155
0
  {
1156
0
    switch( string_format_type )
1157
0
    {
1158
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
1159
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
1160
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
1161
1162
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
1163
0
        {
1164
0
          format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1165
0
        }
1166
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
1167
0
        {
1168
0
          format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1169
0
        }
1170
0
        else
1171
0
        {
1172
0
          libcerror_error_set(
1173
0
           error,
1174
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1175
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1176
0
           "%s: unsupported host byte order.",
1177
0
           function );
1178
1179
0
          return( -1 );
1180
0
        }
1181
0
        if( libuna_base16_stream_size_from_byte_stream(
1182
0
             binary_data->data,
1183
0
             binary_data->data_size,
1184
0
             utf32_string_size,
1185
0
             format_flags,
1186
0
             error ) != 1 )
1187
0
        {
1188
0
          libcerror_error_set(
1189
0
           error,
1190
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1191
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1192
0
           "%s: unable to determine size of UTF-32 string of base16 formatted binary data.",
1193
0
           function );
1194
1195
0
          return( -1 );
1196
0
        }
1197
0
        break;
1198
1199
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
1200
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
1201
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
1202
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
1203
1204
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
1205
0
        {
1206
0
          format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1207
0
        }
1208
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
1209
0
        {
1210
0
          format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1211
0
        }
1212
0
        else
1213
0
        {
1214
0
          libcerror_error_set(
1215
0
           error,
1216
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1217
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1218
0
           "%s: unsupported host byte order.",
1219
0
           function );
1220
1221
0
          return( -1 );
1222
0
        }
1223
0
        if( libuna_base32_stream_size_from_byte_stream(
1224
0
             binary_data->data,
1225
0
             binary_data->data_size,
1226
0
             utf32_string_size,
1227
0
             format_flags,
1228
0
             error ) != 1 )
1229
0
        {
1230
0
          libcerror_error_set(
1231
0
           error,
1232
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1233
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1234
0
           "%s: unable to determine size of UTF-32 string of base32 formatted binary data.",
1235
0
           function );
1236
1237
0
          return( -1 );
1238
0
        }
1239
0
        break;
1240
1241
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
1242
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
1243
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
1244
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
1245
1246
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
1247
0
        {
1248
0
          format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1249
0
        }
1250
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
1251
0
        {
1252
0
          format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1253
0
        }
1254
0
        else
1255
0
        {
1256
0
          libcerror_error_set(
1257
0
           error,
1258
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1259
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1260
0
           "%s: unsupported host byte order.",
1261
0
           function );
1262
1263
0
          return( -1 );
1264
0
        }
1265
0
        if( libuna_base64_stream_size_from_byte_stream(
1266
0
             binary_data->data,
1267
0
             binary_data->data_size,
1268
0
             utf32_string_size,
1269
0
             format_flags,
1270
0
             error ) != 1 )
1271
0
        {
1272
0
          libcerror_error_set(
1273
0
           error,
1274
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1275
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1276
0
           "%s: unable to determine size of UTF-32 string of base64 formatted binary data.",
1277
0
           function );
1278
1279
0
          return( -1 );
1280
0
        }
1281
0
        break;
1282
0
    }
1283
    /* The size returned is the size of the byte stream and the size needed
1284
     * should be the number of characters
1285
     */
1286
0
    *utf32_string_size /= sizeof( uint32_t );
1287
0
  }
1288
  /* Add space for the end-of-string character
1289
   */
1290
0
  *utf32_string_size += 1;
1291
1292
0
  return( 1 );
1293
0
}
1294
1295
/* Copies the binary data to an UTF-32 encoded string
1296
 * Returns 1 if successful or -1 on error
1297
 */
1298
int libfvalue_binary_data_copy_to_utf32_string_with_index(
1299
     libfvalue_binary_data_t *binary_data,
1300
     uint32_t *utf32_string,
1301
     size_t utf32_string_size,
1302
     size_t *utf32_string_index,
1303
     uint32_t string_format_flags,
1304
     libcerror_error_t **error )
1305
0
{
1306
0
  static char *function       = "libfvalue_binary_data_copy_to_utf32_string_with_index";
1307
0
  size_t string_index         = 0;
1308
0
  size_t string_size          = 0;
1309
0
  uint32_t format_flags       = 0;
1310
0
  uint32_t string_format_type = 0;
1311
0
  uint32_t supported_flags    = 0;
1312
1313
0
  if( binary_data == NULL )
1314
0
  {
1315
0
    libcerror_error_set(
1316
0
     error,
1317
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1318
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1319
0
     "%s: invalid binary data.",
1320
0
     function );
1321
1322
0
    return( -1 );
1323
0
  }
1324
0
  if( utf32_string == NULL )
1325
0
  {
1326
0
    libcerror_error_set(
1327
0
     error,
1328
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1329
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1330
0
     "%s: invalid UTF-32 string.",
1331
0
     function );
1332
1333
0
    return( -1 );
1334
0
  }
1335
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
1336
0
  {
1337
0
    libcerror_error_set(
1338
0
     error,
1339
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1340
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1341
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
1342
0
     function );
1343
1344
0
    return( -1 );
1345
0
  }
1346
0
  if( utf32_string_index == NULL )
1347
0
  {
1348
0
    libcerror_error_set(
1349
0
     error,
1350
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1351
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1352
0
     "%s: invalid UTF-32 string index.",
1353
0
     function );
1354
1355
0
    return( -1 );
1356
0
  }
1357
0
  if( *utf32_string_index >= utf32_string_size )
1358
0
  {
1359
0
    libcerror_error_set(
1360
0
     error,
1361
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1362
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1363
0
     "%s: UTF-32 string is too small.",
1364
0
     function );
1365
1366
0
    return( -1 );
1367
0
  }
1368
0
  supported_flags = 0x000000ffUL
1369
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
1370
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
1371
1372
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1373
0
  {
1374
0
    libcerror_error_set(
1375
0
     error,
1376
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1377
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1378
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1379
0
     function,
1380
0
     string_format_flags );
1381
1382
0
    return( -1 );
1383
0
  }
1384
0
  string_format_type = string_format_flags & 0x000000ffUL;
1385
1386
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
1387
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
1388
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
1389
0
  {
1390
0
    libcerror_error_set(
1391
0
     error,
1392
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1393
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1394
0
     "%s: unsupported string format type.",
1395
0
     function );
1396
1397
0
    return( -1 );
1398
0
  }
1399
0
  if( ( binary_data->data != NULL )
1400
0
   && ( binary_data->data_size != 0 ) )
1401
0
  {
1402
0
    string_index = *utf32_string_index * sizeof( uint32_t );
1403
0
    string_size  = utf32_string_size * sizeof( uint32_t );
1404
1405
0
    switch( string_format_type )
1406
0
    {
1407
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
1408
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
1409
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
1410
1411
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
1412
0
        {
1413
0
          format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1414
0
        }
1415
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
1416
0
        {
1417
0
          format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1418
0
        }
1419
0
        else
1420
0
        {
1421
0
          libcerror_error_set(
1422
0
           error,
1423
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1424
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1425
0
           "%s: unsupported host byte order.",
1426
0
           function );
1427
1428
0
          return( -1 );
1429
0
        }
1430
0
        if( libuna_base16_stream_with_index_copy_from_byte_stream(
1431
0
             (uint8_t *) utf32_string,
1432
0
             string_size,
1433
0
             &string_index,
1434
0
             binary_data->data,
1435
0
             binary_data->data_size,
1436
0
             format_flags,
1437
0
             error ) != 1 )
1438
0
        {
1439
0
          libcerror_error_set(
1440
0
           error,
1441
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1442
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1443
0
           "%s: unable to copy base16 formatted binary data to UTF-32 string.",
1444
0
           function );
1445
1446
0
          return( -1 );
1447
0
        }
1448
0
        break;
1449
1450
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
1451
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
1452
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
1453
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
1454
1455
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
1456
0
        {
1457
0
          format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1458
0
        }
1459
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
1460
0
        {
1461
0
          format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1462
0
        }
1463
0
        else
1464
0
        {
1465
0
          libcerror_error_set(
1466
0
           error,
1467
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1468
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1469
0
           "%s: unsupported host byte order.",
1470
0
           function );
1471
1472
0
          return( -1 );
1473
0
        }
1474
0
        if( libuna_base32_stream_with_index_copy_from_byte_stream(
1475
0
             (uint8_t *) utf32_string,
1476
0
             string_size,
1477
0
             &string_index,
1478
0
             binary_data->data,
1479
0
             binary_data->data_size,
1480
0
             format_flags,
1481
0
             error ) != 1 )
1482
0
        {
1483
0
          libcerror_error_set(
1484
0
           error,
1485
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1486
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1487
0
           "%s: unable to copy base32 formatted binary data to UTF-32 string.",
1488
0
           function );
1489
1490
0
          return( -1 );
1491
0
        }
1492
0
        break;
1493
1494
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
1495
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
1496
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
1497
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
1498
1499
0
        if( _BYTE_STREAM_HOST_IS_ENDIAN_BIG )
1500
0
        {
1501
0
          format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1502
0
        }
1503
0
        else if( _BYTE_STREAM_HOST_IS_ENDIAN_LITTLE )
1504
0
        {
1505
0
          format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1506
0
        }
1507
0
        else
1508
0
        {
1509
0
          libcerror_error_set(
1510
0
           error,
1511
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1512
0
           LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1513
0
           "%s: unsupported host byte order.",
1514
0
           function );
1515
1516
0
          return( -1 );
1517
0
        }
1518
0
        if( libuna_base64_stream_with_index_copy_from_byte_stream(
1519
0
             (uint8_t *) utf32_string,
1520
0
             string_size,
1521
0
             &string_index,
1522
0
             binary_data->data,
1523
0
             binary_data->data_size,
1524
0
             format_flags,
1525
0
             error ) != 1 )
1526
0
        {
1527
0
          libcerror_error_set(
1528
0
           error,
1529
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1530
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1531
0
           "%s: unable to copy base64 formatted binary data to UTF-32 string.",
1532
0
           function );
1533
1534
0
          return( -1 );
1535
0
        }
1536
0
        break;
1537
0
    }
1538
0
    *utf32_string_index = string_index / sizeof( uint32_t );
1539
0
  }
1540
0
  utf32_string[ *utf32_string_index ] = 0;
1541
1542
0
  *utf32_string_index += 1;
1543
1544
0
  return( 1 );
1545
0
}
1546