Coverage Report

Created: 2025-06-24 07:14

/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-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 <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.42k
{
46
2.42k
  static char *function = "liblnk_data_string_initialize";
47
48
2.42k
  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.42k
  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.42k
  *data_string = memory_allocate_structure(
71
2.42k
                  liblnk_data_string_t );
72
73
2.42k
  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.42k
  if( memory_set(
85
2.42k
       *data_string,
86
2.42k
       0,
87
2.42k
       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.42k
  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.42k
}
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.42k
{
118
2.42k
  static char *function = "liblnk_data_string_free";
119
120
2.42k
  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.42k
  if( *data_string != NULL )
132
2.42k
  {
133
2.42k
    if( ( *data_string )->data != NULL )
134
1.57k
    {
135
1.57k
      memory_free(
136
1.57k
       ( *data_string )->data );
137
1.57k
    }
138
2.42k
    memory_free(
139
2.42k
     *data_string );
140
141
2.42k
    *data_string = NULL;
142
2.42k
  }
143
2.42k
  return( 1 );
144
2.42k
}
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
     uint32_t encoding_flags,
155
     libcerror_error_t **error )
156
0
{
157
0
  static char *function = "liblnk_data_string_read_data";
158
159
0
  if( data_string == NULL )
160
0
  {
161
0
    libcerror_error_set(
162
0
     error,
163
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
164
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
165
0
     "%s: invalid data string.",
166
0
     function );
167
168
0
    return( -1 );
169
0
  }
170
0
  if( data_string->data != NULL )
171
0
  {
172
0
    libcerror_error_set(
173
0
     error,
174
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
175
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
176
0
     "%s: invalid data string - data already set.",
177
0
     function );
178
179
0
    return( -1 );
180
0
  }
181
0
  if( io_handle == NULL )
182
0
  {
183
0
    libcerror_error_set(
184
0
     error,
185
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
186
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
187
0
     "%s: invalid IO handle.",
188
0
     function );
189
190
0
    return( -1 );
191
0
  }
192
0
  if( data == NULL )
193
0
  {
194
0
    libcerror_error_set(
195
0
     error,
196
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
197
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
198
0
     "%s: invalid data.",
199
0
     function );
200
201
0
    return( -1 );
202
0
  }
203
0
  if( ( data_size < 2 )
204
0
   || ( data_size > (size_t) SSIZE_MAX ) )
205
0
  {
206
0
    libcerror_error_set(
207
0
     error,
208
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
209
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
210
0
     "%s: invalid data size value out of bounds.",
211
0
     function );
212
213
0
    return( -1 );
214
0
  }
215
  /* Store is unicode value for internal use
216
   */
217
0
  data_string->is_unicode = io_handle->is_unicode;
218
219
0
  byte_stream_copy_to_uint16_little_endian(
220
0
   data,
221
0
   data_string->data_size );
222
223
#if defined( HAVE_DEBUG_OUTPUT )
224
  if( libcnotify_verbose != 0 )
225
  {
226
    libcnotify_printf(
227
     "%s: data string size\t\t: %" PRIzd "\n",
228
     function,
229
     data_string->data_size );
230
  }
231
#endif
232
0
  if( data_string->data_size > 0 )
233
0
  {
234
    /* The size contains the number of characters
235
     * a Unicode (UTF-16) string requires 2 bytes per character
236
     */
237
0
    if( data_string->is_unicode != 0 )
238
0
    {
239
0
      if( data_string->data_size > ( ( data_size - 2 ) / 2 ) )
240
0
      {
241
0
        libcerror_error_set(
242
0
         error,
243
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
244
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
245
0
         "%s: invalid data string size value out of bounds.",
246
0
         function );
247
248
0
        goto on_error;
249
0
      }
250
0
      data_string->data_size *= 2;
251
0
    }
252
0
    else
253
0
    {
254
0
      if( data_string->data_size > ( data_size - 2 ) )
255
0
      {
256
0
        libcerror_error_set(
257
0
         error,
258
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
259
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
260
0
         "%s: invalid data string size value out of bounds.",
261
0
         function );
262
263
0
        goto on_error;
264
0
      }
265
0
    }
266
0
    if( data_string->data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
267
0
    {
268
0
      libcerror_error_set(
269
0
       error,
270
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
271
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
272
0
       "%s: invalid data string size value exceed maximum allocation size.",
273
0
       function );
274
275
0
      goto on_error;
276
0
    }
277
0
    data_string->data = (uint8_t *) memory_allocate(
278
0
                                     sizeof( uint8_t ) * data_string->data_size );
279
280
0
    if( data_string->data == NULL )
281
0
    {
282
0
      libcerror_error_set(
283
0
       error,
284
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
285
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
286
0
       "%s: unable to create data string data.",
287
0
       function );
288
289
0
      goto on_error;
290
0
    }
291
0
    if( memory_copy(
292
0
         data_string->data,
293
0
         &( data[ 2 ] ),
294
0
         data_string->data_size ) == NULL )
295
0
    {
296
0
      libcerror_error_set(
297
0
       error,
298
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
299
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
300
0
       "%s: unable to copy data string data.",
301
0
       function );
302
303
0
      goto on_error;
304
0
    }
305
0
    if( data_string->data == NULL )
306
0
    {
307
0
      libcerror_error_set(
308
0
       error,
309
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
310
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
311
0
       "%s: unable to create data string data.",
312
0
       function );
313
314
0
      goto on_error;
315
0
    }
316
#if defined( HAVE_DEBUG_OUTPUT )
317
    if( libcnotify_verbose != 0 )
318
    {
319
      libcnotify_printf(
320
       "%s: data string data:\n",
321
       function );
322
      libcnotify_print_data(
323
       data_string->data,
324
       data_string->data_size,
325
       0 );
326
    }
327
#endif
328
#if defined( HAVE_DEBUG_OUTPUT )
329
    if( libcnotify_verbose != 0 )
330
    {
331
      if( data_string->is_unicode != 0 )
332
      {
333
        if( liblnk_debug_print_utf16_string_value(
334
             function,
335
             "data string\t\t\t",
336
             data_string->data,
337
             data_string->data_size,
338
             LIBUNA_ENDIAN_LITTLE | encoding_flags,
339
             error ) != 1 )
340
        {
341
          libcerror_error_set(
342
           error,
343
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
344
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
345
           "%s: unable to print UTF-16 string value.",
346
           function );
347
348
          goto on_error;
349
        }
350
      }
351
      else
352
      {
353
        if( liblnk_debug_print_string_value(
354
             function,
355
             "data string\t\t\t",
356
             data_string->data,
357
             data_string->data_size,
358
             io_handle->ascii_codepage,
359
             error ) != 1 )
360
        {
361
          libcerror_error_set(
362
           error,
363
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
364
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
365
           "%s: unable to print string value.",
366
           function );
367
368
          goto on_error;
369
        }
370
      }
371
      libcnotify_printf(
372
       "\n" );
373
    }
374
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
375
0
  }
376
0
  return( 1 );
377
378
0
on_error:
379
0
  if( data_string->data != NULL )
380
0
  {
381
0
    memory_free(
382
0
     data_string->data );
383
384
0
    data_string->data = NULL;
385
0
  }
386
0
  return( -1 );
387
0
}
388
389
/* Reads a data string
390
 * Returns 1 if successful or -1 on error
391
 */
392
int liblnk_data_string_read_file_io_handle(
393
     liblnk_data_string_t *data_string,
394
     liblnk_io_handle_t *io_handle,
395
     libbfio_handle_t *file_io_handle,
396
     off64_t file_offset,
397
     uint32_t encoding_flags,
398
     libcerror_error_t **error )
399
430
{
400
430
  uint8_t data_string_size_data[ 2 ];
401
402
430
  static char *function = "liblnk_data_string_read_file_io_handle";
403
430
  ssize_t read_count    = 0;
404
405
430
  if( data_string == NULL )
406
0
  {
407
0
    libcerror_error_set(
408
0
     error,
409
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
410
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
411
0
     "%s: invalid data string.",
412
0
     function );
413
414
0
    return( -1 );
415
0
  }
416
430
  if( data_string->data != NULL )
417
0
  {
418
0
    libcerror_error_set(
419
0
     error,
420
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
421
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
422
0
     "%s: invalid data string - data already set.",
423
0
     function );
424
425
0
    return( -1 );
426
0
  }
427
430
  if( io_handle == NULL )
428
0
  {
429
0
    libcerror_error_set(
430
0
     error,
431
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
432
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
433
0
     "%s: invalid IO handle.",
434
0
     function );
435
436
0
    return( -1 );
437
0
  }
438
  /* Store is unicode value for internal use
439
   */
440
430
  data_string->is_unicode = io_handle->is_unicode;
441
442
#if defined( HAVE_DEBUG_OUTPUT )
443
  if( libcnotify_verbose != 0 )
444
  {
445
    libcnotify_printf(
446
     "%s: reading data string at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
447
     function,
448
     file_offset,
449
     file_offset );
450
  }
451
#endif
452
430
  read_count = libbfio_handle_read_buffer_at_offset(
453
430
                file_io_handle,
454
430
                data_string_size_data,
455
430
                2,
456
430
                file_offset,
457
430
                error );
458
459
430
  if( read_count != (ssize_t) 2 )
460
169
  {
461
169
    libcerror_error_set(
462
169
     error,
463
169
     LIBCERROR_ERROR_DOMAIN_IO,
464
169
     LIBCERROR_IO_ERROR_READ_FAILED,
465
169
     "%s: unable to read data string size at offset: %" PRIi64 " (0x%08" PRIx64 ").",
466
169
     function,
467
169
     file_offset,
468
169
     file_offset );
469
470
169
    goto on_error;
471
169
  }
472
261
  byte_stream_copy_to_uint16_little_endian(
473
261
   data_string_size_data,
474
261
   data_string->data_size );
475
476
#if defined( HAVE_DEBUG_OUTPUT )
477
  if( libcnotify_verbose != 0 )
478
  {
479
    libcnotify_printf(
480
     "%s: data string size\t\t: %" PRIzd "\n",
481
     function,
482
     data_string->data_size );
483
  }
484
#endif
485
261
  if( data_string->data_size > 0 )
486
160
  {
487
    /* The size contains the number of characters
488
     * a Unicode (UTF-16) string requires 2 bytes per character
489
     */
490
160
    if( data_string->is_unicode != 0 )
491
116
    {
492
116
      data_string->data_size *= 2;
493
116
    }
494
160
    if( data_string->data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
495
0
    {
496
0
      libcerror_error_set(
497
0
       error,
498
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
499
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
500
0
       "%s: invalid data string size value exceed maximum allocation size.",
501
0
       function );
502
503
0
      goto on_error;
504
0
    }
505
160
    data_string->data = (uint8_t *) memory_allocate(
506
160
                                     sizeof( uint8_t ) * data_string->data_size );
507
508
160
    if( data_string->data == NULL )
509
0
    {
510
0
      libcerror_error_set(
511
0
       error,
512
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
513
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
514
0
       "%s: unable to create data string data.",
515
0
       function );
516
517
0
      goto on_error;
518
0
    }
519
160
    read_count = libbfio_handle_read_buffer(
520
160
                  file_io_handle,
521
160
                  data_string->data,
522
160
                  data_string->data_size,
523
160
                  error );
524
525
160
    if( read_count != (ssize_t) data_string->data_size )
526
32
    {
527
32
      libcerror_error_set(
528
32
       error,
529
32
       LIBCERROR_ERROR_DOMAIN_IO,
530
32
       LIBCERROR_IO_ERROR_READ_FAILED,
531
32
       "%s: unable to read data string data.",
532
32
       function );
533
534
32
      goto on_error;
535
32
    }
536
#if defined( HAVE_DEBUG_OUTPUT )
537
    if( libcnotify_verbose != 0 )
538
    {
539
      libcnotify_printf(
540
       "%s: data string data:\n",
541
       function );
542
      libcnotify_print_data(
543
       data_string->data,
544
       data_string->data_size,
545
       0 );
546
    }
547
#endif
548
#if defined( HAVE_DEBUG_OUTPUT )
549
    if( libcnotify_verbose != 0 )
550
    {
551
      if( data_string->is_unicode != 0 )
552
      {
553
        if( liblnk_debug_print_utf16_string_value(
554
             function,
555
             "data string\t\t\t",
556
             data_string->data,
557
             data_string->data_size,
558
             LIBUNA_ENDIAN_LITTLE | encoding_flags,
559
             error ) != 1 )
560
        {
561
          libcerror_error_set(
562
           error,
563
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
564
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
565
           "%s: unable to print UTF-16 string value.",
566
           function );
567
568
          goto on_error;
569
        }
570
      }
571
      else
572
      {
573
        if( liblnk_debug_print_string_value(
574
             function,
575
             "data string\t\t\t",
576
             data_string->data,
577
             data_string->data_size,
578
             io_handle->ascii_codepage,
579
             error ) != 1 )
580
        {
581
          libcerror_error_set(
582
           error,
583
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
584
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
585
           "%s: unable to print string value.",
586
           function );
587
588
          goto on_error;
589
        }
590
      }
591
      libcnotify_printf(
592
       "\n" );
593
    }
594
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
595
160
  }
596
229
  return( 1 );
597
598
201
on_error:
599
201
  if( data_string->data != NULL )
600
32
  {
601
32
    memory_free(
602
32
     data_string->data );
603
604
32
    data_string->data = NULL;
605
32
  }
606
201
  return( -1 );
607
261
}
608
609
/* Retrieves the size of the UTF-8 encoded string
610
 * The size includes the end of string character
611
 * Returns 1 if successful, 0 if value is not available or -1 on error
612
 */
613
int liblnk_data_string_get_utf8_string_size(
614
     liblnk_data_string_t *data_string,
615
     int ascii_codepage,
616
     size_t *utf8_string_size,
617
     libcerror_error_t **error )
618
0
{
619
0
  static char *function = "liblnk_data_string_get_utf8_string_size";
620
0
  int result            = 0;
621
622
0
  if( data_string == NULL )
623
0
  {
624
0
    libcerror_error_set(
625
0
     error,
626
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
627
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
628
0
     "%s: invalid data string.",
629
0
     function );
630
631
0
    return( -1 );
632
0
  }
633
0
  if( data_string->data == NULL )
634
0
  {
635
0
    libcerror_error_set(
636
0
     error,
637
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
638
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
639
0
     "%s: invalid data string - missing data.",
640
0
     function );
641
642
0
    return( -1 );
643
0
  }
644
0
  if( utf8_string_size == NULL )
645
0
  {
646
0
    libcerror_error_set(
647
0
     error,
648
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
649
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
650
0
     "%s: invalid UTF-8 string size.",
651
0
     function );
652
653
0
    return( -1 );
654
0
  }
655
0
  if( data_string->is_unicode != 0 )
656
0
  {
657
0
    result = libuna_utf8_string_size_from_utf16_stream(
658
0
        data_string->data,
659
0
        data_string->data_size,
660
0
        LIBUNA_ENDIAN_LITTLE,
661
0
        utf8_string_size,
662
0
        error );
663
0
  }
664
0
  else
665
0
  {
666
0
    result = libuna_utf8_string_size_from_byte_stream(
667
0
        data_string->data,
668
0
        data_string->data_size,
669
0
        ascii_codepage,
670
0
        utf8_string_size,
671
0
        error );
672
0
  }
673
0
  if( result != 1 )
674
0
  {
675
0
    libcerror_error_set(
676
0
     error,
677
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
678
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
679
0
     "%s: unable to retrieve UTF-8 string size.",
680
0
     function );
681
682
0
    return( -1 );
683
0
  }
684
0
  return( 1 );
685
0
}
686
687
/* Retrieves the UTF-8 encoded string
688
 * The size should include the end of string character
689
 * Returns 1 if successful, 0 if value is not available or -1 on error
690
 */
691
int liblnk_data_string_get_utf8_string(
692
     liblnk_data_string_t *data_string,
693
     int ascii_codepage,
694
     uint8_t *utf8_string,
695
     size_t utf8_string_size,
696
     libcerror_error_t **error )
697
0
{
698
0
  static char *function = "liblnk_data_string_get_utf8_string";
699
0
  int result            = 0;
700
701
0
  if( data_string == NULL )
702
0
  {
703
0
    libcerror_error_set(
704
0
     error,
705
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
706
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
707
0
     "%s: invalid data string.",
708
0
     function );
709
710
0
    return( -1 );
711
0
  }
712
0
  if( data_string->data == NULL )
713
0
  {
714
0
    libcerror_error_set(
715
0
     error,
716
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
717
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
718
0
     "%s: invalid data string - missing data.",
719
0
     function );
720
721
0
    return( -1 );
722
0
  }
723
0
  if( utf8_string == NULL )
724
0
  {
725
0
    libcerror_error_set(
726
0
     error,
727
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
728
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
729
0
     "%s: invalid UTF-8 string.",
730
0
     function );
731
732
0
    return( -1 );
733
0
  }
734
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
735
0
  {
736
0
    libcerror_error_set(
737
0
     error,
738
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
739
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
740
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
741
0
     function );
742
743
0
    return( -1 );
744
0
  }
745
0
  if( data_string->is_unicode != 0 )
746
0
  {
747
0
    result = libuna_utf8_string_copy_from_utf16_stream(
748
0
        utf8_string,
749
0
        utf8_string_size,
750
0
        data_string->data,
751
0
        data_string->data_size,
752
0
        LIBUNA_ENDIAN_LITTLE,
753
0
        error );
754
0
  }
755
0
  else
756
0
  {
757
0
    result = libuna_utf8_string_copy_from_byte_stream(
758
0
        utf8_string,
759
0
        utf8_string_size,
760
0
        data_string->data,
761
0
        data_string->data_size,
762
0
        ascii_codepage,
763
0
        error );
764
0
  }
765
0
  if( result != 1 )
766
0
  {
767
0
    libcerror_error_set(
768
0
     error,
769
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
770
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
771
0
     "%s: unable to set UTF-8 string.",
772
0
     function );
773
774
0
    return( -1 );
775
0
  }
776
0
  return( 1 );
777
0
}
778
779
/* Retrieves the size of the UTF-16 encoded string
780
 * The size includes the end of string character
781
 * Returns 1 if successful, 0 if value is not available or -1 on error
782
 */
783
int liblnk_data_string_get_utf16_string_size(
784
     liblnk_data_string_t *data_string,
785
     int ascii_codepage,
786
     size_t *utf16_string_size,
787
     libcerror_error_t **error )
788
0
{
789
0
  static char *function = "liblnk_data_string_get_utf16_string_size";
790
0
  int result            = 0;
791
792
0
  if( data_string == NULL )
793
0
  {
794
0
    libcerror_error_set(
795
0
     error,
796
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
797
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
798
0
     "%s: invalid data string.",
799
0
     function );
800
801
0
    return( -1 );
802
0
  }
803
0
  if( data_string->data == NULL )
804
0
  {
805
0
    libcerror_error_set(
806
0
     error,
807
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
808
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
809
0
     "%s: invalid data string - missing data.",
810
0
     function );
811
812
0
    return( -1 );
813
0
  }
814
0
  if( utf16_string_size == NULL )
815
0
  {
816
0
    libcerror_error_set(
817
0
     error,
818
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
819
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
820
0
     "%s: invalid UTF-16 string size.",
821
0
     function );
822
823
0
    return( -1 );
824
0
  }
825
0
  if( data_string->is_unicode != 0 )
826
0
  {
827
0
    result = libuna_utf16_string_size_from_utf16_stream(
828
0
        data_string->data,
829
0
        data_string->data_size,
830
0
        LIBUNA_ENDIAN_LITTLE,
831
0
        utf16_string_size,
832
0
        error );
833
0
  }
834
0
  else
835
0
  {
836
0
    result = libuna_utf16_string_size_from_byte_stream(
837
0
        data_string->data,
838
0
        data_string->data_size,
839
0
        ascii_codepage,
840
0
        utf16_string_size,
841
0
        error );
842
0
  }
843
0
  if( result != 1 )
844
0
  {
845
0
    libcerror_error_set(
846
0
     error,
847
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
848
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
849
0
     "%s: unable to retrieve UTF-16 string size.",
850
0
     function );
851
852
0
    return( -1 );
853
0
  }
854
0
  return( 1 );
855
0
}
856
857
/* Retrieves the UTF-16 encoded string
858
 * The size should include the end of string character
859
 * Returns 1 if successful, 0 if value is not available or -1 on error
860
 */
861
int liblnk_data_string_get_utf16_string(
862
     liblnk_data_string_t *data_string,
863
     int ascii_codepage,
864
     uint16_t *utf16_string,
865
     size_t utf16_string_size,
866
     libcerror_error_t **error )
867
0
{
868
0
  static char *function = "liblnk_data_string_get_utf16_string";
869
0
  int result            = 0;
870
871
0
  if( data_string == NULL )
872
0
  {
873
0
    libcerror_error_set(
874
0
     error,
875
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
876
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
877
0
     "%s: invalid data string.",
878
0
     function );
879
880
0
    return( -1 );
881
0
  }
882
0
  if( data_string->data == NULL )
883
0
  {
884
0
    libcerror_error_set(
885
0
     error,
886
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
887
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
888
0
     "%s: invalid data string - missing data.",
889
0
     function );
890
891
0
    return( -1 );
892
0
  }
893
0
  if( utf16_string == NULL )
894
0
  {
895
0
    libcerror_error_set(
896
0
     error,
897
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
898
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
899
0
     "%s: invalid UTF-16 string.",
900
0
     function );
901
902
0
    return( -1 );
903
0
  }
904
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
905
0
  {
906
0
    libcerror_error_set(
907
0
     error,
908
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
909
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
910
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
911
0
     function );
912
913
0
    return( -1 );
914
0
  }
915
0
  if( data_string->is_unicode != 0 )
916
0
  {
917
0
    result = libuna_utf16_string_copy_from_utf16_stream(
918
0
        utf16_string,
919
0
        utf16_string_size,
920
0
        data_string->data,
921
0
        data_string->data_size,
922
0
        LIBUNA_ENDIAN_LITTLE,
923
0
        error );
924
0
  }
925
0
  else
926
0
  {
927
0
    result = libuna_utf16_string_copy_from_byte_stream(
928
0
        utf16_string,
929
0
        utf16_string_size,
930
0
        data_string->data,
931
0
        data_string->data_size,
932
0
        ascii_codepage,
933
0
        error );
934
0
  }
935
0
  if( result != 1 )
936
0
  {
937
0
    libcerror_error_set(
938
0
     error,
939
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
940
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
941
0
     "%s: unable to set UTF-16 string.",
942
0
     function );
943
944
0
    return( -1 );
945
0
  }
946
0
  return( 1 );
947
0
}
948
949
/* Retrieves the size of the UTF-8 encoded path string
950
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
951
 * The size includes the end of string character
952
 * Returns 1 if successful, 0 if value is not available or -1 on error
953
 */
954
int liblnk_data_string_get_utf8_path_string_size(
955
     liblnk_data_string_t *data_string,
956
     int ascii_codepage,
957
     size_t *utf8_string_size,
958
     libcerror_error_t **error )
959
0
{
960
0
  static char *function = "liblnk_data_string_get_utf8_path_string_size";
961
0
  int result            = 0;
962
963
0
  if( data_string == NULL )
964
0
  {
965
0
    libcerror_error_set(
966
0
     error,
967
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
968
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
969
0
     "%s: invalid data string.",
970
0
     function );
971
972
0
    return( -1 );
973
0
  }
974
0
  if( data_string->data == NULL )
975
0
  {
976
0
    libcerror_error_set(
977
0
     error,
978
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
979
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
980
0
     "%s: invalid data string - missing data.",
981
0
     function );
982
983
0
    return( -1 );
984
0
  }
985
0
  if( utf8_string_size == NULL )
986
0
  {
987
0
    libcerror_error_set(
988
0
     error,
989
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
990
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
991
0
     "%s: invalid UTF-8 string size.",
992
0
     function );
993
994
0
    return( -1 );
995
0
  }
996
0
  if( data_string->is_unicode != 0 )
997
0
  {
998
0
    result = libuna_utf8_string_size_from_utf16_stream(
999
0
        data_string->data,
1000
0
        data_string->data_size,
1001
0
        LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1002
0
        utf8_string_size,
1003
0
        error );
1004
0
  }
1005
0
  else
1006
0
  {
1007
0
    result = libuna_utf8_string_size_from_byte_stream(
1008
0
        data_string->data,
1009
0
        data_string->data_size,
1010
0
        ascii_codepage,
1011
0
        utf8_string_size,
1012
0
        error );
1013
0
  }
1014
0
  if( result != 1 )
1015
0
  {
1016
0
    libcerror_error_set(
1017
0
     error,
1018
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1019
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1020
0
     "%s: unable to retrieve UTF-8 string size.",
1021
0
     function );
1022
1023
0
    return( -1 );
1024
0
  }
1025
0
  return( 1 );
1026
0
}
1027
1028
/* Retrieves the UTF-8 encoded path string
1029
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
1030
 * The size should include the end of string character
1031
 * Returns 1 if successful, 0 if value is not available or -1 on error
1032
 */
1033
int liblnk_data_string_get_utf8_path_string(
1034
     liblnk_data_string_t *data_string,
1035
     int ascii_codepage,
1036
     uint8_t *utf8_string,
1037
     size_t utf8_string_size,
1038
     libcerror_error_t **error )
1039
0
{
1040
0
  static char *function = "liblnk_data_string_get_utf8_path_string";
1041
0
  int result            = 0;
1042
1043
0
  if( data_string == NULL )
1044
0
  {
1045
0
    libcerror_error_set(
1046
0
     error,
1047
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1048
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1049
0
     "%s: invalid data string.",
1050
0
     function );
1051
1052
0
    return( -1 );
1053
0
  }
1054
0
  if( data_string->data == NULL )
1055
0
  {
1056
0
    libcerror_error_set(
1057
0
     error,
1058
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1059
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1060
0
     "%s: invalid data string - missing data.",
1061
0
     function );
1062
1063
0
    return( -1 );
1064
0
  }
1065
0
  if( utf8_string == NULL )
1066
0
  {
1067
0
    libcerror_error_set(
1068
0
     error,
1069
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1070
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1071
0
     "%s: invalid UTF-8 string.",
1072
0
     function );
1073
1074
0
    return( -1 );
1075
0
  }
1076
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
1077
0
  {
1078
0
    libcerror_error_set(
1079
0
     error,
1080
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1081
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1082
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
1083
0
     function );
1084
1085
0
    return( -1 );
1086
0
  }
1087
0
  if( data_string->is_unicode != 0 )
1088
0
  {
1089
0
    result = libuna_utf8_string_copy_from_utf16_stream(
1090
0
        utf8_string,
1091
0
        utf8_string_size,
1092
0
        data_string->data,
1093
0
        data_string->data_size,
1094
0
        LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1095
0
        error );
1096
0
  }
1097
0
  else
1098
0
  {
1099
0
    result = libuna_utf8_string_copy_from_byte_stream(
1100
0
        utf8_string,
1101
0
        utf8_string_size,
1102
0
        data_string->data,
1103
0
        data_string->data_size,
1104
0
        ascii_codepage,
1105
0
        error );
1106
0
  }
1107
0
  if( result != 1 )
1108
0
  {
1109
0
    libcerror_error_set(
1110
0
     error,
1111
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1112
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1113
0
     "%s: unable to set UTF-8 string.",
1114
0
     function );
1115
1116
0
    return( -1 );
1117
0
  }
1118
0
  return( 1 );
1119
0
}
1120
1121
/* Retrieves the size of the UTF-16 encoded path string
1122
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
1123
 * The size includes the end of string character
1124
 * Returns 1 if successful, 0 if value is not available or -1 on error
1125
 */
1126
int liblnk_data_string_get_utf16_path_string_size(
1127
     liblnk_data_string_t *data_string,
1128
     int ascii_codepage,
1129
     size_t *utf16_string_size,
1130
     libcerror_error_t **error )
1131
0
{
1132
0
  static char *function = "liblnk_data_string_get_utf16_path_string_size";
1133
0
  int result            = 0;
1134
1135
0
  if( data_string == NULL )
1136
0
  {
1137
0
    libcerror_error_set(
1138
0
     error,
1139
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1140
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1141
0
     "%s: invalid data string.",
1142
0
     function );
1143
1144
0
    return( -1 );
1145
0
  }
1146
0
  if( data_string->data == NULL )
1147
0
  {
1148
0
    libcerror_error_set(
1149
0
     error,
1150
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1151
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1152
0
     "%s: invalid data string - missing data.",
1153
0
     function );
1154
1155
0
    return( -1 );
1156
0
  }
1157
0
  if( utf16_string_size == NULL )
1158
0
  {
1159
0
    libcerror_error_set(
1160
0
     error,
1161
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1162
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1163
0
     "%s: invalid UTF-16 string size.",
1164
0
     function );
1165
1166
0
    return( -1 );
1167
0
  }
1168
0
  if( data_string->is_unicode != 0 )
1169
0
  {
1170
0
    result = libuna_utf16_string_size_from_utf16_stream(
1171
0
        data_string->data,
1172
0
        data_string->data_size,
1173
0
        LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1174
0
        utf16_string_size,
1175
0
        error );
1176
0
  }
1177
0
  else
1178
0
  {
1179
0
    result = libuna_utf16_string_size_from_byte_stream(
1180
0
        data_string->data,
1181
0
        data_string->data_size,
1182
0
        ascii_codepage,
1183
0
        utf16_string_size,
1184
0
        error );
1185
0
  }
1186
0
  if( result != 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 retrieve UTF-16 string size.",
1193
0
     function );
1194
1195
0
    return( -1 );
1196
0
  }
1197
0
  return( 1 );
1198
0
}
1199
1200
/* Retrieves the UTF-16 encoded path string
1201
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
1202
 * The size should include the end of string character
1203
 * Returns 1 if successful, 0 if value is not available or -1 on error
1204
 */
1205
int liblnk_data_string_get_utf16_path_string(
1206
     liblnk_data_string_t *data_string,
1207
     int ascii_codepage,
1208
     uint16_t *utf16_string,
1209
     size_t utf16_string_size,
1210
     libcerror_error_t **error )
1211
0
{
1212
0
  static char *function = "liblnk_data_string_get_utf16_path_string";
1213
0
  int result            = 0;
1214
1215
0
  if( data_string == NULL )
1216
0
  {
1217
0
    libcerror_error_set(
1218
0
     error,
1219
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1220
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1221
0
     "%s: invalid data string.",
1222
0
     function );
1223
1224
0
    return( -1 );
1225
0
  }
1226
0
  if( data_string->data == NULL )
1227
0
  {
1228
0
    libcerror_error_set(
1229
0
     error,
1230
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1231
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1232
0
     "%s: invalid data string - missing data.",
1233
0
     function );
1234
1235
0
    return( -1 );
1236
0
  }
1237
0
  if( utf16_string == NULL )
1238
0
  {
1239
0
    libcerror_error_set(
1240
0
     error,
1241
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1242
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1243
0
     "%s: invalid UTF-16 string.",
1244
0
     function );
1245
1246
0
    return( -1 );
1247
0
  }
1248
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
1249
0
  {
1250
0
    libcerror_error_set(
1251
0
     error,
1252
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1253
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1254
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
1255
0
     function );
1256
1257
0
    return( -1 );
1258
0
  }
1259
0
  if( data_string->is_unicode != 0 )
1260
0
  {
1261
0
    result = libuna_utf16_string_copy_from_utf16_stream(
1262
0
        utf16_string,
1263
0
        utf16_string_size,
1264
0
        data_string->data,
1265
0
        data_string->data_size,
1266
0
        LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1267
0
        error );
1268
0
  }
1269
0
  else
1270
0
  {
1271
0
    result = libuna_utf16_string_copy_from_byte_stream(
1272
0
        utf16_string,
1273
0
        utf16_string_size,
1274
0
        data_string->data,
1275
0
        data_string->data_size,
1276
0
        ascii_codepage,
1277
0
        error );
1278
0
  }
1279
0
  if( result != 1 )
1280
0
  {
1281
0
    libcerror_error_set(
1282
0
     error,
1283
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1284
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1285
0
     "%s: unable to set UTF-16 string.",
1286
0
     function );
1287
1288
0
    return( -1 );
1289
0
  }
1290
0
  return( 1 );
1291
0
}
1292