Coverage Report

Created: 2023-06-07 06:53

/src/liblnk/liblnk/liblnk_data_string.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Data string functions
3
 *
4
 * Copyright (C) 2009-2023, 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 <narrow_string.h>
26
#include <system_string.h>
27
#include <types.h>
28
#include <wide_string.h>
29
30
#include "liblnk_data_string.h"
31
#include "liblnk_debug.h"
32
#include "liblnk_definitions.h"
33
#include "liblnk_libbfio.h"
34
#include "liblnk_libcerror.h"
35
#include "liblnk_libcnotify.h"
36
#include "liblnk_libuna.h"
37
38
/* Creates a data string
39
 * Make sure the value data_string is referencing, is set to NULL
40
 * Returns 1 if successful or -1 on error
41
 */
42
int liblnk_data_string_initialize(
43
     liblnk_data_string_t **data_string,
44
     libcerror_error_t **error )
45
2.45k
{
46
2.45k
  static char *function = "liblnk_data_string_initialize";
47
48
2.45k
  if( data_string == NULL )
49
0
  {
50
0
    libcerror_error_set(
51
0
     error,
52
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
53
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
54
0
     "%s: invalid data string.",
55
0
     function );
56
57
0
    return( -1 );
58
0
  }
59
2.45k
  if( *data_string != NULL )
60
0
  {
61
0
    libcerror_error_set(
62
0
     error,
63
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
64
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
65
0
     "%s: invalid data string value already set.",
66
0
     function );
67
68
0
    return( -1 );
69
0
  }
70
2.45k
  *data_string = memory_allocate_structure(
71
2.45k
                  liblnk_data_string_t );
72
73
2.45k
  if( *data_string == NULL )
74
0
  {
75
0
    libcerror_error_set(
76
0
     error,
77
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
78
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
79
0
     "%s: unable to create data string.",
80
0
     function );
81
82
0
    goto on_error;
83
0
  }
84
2.45k
  if( memory_set(
85
2.45k
       *data_string,
86
2.45k
       0,
87
2.45k
       sizeof( liblnk_data_string_t ) ) == NULL )
88
0
  {
89
0
    libcerror_error_set(
90
0
     error,
91
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
92
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
93
0
     "%s: unable to clear data string.",
94
0
     function );
95
96
0
    goto on_error;
97
0
  }
98
2.45k
  return( 1 );
99
100
0
on_error:
101
0
  if( *data_string != NULL )
102
0
  {
103
0
    memory_free(
104
0
     *data_string );
105
106
0
    *data_string = NULL;
107
0
  }
108
0
  return( -1 );
109
2.45k
}
110
111
/* Frees a data string
112
 * Returns 1 if successful or -1 on error
113
 */
114
int liblnk_data_string_free(
115
     liblnk_data_string_t **data_string,
116
     libcerror_error_t **error )
117
2.45k
{
118
2.45k
  static char *function = "liblnk_data_string_free";
119
120
2.45k
  if( data_string == NULL )
121
0
  {
122
0
    libcerror_error_set(
123
0
     error,
124
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
125
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
126
0
     "%s: invalid data string.",
127
0
     function );
128
129
0
    return( -1 );
130
0
  }
131
2.45k
  if( *data_string != NULL )
132
2.45k
  {
133
2.45k
    if( ( *data_string )->data != NULL )
134
1.58k
    {
135
1.58k
      memory_free(
136
1.58k
       ( *data_string )->data );
137
1.58k
    }
138
2.45k
    memory_free(
139
2.45k
     *data_string );
140
141
2.45k
    *data_string = NULL;
142
2.45k
  }
143
2.45k
  return( 1 );
144
2.45k
}
145
146
/* Reads a data string
147
 * Returns 1 if successful or -1 on error
148
 */
149
int liblnk_data_string_read_data(
150
     liblnk_data_string_t *data_string,
151
     liblnk_io_handle_t *io_handle,
152
     const uint8_t *data,
153
     size_t data_size,
154
     libcerror_error_t **error )
155
0
{
156
0
  static char *function = "liblnk_data_string_read_data";
157
158
0
  if( data_string == NULL )
159
0
  {
160
0
    libcerror_error_set(
161
0
     error,
162
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
163
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
164
0
     "%s: invalid data string.",
165
0
     function );
166
167
0
    return( -1 );
168
0
  }
169
0
  if( data_string->data != NULL )
170
0
  {
171
0
    libcerror_error_set(
172
0
     error,
173
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
174
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
175
0
     "%s: invalid data string - data already set.",
176
0
     function );
177
178
0
    return( -1 );
179
0
  }
180
0
  if( io_handle == NULL )
181
0
  {
182
0
    libcerror_error_set(
183
0
     error,
184
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
185
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
186
0
     "%s: invalid IO handle.",
187
0
     function );
188
189
0
    return( -1 );
190
0
  }
191
0
  if( data == NULL )
192
0
  {
193
0
    libcerror_error_set(
194
0
     error,
195
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
196
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
197
0
     "%s: invalid data.",
198
0
     function );
199
200
0
    return( -1 );
201
0
  }
202
0
  if( ( data_size < 2 )
203
0
   || ( data_size > (size_t) SSIZE_MAX ) )
204
0
  {
205
0
    libcerror_error_set(
206
0
     error,
207
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
208
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
209
0
     "%s: invalid data size value out of bounds.",
210
0
     function );
211
212
0
    return( -1 );
213
0
  }
214
  /* Store is unicode value for internal use
215
   */
216
0
  data_string->is_unicode = io_handle->is_unicode;
217
218
0
  byte_stream_copy_to_uint16_little_endian(
219
0
   data,
220
0
   data_string->data_size );
221
222
#if defined( HAVE_DEBUG_OUTPUT )
223
  if( libcnotify_verbose != 0 )
224
  {
225
    libcnotify_printf(
226
     "%s: data string size\t\t: %" PRIzd "\n",
227
     function,
228
     data_string->data_size );
229
  }
230
#endif
231
0
  if( data_string->data_size > 0 )
232
0
  {
233
    /* The size contains the number of characters
234
     * a Unicode (UTF-16) string requires 2 bytes per character
235
     */
236
0
    if( data_string->is_unicode != 0 )
237
0
    {
238
0
      if( data_string->data_size > ( ( data_size - 2 ) / 2 ) )
239
0
      {
240
0
        libcerror_error_set(
241
0
         error,
242
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
243
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
244
0
         "%s: invalid data string size value out of bounds.",
245
0
         function );
246
247
0
        goto on_error;
248
0
      }
249
0
      data_string->data_size *= 2;
250
0
    }
251
0
    else
252
0
    {
253
0
      if( data_string->data_size > ( data_size - 2 ) )
254
0
      {
255
0
        libcerror_error_set(
256
0
         error,
257
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
258
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
259
0
         "%s: invalid data string size value out of bounds.",
260
0
         function );
261
262
0
        goto on_error;
263
0
      }
264
0
    }
265
0
    if( data_string->data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
266
0
    {
267
0
      libcerror_error_set(
268
0
       error,
269
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
270
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
271
0
       "%s: invalid data string size value exceed maximum allocation size.",
272
0
       function );
273
274
0
      goto on_error;
275
0
    }
276
0
    data_string->data = (uint8_t *) memory_allocate(
277
0
                                     sizeof( uint8_t ) * data_string->data_size );
278
279
0
    if( data_string->data == NULL )
280
0
    {
281
0
      libcerror_error_set(
282
0
       error,
283
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
284
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
285
0
       "%s: unable to create data string data.",
286
0
       function );
287
288
0
      goto on_error;
289
0
    }
290
0
    if( memory_copy(
291
0
         data_string->data,
292
0
         &( data[ 2 ] ),
293
0
         data_string->data_size ) == NULL )
294
0
    {
295
0
      libcerror_error_set(
296
0
       error,
297
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
298
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
299
0
       "%s: unable to copy data string data.",
300
0
       function );
301
302
0
      goto on_error;
303
0
    }
304
0
    if( data_string->data == NULL )
305
0
    {
306
0
      libcerror_error_set(
307
0
       error,
308
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
309
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
310
0
       "%s: unable to create data string data.",
311
0
       function );
312
313
0
      goto on_error;
314
0
    }
315
#if defined( HAVE_DEBUG_OUTPUT )
316
    if( libcnotify_verbose != 0 )
317
    {
318
      libcnotify_printf(
319
       "%s: data string data:\n",
320
       function );
321
      libcnotify_print_data(
322
       data_string->data,
323
       data_string->data_size,
324
       0 );
325
    }
326
#endif
327
#if defined( HAVE_DEBUG_OUTPUT )
328
    if( libcnotify_verbose != 0 )
329
    {
330
      if( data_string->is_unicode != 0 )
331
      {
332
        if( liblnk_debug_print_utf16_string_value(
333
             function,
334
             "data string\t\t\t",
335
             data_string->data,
336
             data_string->data_size,
337
             LIBUNA_ENDIAN_LITTLE,
338
             error ) != 1 )
339
        {
340
          libcerror_error_set(
341
           error,
342
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
343
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
344
           "%s: unable to print UTF-16 string value.",
345
           function );
346
347
          goto on_error;
348
        }
349
      }
350
      else
351
      {
352
        if( liblnk_debug_print_string_value(
353
             function,
354
             "data string\t\t\t",
355
             data_string->data,
356
             data_string->data_size,
357
             io_handle->ascii_codepage,
358
             error ) != 1 )
359
        {
360
          libcerror_error_set(
361
           error,
362
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
363
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
364
           "%s: unable to print string value.",
365
           function );
366
367
          goto on_error;
368
        }
369
      }
370
      libcnotify_printf(
371
       "\n" );
372
    }
373
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
374
0
  }
375
0
  return( 1 );
376
377
0
on_error:
378
0
  if( data_string->data != NULL )
379
0
  {
380
0
    memory_free(
381
0
     data_string->data );
382
383
0
    data_string->data = NULL;
384
0
  }
385
0
  return( -1 );
386
0
}
387
388
/* Reads a data string
389
 * Returns 1 if successful or -1 on error
390
 */
391
int liblnk_data_string_read_file_io_handle(
392
     liblnk_data_string_t *data_string,
393
     liblnk_io_handle_t *io_handle,
394
     libbfio_handle_t *file_io_handle,
395
     off64_t file_offset,
396
     libcerror_error_t **error )
397
408
{
398
408
  uint8_t data_string_size_data[ 2 ];
399
400
408
  static char *function = "liblnk_data_string_read_file_io_handle";
401
408
  ssize_t read_count    = 0;
402
403
408
  if( data_string == NULL )
404
0
  {
405
0
    libcerror_error_set(
406
0
     error,
407
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
408
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
409
0
     "%s: invalid data string.",
410
0
     function );
411
412
0
    return( -1 );
413
0
  }
414
408
  if( data_string->data != NULL )
415
0
  {
416
0
    libcerror_error_set(
417
0
     error,
418
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
419
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
420
0
     "%s: invalid data string - data already set.",
421
0
     function );
422
423
0
    return( -1 );
424
0
  }
425
408
  if( io_handle == NULL )
426
0
  {
427
0
    libcerror_error_set(
428
0
     error,
429
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
430
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
431
0
     "%s: invalid IO handle.",
432
0
     function );
433
434
0
    return( -1 );
435
0
  }
436
  /* Store is unicode value for internal use
437
   */
438
408
  data_string->is_unicode = io_handle->is_unicode;
439
440
#if defined( HAVE_DEBUG_OUTPUT )
441
  if( libcnotify_verbose != 0 )
442
  {
443
    libcnotify_printf(
444
     "%s: reading data string at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
445
     function,
446
     file_offset,
447
     file_offset );
448
  }
449
#endif
450
408
  read_count = libbfio_handle_read_buffer_at_offset(
451
408
                file_io_handle,
452
408
                data_string_size_data,
453
408
                2,
454
408
                file_offset,
455
408
                error );
456
457
408
  if( read_count != (ssize_t) 2 )
458
165
  {
459
165
    libcerror_error_set(
460
165
     error,
461
165
     LIBCERROR_ERROR_DOMAIN_IO,
462
165
     LIBCERROR_IO_ERROR_READ_FAILED,
463
165
     "%s: unable to read data string size at offset: %" PRIi64 " (0x%08" PRIx64 ").",
464
165
     function,
465
165
     file_offset,
466
165
     file_offset );
467
468
165
    goto on_error;
469
165
  }
470
243
  byte_stream_copy_to_uint16_little_endian(
471
243
   data_string_size_data,
472
243
   data_string->data_size );
473
474
#if defined( HAVE_DEBUG_OUTPUT )
475
  if( libcnotify_verbose != 0 )
476
  {
477
    libcnotify_printf(
478
     "%s: data string size\t\t: %" PRIzd "\n",
479
     function,
480
     data_string->data_size );
481
  }
482
#endif
483
243
  if( data_string->data_size > 0 )
484
154
  {
485
    /* The size contains the number of characters
486
     * a Unicode (UTF-16) string requires 2 bytes per character
487
     */
488
154
    if( data_string->is_unicode != 0 )
489
112
    {
490
112
      data_string->data_size *= 2;
491
112
    }
492
154
    if( data_string->data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
493
0
    {
494
0
      libcerror_error_set(
495
0
       error,
496
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
497
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
498
0
       "%s: invalid data string size value exceed maximum allocation size.",
499
0
       function );
500
501
0
      goto on_error;
502
0
    }
503
154
    data_string->data = (uint8_t *) memory_allocate(
504
154
                                     sizeof( uint8_t ) * data_string->data_size );
505
506
154
    if( data_string->data == NULL )
507
0
    {
508
0
      libcerror_error_set(
509
0
       error,
510
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
511
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
512
0
       "%s: unable to create data string data.",
513
0
       function );
514
515
0
      goto on_error;
516
0
    }
517
154
    read_count = libbfio_handle_read_buffer(
518
154
                  file_io_handle,
519
154
                  data_string->data,
520
154
                  data_string->data_size,
521
154
                  error );
522
523
154
    if( read_count != (ssize_t) data_string->data_size )
524
28
    {
525
28
      libcerror_error_set(
526
28
       error,
527
28
       LIBCERROR_ERROR_DOMAIN_IO,
528
28
       LIBCERROR_IO_ERROR_READ_FAILED,
529
28
       "%s: unable to read data string data.",
530
28
       function );
531
532
28
      goto on_error;
533
28
    }
534
#if defined( HAVE_DEBUG_OUTPUT )
535
    if( libcnotify_verbose != 0 )
536
    {
537
      libcnotify_printf(
538
       "%s: data string data:\n",
539
       function );
540
      libcnotify_print_data(
541
       data_string->data,
542
       data_string->data_size,
543
       0 );
544
    }
545
#endif
546
#if defined( HAVE_DEBUG_OUTPUT )
547
    if( libcnotify_verbose != 0 )
548
    {
549
      if( data_string->is_unicode != 0 )
550
      {
551
        if( liblnk_debug_print_utf16_string_value(
552
             function,
553
             "data string\t\t\t",
554
             data_string->data,
555
             data_string->data_size,
556
             LIBUNA_ENDIAN_LITTLE,
557
             error ) != 1 )
558
        {
559
          libcerror_error_set(
560
           error,
561
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
562
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
563
           "%s: unable to print UTF-16 string value.",
564
           function );
565
566
          goto on_error;
567
        }
568
      }
569
      else
570
      {
571
        if( liblnk_debug_print_string_value(
572
             function,
573
             "data string\t\t\t",
574
             data_string->data,
575
             data_string->data_size,
576
             io_handle->ascii_codepage,
577
             error ) != 1 )
578
        {
579
          libcerror_error_set(
580
           error,
581
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
582
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
583
           "%s: unable to print string value.",
584
           function );
585
586
          goto on_error;
587
        }
588
      }
589
      libcnotify_printf(
590
       "\n" );
591
    }
592
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
593
154
  }
594
215
  return( 1 );
595
596
193
on_error:
597
193
  if( data_string->data != NULL )
598
28
  {
599
28
    memory_free(
600
28
     data_string->data );
601
602
28
    data_string->data = NULL;
603
28
  }
604
193
  return( -1 );
605
243
}
606
607
/* Retrieves the size of the UTF-8 encoded data string
608
 * The size includes the end of string character
609
 * Returns 1 if successful, 0 if value is not available or -1 on error
610
 */
611
int liblnk_data_string_get_utf8_string_size(
612
     liblnk_data_string_t *data_string,
613
     int ascii_codepage,
614
     size_t *utf8_string_size,
615
     libcerror_error_t **error )
616
0
{
617
0
  static char *function = "liblnk_data_string_get_utf8_string_size";
618
0
  int result            = 0;
619
620
0
  if( data_string == NULL )
621
0
  {
622
0
    libcerror_error_set(
623
0
     error,
624
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
625
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
626
0
     "%s: invalid data string.",
627
0
     function );
628
629
0
    return( -1 );
630
0
  }
631
0
  if( data_string->data == NULL )
632
0
  {
633
0
    libcerror_error_set(
634
0
     error,
635
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
636
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
637
0
     "%s: invalid data string - missing data.",
638
0
     function );
639
640
0
    return( -1 );
641
0
  }
642
0
  if( utf8_string_size == NULL )
643
0
  {
644
0
    libcerror_error_set(
645
0
     error,
646
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
647
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
648
0
     "%s: invalid UTF-8 string size.",
649
0
     function );
650
651
0
    return( -1 );
652
0
  }
653
0
  if( data_string->is_unicode != 0 )
654
0
  {
655
0
    result = libuna_utf8_string_size_from_utf16_stream(
656
0
        data_string->data,
657
0
        data_string->data_size,
658
0
        LIBUNA_ENDIAN_LITTLE,
659
0
        utf8_string_size,
660
0
        error );
661
0
  }
662
0
  else
663
0
  {
664
0
    result = libuna_utf8_string_size_from_byte_stream(
665
0
        data_string->data,
666
0
        data_string->data_size,
667
0
        ascii_codepage,
668
0
        utf8_string_size,
669
0
        error );
670
0
  }
671
0
  if( result != 1 )
672
0
  {
673
0
    libcerror_error_set(
674
0
     error,
675
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
676
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
677
0
     "%s: unable to retrieve UTF-8 data string size.",
678
0
     function );
679
680
0
    return( -1 );
681
0
  }
682
0
  return( 1 );
683
0
}
684
685
/* Retrieves the UTF-8 encoded data string
686
 * The size should include the end of string character
687
 * Returns 1 if successful, 0 if value is not available or -1 on error
688
 */
689
int liblnk_data_string_get_utf8_string(
690
     liblnk_data_string_t *data_string,
691
     int ascii_codepage,
692
     uint8_t *utf8_string,
693
     size_t utf8_string_size,
694
     libcerror_error_t **error )
695
0
{
696
0
  static char *function = "liblnk_data_string_get_utf8_string";
697
0
  int result            = 0;
698
699
0
  if( data_string == NULL )
700
0
  {
701
0
    libcerror_error_set(
702
0
     error,
703
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
704
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
705
0
     "%s: invalid data string.",
706
0
     function );
707
708
0
    return( -1 );
709
0
  }
710
0
  if( data_string->data == NULL )
711
0
  {
712
0
    libcerror_error_set(
713
0
     error,
714
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
715
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
716
0
     "%s: invalid data string - missing data.",
717
0
     function );
718
719
0
    return( -1 );
720
0
  }
721
0
  if( utf8_string == NULL )
722
0
  {
723
0
    libcerror_error_set(
724
0
     error,
725
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
726
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
727
0
     "%s: invalid UTF-8 string.",
728
0
     function );
729
730
0
    return( -1 );
731
0
  }
732
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
733
0
  {
734
0
    libcerror_error_set(
735
0
     error,
736
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
737
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
738
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
739
0
     function );
740
741
0
    return( -1 );
742
0
  }
743
0
  if( data_string->is_unicode != 0 )
744
0
  {
745
0
    result = libuna_utf8_string_copy_from_utf16_stream(
746
0
        utf8_string,
747
0
        utf8_string_size,
748
0
        data_string->data,
749
0
        data_string->data_size,
750
0
        LIBUNA_ENDIAN_LITTLE,
751
0
        error );
752
0
  }
753
0
  else
754
0
  {
755
0
    result = libuna_utf8_string_copy_from_byte_stream(
756
0
        utf8_string,
757
0
        utf8_string_size,
758
0
        data_string->data,
759
0
        data_string->data_size,
760
0
        ascii_codepage,
761
0
        error );
762
0
  }
763
0
  if( result != 1 )
764
0
  {
765
0
    libcerror_error_set(
766
0
     error,
767
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
768
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
769
0
     "%s: unable to set UTF-8 data string.",
770
0
     function );
771
772
0
    return( -1 );
773
0
  }
774
0
  return( 1 );
775
0
}
776
777
/* Retrieves the size of the UTF-16 encoded data string
778
 * The size includes the end of string character
779
 * Returns 1 if successful, 0 if value is not available or -1 on error
780
 */
781
int liblnk_data_string_get_utf16_string_size(
782
     liblnk_data_string_t *data_string,
783
     int ascii_codepage,
784
     size_t *utf16_string_size,
785
     libcerror_error_t **error )
786
0
{
787
0
  static char *function = "liblnk_data_string_get_utf16_string_size";
788
0
  int result            = 0;
789
790
0
  if( data_string == NULL )
791
0
  {
792
0
    libcerror_error_set(
793
0
     error,
794
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
795
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
796
0
     "%s: invalid data string.",
797
0
     function );
798
799
0
    return( -1 );
800
0
  }
801
0
  if( data_string->data == NULL )
802
0
  {
803
0
    libcerror_error_set(
804
0
     error,
805
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
806
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
807
0
     "%s: invalid data string - missing data.",
808
0
     function );
809
810
0
    return( -1 );
811
0
  }
812
0
  if( utf16_string_size == NULL )
813
0
  {
814
0
    libcerror_error_set(
815
0
     error,
816
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
817
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
818
0
     "%s: invalid UTF-16 string size.",
819
0
     function );
820
821
0
    return( -1 );
822
0
  }
823
0
  if( data_string->is_unicode != 0 )
824
0
  {
825
0
    result = libuna_utf16_string_size_from_utf16_stream(
826
0
        data_string->data,
827
0
        data_string->data_size,
828
0
        LIBUNA_ENDIAN_LITTLE,
829
0
        utf16_string_size,
830
0
        error );
831
0
  }
832
0
  else
833
0
  {
834
0
    result = libuna_utf16_string_size_from_byte_stream(
835
0
        data_string->data,
836
0
        data_string->data_size,
837
0
        ascii_codepage,
838
0
        utf16_string_size,
839
0
        error );
840
0
  }
841
0
  if( result != 1 )
842
0
  {
843
0
    libcerror_error_set(
844
0
     error,
845
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
846
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
847
0
     "%s: unable to retrieve UTF-16 data string size.",
848
0
     function );
849
850
0
    return( -1 );
851
0
  }
852
0
  return( 1 );
853
0
}
854
855
/* Retrieves the UTF-16 encoded data string
856
 * The size should include the end of string character
857
 * Returns 1 if successful, 0 if value is not available or -1 on error
858
 */
859
int liblnk_data_string_get_utf16_string(
860
     liblnk_data_string_t *data_string,
861
     int ascii_codepage,
862
     uint16_t *utf16_string,
863
     size_t utf16_string_size,
864
     libcerror_error_t **error )
865
0
{
866
0
  static char *function = "liblnk_data_string_get_utf16_string";
867
0
  int result            = 0;
868
869
0
  if( data_string == NULL )
870
0
  {
871
0
    libcerror_error_set(
872
0
     error,
873
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
874
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
875
0
     "%s: invalid data string.",
876
0
     function );
877
878
0
    return( -1 );
879
0
  }
880
0
  if( data_string->data == NULL )
881
0
  {
882
0
    libcerror_error_set(
883
0
     error,
884
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
885
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
886
0
     "%s: invalid data string - missing data.",
887
0
     function );
888
889
0
    return( -1 );
890
0
  }
891
0
  if( utf16_string == NULL )
892
0
  {
893
0
    libcerror_error_set(
894
0
     error,
895
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
896
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
897
0
     "%s: invalid UTF-16 string.",
898
0
     function );
899
900
0
    return( -1 );
901
0
  }
902
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
903
0
  {
904
0
    libcerror_error_set(
905
0
     error,
906
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
907
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
908
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
909
0
     function );
910
911
0
    return( -1 );
912
0
  }
913
0
  if( data_string->is_unicode != 0 )
914
0
  {
915
0
    result = libuna_utf16_string_copy_from_utf16_stream(
916
0
        utf16_string,
917
0
        utf16_string_size,
918
0
        data_string->data,
919
0
        data_string->data_size,
920
0
        LIBUNA_ENDIAN_LITTLE,
921
0
        error );
922
0
  }
923
0
  else
924
0
  {
925
0
    result = libuna_utf16_string_copy_from_byte_stream(
926
0
        utf16_string,
927
0
        utf16_string_size,
928
0
        data_string->data,
929
0
        data_string->data_size,
930
0
        ascii_codepage,
931
0
        error );
932
0
  }
933
0
  if( result != 1 )
934
0
  {
935
0
    libcerror_error_set(
936
0
     error,
937
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
938
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
939
0
     "%s: unable to set UTF-16 data string.",
940
0
     function );
941
942
0
    return( -1 );
943
0
  }
944
0
  return( 1 );
945
0
}
946