Coverage Report

Created: 2026-07-10 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libewf/libfvalue/libfvalue_binary_data.c
Line
Count
Source
1
/*
2
 * Binary data value functions
3
 *
4
 * Copyright (C) 2010-2026, 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
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
700
        format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
701
#else
702
0
        format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
703
0
#endif
704
0
        if( libuna_base16_stream_size_from_byte_stream(
705
0
             binary_data->data,
706
0
             binary_data->data_size,
707
0
             utf16_string_size,
708
0
             format_flags,
709
0
             error ) != 1 )
710
0
        {
711
0
          libcerror_error_set(
712
0
           error,
713
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
714
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
715
0
           "%s: unable to determine size of UTF-16 string of base16 formatted binary data.",
716
0
           function );
717
718
0
          return( -1 );
719
0
        }
720
0
        break;
721
722
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
723
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
724
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
725
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
726
727
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
728
        format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
729
#else
730
0
        format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
731
0
#endif
732
0
        if( libuna_base32_stream_size_from_byte_stream(
733
0
             binary_data->data,
734
0
             binary_data->data_size,
735
0
             utf16_string_size,
736
0
             format_flags,
737
0
             error ) != 1 )
738
0
        {
739
0
          libcerror_error_set(
740
0
           error,
741
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
742
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
743
0
           "%s: unable to determine size of UTF-16 string of base32 formatted binary data.",
744
0
           function );
745
746
0
          return( -1 );
747
0
        }
748
0
        break;
749
750
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
751
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
752
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
753
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
754
755
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
756
        format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
757
#else
758
0
        format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
759
0
#endif
760
0
        if( libuna_base64_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 base64 formatted binary data.",
772
0
           function );
773
774
0
          return( -1 );
775
0
        }
776
0
        break;
777
0
    }
778
    /* The size returned is the size of the byte stream and the size needed
779
     * should be the number of characters
780
     */
781
0
    *utf16_string_size /= sizeof( uint16_t );
782
0
  }
783
  /* Add space for the end-of-string character
784
   */
785
0
  *utf16_string_size += 1;
786
787
0
  return( 1 );
788
0
}
789
790
/* Copies the binary data to an UTF-16 encoded string
791
 * Returns 1 if successful or -1 on error
792
 */
793
int libfvalue_binary_data_copy_to_utf16_string_with_index(
794
     libfvalue_binary_data_t *binary_data,
795
     uint16_t *utf16_string,
796
     size_t utf16_string_size,
797
     size_t *utf16_string_index,
798
     uint32_t string_format_flags,
799
     libcerror_error_t **error )
800
0
{
801
0
  static char *function       = "libfvalue_binary_data_copy_to_utf16_string_with_index";
802
0
  size_t string_index         = 0;
803
0
  size_t string_size          = 0;
804
0
  uint32_t format_flags       = 0;
805
0
  uint32_t string_format_type = 0;
806
0
  uint32_t supported_flags    = 0;
807
808
0
  if( binary_data == NULL )
809
0
  {
810
0
    libcerror_error_set(
811
0
     error,
812
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
813
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
814
0
     "%s: invalid binary data.",
815
0
     function );
816
817
0
    return( -1 );
818
0
  }
819
0
  if( utf16_string == NULL )
820
0
  {
821
0
    libcerror_error_set(
822
0
     error,
823
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
824
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
825
0
     "%s: invalid UTF-16 string.",
826
0
     function );
827
828
0
    return( -1 );
829
0
  }
830
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
831
0
  {
832
0
    libcerror_error_set(
833
0
     error,
834
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
835
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
836
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
837
0
     function );
838
839
0
    return( -1 );
840
0
  }
841
0
  if( utf16_string_index == NULL )
842
0
  {
843
0
    libcerror_error_set(
844
0
     error,
845
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
846
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
847
0
     "%s: invalid UTF-16 string index.",
848
0
     function );
849
850
0
    return( -1 );
851
0
  }
852
0
  if( *utf16_string_index >= utf16_string_size )
853
0
  {
854
0
    libcerror_error_set(
855
0
     error,
856
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
857
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
858
0
     "%s: UTF-16 string is too small.",
859
0
     function );
860
861
0
    return( -1 );
862
0
  }
863
0
  supported_flags = 0x000000ffUL
864
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
865
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
866
867
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
868
0
  {
869
0
    libcerror_error_set(
870
0
     error,
871
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
872
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
873
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
874
0
     function,
875
0
     string_format_flags );
876
877
0
    return( -1 );
878
0
  }
879
0
  string_format_type = string_format_flags & 0x000000ffUL;
880
881
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
882
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
883
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
884
0
  {
885
0
    libcerror_error_set(
886
0
     error,
887
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
888
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
889
0
     "%s: unsupported string format type.",
890
0
     function );
891
892
0
    return( -1 );
893
0
  }
894
0
  if( ( binary_data->data != NULL )
895
0
   && ( binary_data->data_size != 0 ) )
896
0
  {
897
0
    string_index = *utf16_string_index * sizeof( uint16_t );
898
0
    string_size  = utf16_string_size * sizeof( uint16_t );
899
900
0
    switch( string_format_type )
901
0
    {
902
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
903
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
904
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
905
906
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
907
        format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
908
#else
909
0
        format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
910
0
#endif
911
0
        if( libuna_base16_stream_with_index_copy_from_byte_stream(
912
0
             (uint8_t *) utf16_string,
913
0
             string_size,
914
0
             &string_index,
915
0
             binary_data->data,
916
0
             binary_data->data_size,
917
0
             format_flags,
918
0
             error ) != 1 )
919
0
        {
920
0
          libcerror_error_set(
921
0
           error,
922
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
923
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
924
0
           "%s: unable to copy base16 formatted binary data to UTF-16 string.",
925
0
           function );
926
927
0
          return( -1 );
928
0
        }
929
0
        break;
930
931
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
932
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
933
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
934
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
935
936
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
937
        format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
938
#else
939
0
        format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
940
0
#endif
941
0
        if( libuna_base32_stream_with_index_copy_from_byte_stream(
942
0
             (uint8_t *) utf16_string,
943
0
             string_size,
944
0
             &string_index,
945
0
             binary_data->data,
946
0
             binary_data->data_size,
947
0
             format_flags,
948
0
             error ) != 1 )
949
0
        {
950
0
          libcerror_error_set(
951
0
           error,
952
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
953
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
954
0
           "%s: unable to copy base32 formatted binary data to UTF-16 string.",
955
0
           function );
956
957
0
          return( -1 );
958
0
        }
959
0
        break;
960
961
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
962
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
963
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
964
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
965
966
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
967
        format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF16_BIG_ENDIAN;
968
#else
969
0
        format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN;
970
0
#endif
971
0
        if( libuna_base64_stream_with_index_copy_from_byte_stream(
972
0
             (uint8_t *) utf16_string,
973
0
             string_size,
974
0
             &string_index,
975
0
             binary_data->data,
976
0
             binary_data->data_size,
977
0
             format_flags,
978
0
             error ) != 1 )
979
0
        {
980
0
          libcerror_error_set(
981
0
           error,
982
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
983
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
984
0
           "%s: unable to copy base64 formatted binary data to UTF-16 string.",
985
0
           function );
986
987
0
          return( -1 );
988
0
        }
989
0
        break;
990
0
    }
991
0
    *utf16_string_index = string_index / sizeof( uint16_t );
992
0
  }
993
0
  utf16_string[ *utf16_string_index ] = 0;
994
995
0
  *utf16_string_index += 1;
996
997
0
  return( 1 );
998
0
}
999
1000
/* Retrieves the size of an UTF-32 formatted string of the binary data
1001
 * Returns 1 if successful or -1 on error
1002
 */
1003
int libfvalue_binary_data_get_utf32_string_size(
1004
     libfvalue_binary_data_t *binary_data,
1005
     size_t *utf32_string_size,
1006
     uint32_t string_format_flags,
1007
     libcerror_error_t **error )
1008
0
{
1009
0
  static char *function       = "libfvalue_binary_data_get_utf32_string_size";
1010
0
  uint32_t format_flags       = 0;
1011
0
  uint32_t string_format_type = 0;
1012
0
  uint32_t supported_flags    = 0;
1013
1014
0
  if( binary_data == NULL )
1015
0
  {
1016
0
    libcerror_error_set(
1017
0
     error,
1018
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1019
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1020
0
     "%s: invalid binary data.",
1021
0
     function );
1022
1023
0
    return( -1 );
1024
0
  }
1025
0
  if( utf32_string_size == NULL )
1026
0
  {
1027
0
    libcerror_error_set(
1028
0
     error,
1029
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1030
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1031
0
     "%s: invalid UTF-32 string size.",
1032
0
     function );
1033
1034
0
    return( -1 );
1035
0
  }
1036
0
  supported_flags = 0x000000ffUL
1037
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
1038
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
1039
1040
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1041
0
  {
1042
0
    libcerror_error_set(
1043
0
     error,
1044
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1045
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1046
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1047
0
     function,
1048
0
     string_format_flags );
1049
1050
0
    return( -1 );
1051
0
  }
1052
0
  string_format_type = string_format_flags & 0x000000ffUL;
1053
1054
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
1055
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
1056
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
1057
0
  {
1058
0
    libcerror_error_set(
1059
0
     error,
1060
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1061
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1062
0
     "%s: unsupported string format type.",
1063
0
     function );
1064
1065
0
    return( -1 );
1066
0
  }
1067
0
  *utf32_string_size = 0;
1068
1069
0
  if( ( binary_data->data != NULL )
1070
0
   && ( binary_data->data_size != 0 ) )
1071
0
  {
1072
0
    switch( string_format_type )
1073
0
    {
1074
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
1075
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
1076
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
1077
1078
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
1079
        format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1080
#elif _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_LITTLE
1081
        format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1082
#else
1083
#error "Unsupported middle-endian host byte-order"
1084
#endif
1085
0
        if( libuna_base16_stream_size_from_byte_stream(
1086
0
             binary_data->data,
1087
0
             binary_data->data_size,
1088
0
             utf32_string_size,
1089
0
             format_flags,
1090
0
             error ) != 1 )
1091
0
        {
1092
0
          libcerror_error_set(
1093
0
           error,
1094
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1095
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1096
0
           "%s: unable to determine size of UTF-32 string of base16 formatted binary data.",
1097
0
           function );
1098
1099
0
          return( -1 );
1100
0
        }
1101
0
        break;
1102
1103
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
1104
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
1105
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
1106
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
1107
1108
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
1109
        format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1110
#elif _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_LITTLE
1111
        format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1112
#else
1113
#error "Unsupported middle-endian host byte-order"
1114
#endif
1115
0
        if( libuna_base32_stream_size_from_byte_stream(
1116
0
             binary_data->data,
1117
0
             binary_data->data_size,
1118
0
             utf32_string_size,
1119
0
             format_flags,
1120
0
             error ) != 1 )
1121
0
        {
1122
0
          libcerror_error_set(
1123
0
           error,
1124
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1125
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1126
0
           "%s: unable to determine size of UTF-32 string of base32 formatted binary data.",
1127
0
           function );
1128
1129
0
          return( -1 );
1130
0
        }
1131
0
        break;
1132
1133
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
1134
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
1135
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
1136
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
1137
1138
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
1139
        format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1140
#elif _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_LITTLE
1141
        format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1142
#else
1143
#error "Unsupported middle-endian host byte-order"
1144
#endif
1145
0
        if( libuna_base64_stream_size_from_byte_stream(
1146
0
             binary_data->data,
1147
0
             binary_data->data_size,
1148
0
             utf32_string_size,
1149
0
             format_flags,
1150
0
             error ) != 1 )
1151
0
        {
1152
0
          libcerror_error_set(
1153
0
           error,
1154
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1155
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1156
0
           "%s: unable to determine size of UTF-32 string of base64 formatted binary data.",
1157
0
           function );
1158
1159
0
          return( -1 );
1160
0
        }
1161
0
        break;
1162
0
    }
1163
    /* The size returned is the size of the byte stream and the size needed
1164
     * should be the number of characters
1165
     */
1166
0
    *utf32_string_size /= sizeof( uint32_t );
1167
0
  }
1168
  /* Add space for the end-of-string character
1169
   */
1170
0
  *utf32_string_size += 1;
1171
1172
0
  return( 1 );
1173
0
}
1174
1175
/* Copies the binary data to an UTF-32 encoded string
1176
 * Returns 1 if successful or -1 on error
1177
 */
1178
int libfvalue_binary_data_copy_to_utf32_string_with_index(
1179
     libfvalue_binary_data_t *binary_data,
1180
     uint32_t *utf32_string,
1181
     size_t utf32_string_size,
1182
     size_t *utf32_string_index,
1183
     uint32_t string_format_flags,
1184
     libcerror_error_t **error )
1185
0
{
1186
0
  static char *function       = "libfvalue_binary_data_copy_to_utf32_string_with_index";
1187
0
  size_t string_index         = 0;
1188
0
  size_t string_size          = 0;
1189
0
  uint32_t format_flags       = 0;
1190
0
  uint32_t string_format_type = 0;
1191
0
  uint32_t supported_flags    = 0;
1192
1193
0
  if( binary_data == NULL )
1194
0
  {
1195
0
    libcerror_error_set(
1196
0
     error,
1197
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1198
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1199
0
     "%s: invalid binary data.",
1200
0
     function );
1201
1202
0
    return( -1 );
1203
0
  }
1204
0
  if( utf32_string == NULL )
1205
0
  {
1206
0
    libcerror_error_set(
1207
0
     error,
1208
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1209
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1210
0
     "%s: invalid UTF-32 string.",
1211
0
     function );
1212
1213
0
    return( -1 );
1214
0
  }
1215
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
1216
0
  {
1217
0
    libcerror_error_set(
1218
0
     error,
1219
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1220
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1221
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
1222
0
     function );
1223
1224
0
    return( -1 );
1225
0
  }
1226
0
  if( utf32_string_index == NULL )
1227
0
  {
1228
0
    libcerror_error_set(
1229
0
     error,
1230
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1231
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1232
0
     "%s: invalid UTF-32 string index.",
1233
0
     function );
1234
1235
0
    return( -1 );
1236
0
  }
1237
0
  if( *utf32_string_index >= utf32_string_size )
1238
0
  {
1239
0
    libcerror_error_set(
1240
0
     error,
1241
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1242
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1243
0
     "%s: UTF-32 string is too small.",
1244
0
     function );
1245
1246
0
    return( -1 );
1247
0
  }
1248
0
  supported_flags = 0x000000ffUL
1249
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_LOWER
1250
0
                  | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
1251
1252
0
  if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1253
0
  {
1254
0
    libcerror_error_set(
1255
0
     error,
1256
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1257
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1258
0
     "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1259
0
     function,
1260
0
     string_format_flags );
1261
1262
0
    return( -1 );
1263
0
  }
1264
0
  string_format_type = string_format_flags & 0x000000ffUL;
1265
1266
0
  if( ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16 )
1267
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32 )
1268
0
   && ( string_format_type != LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64 ) )
1269
0
  {
1270
0
    libcerror_error_set(
1271
0
     error,
1272
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1273
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1274
0
     "%s: unsupported string format type.",
1275
0
     function );
1276
1277
0
    return( -1 );
1278
0
  }
1279
0
  if( ( binary_data->data != NULL )
1280
0
   && ( binary_data->data_size != 0 ) )
1281
0
  {
1282
0
    string_index = *utf32_string_index * sizeof( uint32_t );
1283
0
    string_size  = utf32_string_size * sizeof( uint32_t );
1284
1285
0
    switch( string_format_type )
1286
0
    {
1287
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16:
1288
0
        format_flags = LIBUNA_BASE16_VARIANT_CASE_UPPER
1289
0
               | LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE;
1290
1291
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
1292
        format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1293
#elif _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_LITTLE
1294
        format_flags |= LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1295
#else
1296
#error "Unsupported middle-endian host byte-order"
1297
#endif
1298
0
        if( libuna_base16_stream_with_index_copy_from_byte_stream(
1299
0
             (uint8_t *) utf32_string,
1300
0
             string_size,
1301
0
             &string_index,
1302
0
             binary_data->data,
1303
0
             binary_data->data_size,
1304
0
             format_flags,
1305
0
             error ) != 1 )
1306
0
        {
1307
0
          libcerror_error_set(
1308
0
           error,
1309
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1310
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1311
0
           "%s: unable to copy base16 formatted binary data to UTF-32 string.",
1312
0
           function );
1313
1314
0
          return( -1 );
1315
0
        }
1316
0
        break;
1317
1318
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE32:
1319
0
        format_flags = LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL
1320
0
               | LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE
1321
0
               | LIBUNA_BASE32_VARIANT_PADDING_REQUIRED;
1322
1323
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
1324
        format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1325
#elif _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_LITTLE
1326
        format_flags |= LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1327
#else
1328
#error "Unsupported middle-endian host byte-order"
1329
#endif
1330
0
        if( libuna_base32_stream_with_index_copy_from_byte_stream(
1331
0
             (uint8_t *) utf32_string,
1332
0
             string_size,
1333
0
             &string_index,
1334
0
             binary_data->data,
1335
0
             binary_data->data_size,
1336
0
             format_flags,
1337
0
             error ) != 1 )
1338
0
        {
1339
0
          libcerror_error_set(
1340
0
           error,
1341
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1342
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1343
0
           "%s: unable to copy base32 formatted binary data to UTF-32 string.",
1344
0
           function );
1345
1346
0
          return( -1 );
1347
0
        }
1348
0
        break;
1349
1350
0
      case LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE64:
1351
0
        format_flags = LIBUNA_BASE64_VARIANT_ALPHABET_NORMAL
1352
0
               | LIBUNA_BASE64_VARIANT_CHARACTER_LIMIT_NONE
1353
0
               | LIBUNA_BASE64_VARIANT_PADDING_REQUIRED;
1354
1355
#if _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_BIG
1356
        format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF32_BIG_ENDIAN;
1357
#elif _BYTE_STREAM_HOST_BYTE_ORDER == _BYTE_STREAM_ENDIAN_LITTLE
1358
        format_flags |= LIBUNA_BASE64_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN;
1359
#else
1360
#error "Unsupported middle-endian host byte-order"
1361
#endif
1362
0
        if( libuna_base64_stream_with_index_copy_from_byte_stream(
1363
0
             (uint8_t *) utf32_string,
1364
0
             string_size,
1365
0
             &string_index,
1366
0
             binary_data->data,
1367
0
             binary_data->data_size,
1368
0
             format_flags,
1369
0
             error ) != 1 )
1370
0
        {
1371
0
          libcerror_error_set(
1372
0
           error,
1373
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1374
0
           LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1375
0
           "%s: unable to copy base64 formatted binary data to UTF-32 string.",
1376
0
           function );
1377
1378
0
          return( -1 );
1379
0
        }
1380
0
        break;
1381
0
    }
1382
0
    *utf32_string_index = string_index / sizeof( uint32_t );
1383
0
  }
1384
0
  utf32_string[ *utf32_string_index ] = 0;
1385
1386
0
  *utf32_string_index += 1;
1387
1388
0
  return( 1 );
1389
0
}
1390