Coverage Report

Created: 2025-06-13 07:22

/src/libevtx/libfwevt/libfwevt_integer.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Integer functions
3
 *
4
 * Copyright (C) 2011-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 <types.h>
24
25
#include "libfwevt_integer.h"
26
#include "libfwevt_libcerror.h"
27
28
/* Copies an integer from an UTF-16 stream
29
 * Returns 1 if successful or -1 on error
30
 */
31
int libfwevt_integer_copy_from_utf16_stream(
32
     uint64_t *integer_value,
33
     const uint8_t *utf16_stream,
34
     size_t utf16_stream_size,
35
     libcerror_error_t **error )
36
0
{
37
0
  static char *function       = "libfwevt_integer_copy_from_utf16_stream";
38
0
  size_t utf16_stream_offset  = 0;
39
0
  uint64_t safe_integer_value = 0;
40
0
  uint8_t digit               = 0;
41
42
0
  if( integer_value == 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 integer value.",
49
0
     function );
50
51
0
    return( -1 );
52
0
  }
53
0
  if( utf16_stream == NULL )
54
0
  {
55
0
    libcerror_error_set(
56
0
     error,
57
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
58
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
59
0
     "%s: invalid UTF-16 stream.",
60
0
     function );
61
62
0
    return( -1 );
63
0
  }
64
0
  if( ( utf16_stream_size < 2 )
65
0
   || ( utf16_stream_size > SSIZE_MAX )
66
0
   || ( ( utf16_stream_size % 2 ) != 0 ) )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
71
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
72
0
     "%s: UTF-16 stream size value out of bounds.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
0
  for( utf16_stream_offset = 0;
78
0
       utf16_stream_offset < utf16_stream_size;
79
0
       utf16_stream_offset += 2 )
80
0
  {
81
0
    if( utf16_stream_offset >= 42 )
82
0
    {
83
0
      libcerror_error_set(
84
0
       error,
85
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
86
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
87
0
       "%s: unsupported UTF-16 stream.",
88
0
       function );
89
90
0
      return( -1 );
91
0
    }
92
0
    if( utf16_stream[ utf16_stream_offset + 1 ] != 0 )
93
0
    {
94
0
      libcerror_error_set(
95
0
       error,
96
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
97
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
98
0
       "%s: unsupported integer string.",
99
0
       function );
100
101
0
      return( -1 );
102
0
    }
103
0
    digit = utf16_stream[ utf16_stream_offset ];
104
105
0
    if( digit == 0 )
106
0
    {
107
0
      break;
108
0
    }
109
0
    if( ( digit < (uint8_t) '0' )
110
0
     || ( digit > (uint8_t) '9' ) )
111
0
    {
112
0
      libcerror_error_set(
113
0
       error,
114
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
115
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
116
0
       "%s: invalid integer string.",
117
0
       function );
118
119
0
      return( -1 );
120
0
    }
121
0
    safe_integer_value *= 10;
122
0
    safe_integer_value += digit - (uint8_t) '0';
123
0
  }
124
0
  if( ( utf16_stream[ utf16_stream_offset ] != 0 )
125
0
   || ( utf16_stream[ utf16_stream_offset + 1 ] != 0 ) )
126
0
  {
127
0
    libcerror_error_set(
128
0
     error,
129
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
130
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
131
0
     "%s: unsupported integer string.",
132
0
     function );
133
134
0
    return( -1 );
135
0
  }
136
0
  *integer_value = safe_integer_value;
137
138
0
  return( 1 );
139
0
}
140
141
/* Deterimes the size of the string of the integer as a signed decimal
142
 * The string size includes the end of string character
143
 * Returns 1 if successful or -1 on error
144
 */
145
int libfwevt_integer_as_signed_decimal_get_string_size(
146
     uint64_t integer_value,
147
     uint8_t integer_size,
148
     size_t *string_size,
149
     libcerror_error_t **error )
150
0
{
151
0
  static char *function        = "libfwevt_integer_as_signed_decimal_get_string_size";
152
0
  uint64_t divider             = 0;
153
0
  uint8_t is_negative          = 0;
154
0
  uint8_t number_of_characters = 0;
155
0
  int8_t bit_shift             = integer_size - 1;
156
157
0
  if( string_size == NULL )
158
0
  {
159
0
    libcerror_error_set(
160
0
     error,
161
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
162
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
163
0
     "%s: invalid string size.",
164
0
     function );
165
166
0
    return( -1 );
167
0
  }
168
  /* The string is at least a single digit with an end of string character
169
   */
170
0
  number_of_characters = 2;
171
172
0
  is_negative = (uint8_t) ( integer_value >> bit_shift );
173
174
0
  if( is_negative != 0 )
175
0
  {
176
0
    number_of_characters += 1;
177
178
0
    integer_value &= ~( (uint64_t) 1 << bit_shift );
179
180
0
    if( integer_value == 0 )
181
0
    {
182
0
      integer_value |= (uint64_t) 1 << bit_shift;
183
0
    }
184
0
  }
185
0
  divider = 1;
186
187
0
  while( ( integer_value / divider ) >= 10 )
188
0
  {
189
0
    divider *= 10;
190
191
0
    number_of_characters += 1;
192
0
  }
193
0
  *string_size = number_of_characters;
194
195
0
  return( 1 );
196
0
}
197
198
/* Copies an integer as an unsigned decimal to an UTF-8 string
199
 * The string size should include the end of string character
200
 * Returns 1 if successful or -1 on error
201
 */
202
int libfwevt_integer_as_signed_decimal_copy_to_utf8_string_with_index(
203
     uint64_t integer_value,
204
     uint8_t integer_size,
205
     uint8_t *utf8_string,
206
     size_t utf8_string_size,
207
     size_t *utf8_string_index,
208
     libcerror_error_t **error )
209
0
{
210
0
  static char *function         = "libfwevt_integer_as_signed_decimal_copy_to_utf8_string_with_index";
211
0
  size_t safe_utf8_string_index = 0;
212
0
  uint64_t divider              = 0;
213
0
  uint8_t is_negative           = 0;
214
0
  uint8_t number_of_characters  = 0;
215
0
  int8_t bit_shift              = integer_size - 1;
216
217
0
  if( utf8_string == NULL )
218
0
  {
219
0
    libcerror_error_set(
220
0
     error,
221
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
222
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
223
0
     "%s: invalid UTF-8 string.",
224
0
     function );
225
226
0
    return( -1 );
227
0
  }
228
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
229
0
  {
230
0
    libcerror_error_set(
231
0
     error,
232
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
233
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
234
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
235
0
     function );
236
237
0
    return( -1 );
238
0
  }
239
0
  if( utf8_string_index == NULL )
240
0
  {
241
0
    libcerror_error_set(
242
0
     error,
243
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
244
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
245
0
     "%s: invalid UTF-8 string index.",
246
0
     function );
247
248
0
    return( -1 );
249
0
  }
250
0
  safe_utf8_string_index = *utf8_string_index;
251
252
  /* The string is at least a single digit with an end of string character
253
   */
254
0
  number_of_characters = 2;
255
256
0
  is_negative = (uint8_t) ( integer_value >> bit_shift );
257
258
0
  if( is_negative != 0 )
259
0
  {
260
0
    number_of_characters += 1;
261
262
0
    integer_value &= ~( (uint64_t) 1 << bit_shift );
263
264
0
    if( integer_value == 0 )
265
0
    {
266
0
      integer_value |= (uint64_t) 1 << bit_shift;
267
0
    }
268
0
  }
269
0
  divider = 1;
270
271
0
  while( ( integer_value / divider ) >= 10 )
272
0
  {
273
0
    divider *= 10;
274
275
0
    number_of_characters += 1;
276
0
  }
277
0
  if( ( number_of_characters > utf8_string_size )
278
0
   || ( safe_utf8_string_index > ( utf8_string_size - number_of_characters ) ) )
279
0
  {
280
0
    libcerror_error_set(
281
0
     error,
282
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
283
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
284
0
     "%s: invalid UTF-8 string size value too small.",
285
0
     function );
286
287
0
    return( -1 );
288
0
  }
289
0
  if( is_negative != 0 )
290
0
  {
291
0
    utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '-';
292
0
  }
293
0
  while( divider > 1 )
294
0
  {
295
0
    utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0' + (uint8_t) ( integer_value / divider );
296
297
0
    integer_value %= divider;
298
299
0
    divider /= 10;
300
0
  }
301
0
  utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0' + (uint8_t) ( integer_value / divider );
302
0
  utf8_string[ safe_utf8_string_index++ ] = 0;
303
304
0
  *utf8_string_index = safe_utf8_string_index;
305
306
0
  return( 1 );
307
0
}
308
309
/* Copies an integer as an unsigned decimal to an UTF-16 string
310
 * The string size should include the end of string character
311
 * Returns 1 if successful or -1 on error
312
 */
313
int libfwevt_integer_as_signed_decimal_copy_to_utf16_string_with_index(
314
     uint64_t integer_value,
315
     uint8_t integer_size,
316
     uint16_t *utf16_string,
317
     size_t utf16_string_size,
318
     size_t *utf16_string_index,
319
     libcerror_error_t **error )
320
0
{
321
0
  static char *function          = "libfwevt_integer_as_signed_decimal_copy_to_utf16_string_with_index";
322
0
  size_t safe_utf16_string_index = 0;
323
0
  uint64_t divider               = 0;
324
0
  uint8_t is_negative            = 0;
325
0
  uint8_t number_of_characters   = 0;
326
0
  int8_t bit_shift               = integer_size - 1;
327
328
0
  if( utf16_string == NULL )
329
0
  {
330
0
    libcerror_error_set(
331
0
     error,
332
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
333
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
334
0
     "%s: invalid UTF-16 string.",
335
0
     function );
336
337
0
    return( -1 );
338
0
  }
339
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
340
0
  {
341
0
    libcerror_error_set(
342
0
     error,
343
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
344
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
345
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
346
0
     function );
347
348
0
    return( -1 );
349
0
  }
350
0
  if( utf16_string_index == NULL )
351
0
  {
352
0
    libcerror_error_set(
353
0
     error,
354
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
355
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
356
0
     "%s: invalid UTF-16 string index.",
357
0
     function );
358
359
0
    return( -1 );
360
0
  }
361
0
  safe_utf16_string_index = *utf16_string_index;
362
363
  /* The string is at least a single digit with an end of string character
364
   */
365
0
  number_of_characters = 2;
366
367
0
  is_negative = (uint8_t) ( integer_value >> bit_shift );
368
369
0
  if( is_negative != 0 )
370
0
  {
371
0
    number_of_characters += 1;
372
373
0
    integer_value &= ~( (uint64_t) 1 << bit_shift );
374
375
0
    if( integer_value == 0 )
376
0
    {
377
0
      integer_value |= (uint64_t) 1 << bit_shift;
378
0
    }
379
0
  }
380
0
  divider = 1;
381
382
0
  while( ( integer_value / divider ) >= 10 )
383
0
  {
384
0
    divider *= 10;
385
386
0
    number_of_characters += 1;
387
0
  }
388
0
  if( ( number_of_characters > utf16_string_size )
389
0
   || ( safe_utf16_string_index > ( utf16_string_size - number_of_characters ) ) )
390
0
  {
391
0
    libcerror_error_set(
392
0
     error,
393
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
394
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
395
0
     "%s: invalid UTF-16 string size value too small.",
396
0
     function );
397
398
0
    return( -1 );
399
0
  }
400
0
  if( is_negative != 0 )
401
0
  {
402
0
    utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '-';
403
0
  }
404
0
  while( divider > 1 )
405
0
  {
406
0
    utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0' + (uint16_t) ( integer_value / divider );
407
408
0
    integer_value %= divider;
409
410
0
    divider /= 10;
411
0
  }
412
0
  utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0' + (uint16_t) ( integer_value / divider );
413
0
  utf16_string[ safe_utf16_string_index++ ] = 0;
414
415
0
  *utf16_string_index = safe_utf16_string_index;
416
417
0
  return( 1 );
418
0
}
419
420
/* Deterimes the size of the string of the integer as an unsigned decimal
421
 * The string size includes the end of string character
422
 * Returns 1 if successful or -1 on error
423
 */
424
int libfwevt_integer_as_unsigned_decimal_get_string_size(
425
     uint64_t integer_value,
426
     size_t *string_size,
427
     libcerror_error_t **error )
428
0
{
429
0
  static char *function        = "libfwevt_integer_as_decimal_get_string_size";
430
0
  uint64_t divider             = 0;
431
0
  uint8_t number_of_characters = 0;
432
433
0
  if( string_size == NULL )
434
0
  {
435
0
    libcerror_error_set(
436
0
     error,
437
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
438
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
439
0
     "%s: invalid string size.",
440
0
     function );
441
442
0
    return( -1 );
443
0
  }
444
  /* The string is at least a single digit with an end of string character
445
   */
446
0
  number_of_characters = 2;
447
448
0
  divider = 1;
449
450
0
  while( ( integer_value / divider ) >= 10 )
451
0
  {
452
0
    divider *= 10;
453
454
0
    number_of_characters += 1;
455
0
  }
456
0
  *string_size = number_of_characters;
457
458
0
  return( 1 );
459
0
}
460
461
/* Copies an integer as an unsigned decimal to an UTF-8 string
462
 * The string size should include the end of string character
463
 * Returns 1 if successful or -1 on error
464
 */
465
int libfwevt_integer_as_unsigned_decimal_copy_to_utf8_string_with_index(
466
     uint64_t integer_value,
467
     uint8_t *utf8_string,
468
     size_t utf8_string_size,
469
     size_t *utf8_string_index,
470
     libcerror_error_t **error )
471
0
{
472
0
  static char *function         = "libfwevt_integer_as_unsigned_decimal_copy_to_utf8_string_with_index";
473
0
  size_t safe_utf8_string_index = 0;
474
0
  uint64_t divider              = 0;
475
0
  uint8_t number_of_characters  = 0;
476
477
0
  if( utf8_string == NULL )
478
0
  {
479
0
    libcerror_error_set(
480
0
     error,
481
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
482
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
483
0
     "%s: invalid UTF-8 string.",
484
0
     function );
485
486
0
    return( -1 );
487
0
  }
488
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
489
0
  {
490
0
    libcerror_error_set(
491
0
     error,
492
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
493
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
494
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
495
0
     function );
496
497
0
    return( -1 );
498
0
  }
499
0
  if( utf8_string_index == NULL )
500
0
  {
501
0
    libcerror_error_set(
502
0
     error,
503
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
504
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
505
0
     "%s: invalid UTF-8 string index.",
506
0
     function );
507
508
0
    return( -1 );
509
0
  }
510
0
  safe_utf8_string_index = *utf8_string_index;
511
512
  /* The string is at least a single digit with an end of string character
513
   */
514
0
  number_of_characters = 2;
515
516
0
  divider = 1;
517
518
0
  while( ( integer_value / divider ) >= 10 )
519
0
  {
520
0
    divider *= 10;
521
522
0
    number_of_characters += 1;
523
0
  }
524
0
  if( ( number_of_characters > utf8_string_size )
525
0
   || ( safe_utf8_string_index > ( utf8_string_size - number_of_characters ) ) )
526
0
  {
527
0
    libcerror_error_set(
528
0
     error,
529
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
530
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
531
0
     "%s: invalid UTF-8 string size value too small.",
532
0
     function );
533
534
0
    return( -1 );
535
0
  }
536
0
  while( divider > 1 )
537
0
  {
538
0
    utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0' + (uint8_t) ( integer_value / divider );
539
540
0
    integer_value %= divider;
541
542
0
    divider /= 10;
543
0
  }
544
0
  utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0' + (uint8_t) ( integer_value / divider );
545
0
  utf8_string[ safe_utf8_string_index++ ] = 0;
546
547
0
  *utf8_string_index = safe_utf8_string_index;
548
549
0
  return( 1 );
550
0
}
551
552
/* Copies an integer as an unsigned decimal to an UTF-16 string
553
 * The string size should include the end of string character
554
 * Returns 1 if successful or -1 on error
555
 */
556
int libfwevt_integer_as_unsigned_decimal_copy_to_utf16_string_with_index(
557
     uint64_t integer_value,
558
     uint16_t *utf16_string,
559
     size_t utf16_string_size,
560
     size_t *utf16_string_index,
561
     libcerror_error_t **error )
562
0
{
563
0
  static char *function          = "libfwevt_integer_as_unsigned_decimal_copy_to_utf16_string_with_index";
564
0
  size_t safe_utf16_string_index = 0;
565
0
  uint64_t divider               = 0;
566
0
  uint8_t number_of_characters   = 0;
567
568
0
  if( utf16_string == NULL )
569
0
  {
570
0
    libcerror_error_set(
571
0
     error,
572
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
573
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
574
0
     "%s: invalid UTF-16 string.",
575
0
     function );
576
577
0
    return( -1 );
578
0
  }
579
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
580
0
  {
581
0
    libcerror_error_set(
582
0
     error,
583
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
584
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
585
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
586
0
     function );
587
588
0
    return( -1 );
589
0
  }
590
0
  if( utf16_string_index == NULL )
591
0
  {
592
0
    libcerror_error_set(
593
0
     error,
594
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
595
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
596
0
     "%s: invalid UTF-16 string index.",
597
0
     function );
598
599
0
    return( -1 );
600
0
  }
601
0
  safe_utf16_string_index = *utf16_string_index;
602
603
  /* The string is at least a single digit with an end of string character
604
   */
605
0
  number_of_characters = 2;
606
607
0
  divider = 1;
608
609
0
  while( ( integer_value / divider ) >= 10 )
610
0
  {
611
0
    divider *= 10;
612
613
0
    number_of_characters += 1;
614
0
  }
615
0
  if( ( number_of_characters > utf16_string_size )
616
0
   || ( safe_utf16_string_index > ( utf16_string_size - number_of_characters ) ) )
617
0
  {
618
0
    libcerror_error_set(
619
0
     error,
620
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
621
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
622
0
     "%s: invalid UTF-16 string size value too small.",
623
0
     function );
624
625
0
    return( -1 );
626
0
  }
627
0
  while( divider > 1 )
628
0
  {
629
0
    utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0' + (uint16_t) ( integer_value / divider );
630
631
0
    integer_value %= divider;
632
633
0
    divider /= 10;
634
0
  }
635
0
  utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0' + (uint16_t) ( integer_value / divider );
636
0
  utf16_string[ safe_utf16_string_index++ ] = 0;
637
638
0
  *utf16_string_index = safe_utf16_string_index;
639
640
0
  return( 1 );
641
0
}
642
643
/* Copies an integer as hexadecimal to an UTF-8 string
644
 * The string size should include the end of string character
645
 * Returns 1 if successful or -1 on error
646
 */
647
int libfwevt_integer_as_hexadecimal_copy_to_utf8_string_with_index(
648
     uint64_t integer_value,
649
     uint8_t integer_size,
650
     uint8_t *utf8_string,
651
     size_t utf8_string_size,
652
     size_t *utf8_string_index,
653
     libcerror_error_t **error )
654
0
{
655
0
  static char *function         = "libfwevt_integer_as_hexadecimal_copy_to_utf8_string_with_index";
656
0
  size_t safe_utf8_string_index = 0;
657
0
  uint8_t number_of_characters  = 0;
658
0
  uint8_t byte_value            = 0;
659
0
  int8_t bit_shift              = 0;
660
661
0
  if( integer_size == 32 )
662
0
  {
663
0
    number_of_characters = 11;
664
0
  }
665
0
  else if( integer_size == 64 )
666
0
  {
667
0
    number_of_characters = 19;
668
0
  }
669
0
  else
670
0
  {
671
0
    libcerror_error_set(
672
0
     error,
673
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
674
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
675
0
     "%s: unsupported integer size.",
676
0
     function );
677
678
0
    return( -1 );
679
0
  }
680
0
  if( utf8_string == NULL )
681
0
  {
682
0
    libcerror_error_set(
683
0
     error,
684
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
685
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
686
0
     "%s: invalid UTF-8 string.",
687
0
     function );
688
689
0
    return( -1 );
690
0
  }
691
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
692
0
  {
693
0
    libcerror_error_set(
694
0
     error,
695
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
696
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
697
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
698
0
     function );
699
700
0
    return( -1 );
701
0
  }
702
0
  if( utf8_string_index == NULL )
703
0
  {
704
0
    libcerror_error_set(
705
0
     error,
706
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
707
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
708
0
     "%s: invalid UTF-8 string index.",
709
0
     function );
710
711
0
    return( -1 );
712
0
  }
713
0
  safe_utf8_string_index = *utf8_string_index;
714
715
0
  if( ( number_of_characters > utf8_string_size )
716
0
   || ( safe_utf8_string_index > ( utf8_string_size - number_of_characters ) ) )
717
0
  {
718
0
    libcerror_error_set(
719
0
     error,
720
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
721
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
722
0
     "%s: invalid UTF-8 string size value too small.",
723
0
     function );
724
725
0
    return( -1 );
726
0
  }
727
0
  utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0';
728
0
  utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'x';
729
730
0
  bit_shift = (uint8_t) ( integer_size - 4 );
731
732
0
  do
733
0
  {
734
0
    byte_value = (uint8_t) ( ( integer_value >> bit_shift ) & 0x0f );
735
736
0
    if( byte_value <= 9 )
737
0
    {
738
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) '0' + byte_value;
739
0
    }
740
0
    else
741
0
    {
742
0
      utf8_string[ safe_utf8_string_index++ ] = (uint8_t) 'a' + byte_value - 10;
743
0
    }
744
0
    bit_shift -= 4;
745
0
  }
746
0
  while( bit_shift >= 0 );
747
748
0
  utf8_string[ safe_utf8_string_index++ ] = 0;
749
750
0
  *utf8_string_index = safe_utf8_string_index;
751
752
0
  return( 1 );
753
0
}
754
755
/* Copies an integer as hexadecimal to an UTF-16 string
756
 * The string size should include the end of string character
757
 * Returns 1 if successful or -1 on error
758
 */
759
int libfwevt_integer_as_hexadecimal_copy_to_utf16_string_with_index(
760
     uint64_t integer_value,
761
     uint8_t integer_size,
762
     uint16_t *utf16_string,
763
     size_t utf16_string_size,
764
     size_t *utf16_string_index,
765
     libcerror_error_t **error )
766
0
{
767
0
  static char *function          = "libfwevt_integer_as_hexadecimal_copy_to_utf16_string_with_index";
768
0
  size_t safe_utf16_string_index = 0;
769
0
  uint8_t number_of_characters   = 0;
770
0
  uint8_t byte_value             = 0;
771
0
  int8_t bit_shift               = 0;
772
773
0
  if( integer_size == 32 )
774
0
  {
775
0
    number_of_characters = 11;
776
0
  }
777
0
  else if( integer_size == 64 )
778
0
  {
779
0
    number_of_characters = 19;
780
0
  }
781
0
  else
782
0
  {
783
0
    libcerror_error_set(
784
0
     error,
785
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
786
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
787
0
     "%s: unsupported integer size.",
788
0
     function );
789
790
0
    return( -1 );
791
0
  }
792
0
  if( utf16_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 UTF-16 string.",
799
0
     function );
800
801
0
    return( -1 );
802
0
  }
803
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
804
0
  {
805
0
    libcerror_error_set(
806
0
     error,
807
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
808
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
809
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
810
0
     function );
811
812
0
    return( -1 );
813
0
  }
814
0
  if( utf16_string_index == 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 index.",
821
0
     function );
822
823
0
    return( -1 );
824
0
  }
825
0
  safe_utf16_string_index = *utf16_string_index;
826
827
0
  if( ( number_of_characters > utf16_string_size )
828
0
   || ( safe_utf16_string_index > ( utf16_string_size - number_of_characters ) ) )
829
0
  {
830
0
    libcerror_error_set(
831
0
     error,
832
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
833
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
834
0
     "%s: invalid UTF-16 string size value too small.",
835
0
     function );
836
837
0
    return( -1 );
838
0
  }
839
0
  utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0';
840
0
  utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'x';
841
842
0
  bit_shift = (uint16_t) ( integer_size - 4 );
843
844
0
  do
845
0
  {
846
0
    byte_value = (uint16_t) ( ( integer_value >> bit_shift ) & 0x0f );
847
848
0
    if( byte_value <= 9 )
849
0
    {
850
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) '0' + byte_value;
851
0
    }
852
0
    else
853
0
    {
854
0
      utf16_string[ safe_utf16_string_index++ ] = (uint16_t) 'a' + byte_value - 10;
855
0
    }
856
0
    bit_shift -= 4;
857
0
  }
858
0
  while( bit_shift >= 0 );
859
860
0
  utf16_string[ safe_utf16_string_index++ ] = 0;
861
862
0
  *utf16_string_index = safe_utf16_string_index;
863
864
0
  return( 1 );
865
0
}
866