Coverage Report

Created: 2023-06-07 06:53

/src/libevtx/libfwevt/libfwevt_xml_document.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Windows Event Log binary XML document functions
3
 *
4
 * Copyright (C) 2011-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 <system_string.h>
26
#include <types.h>
27
28
#include "libfwevt_debug.h"
29
#include "libfwevt_definitions.h"
30
#include "libfwevt_libcdata.h"
31
#include "libfwevt_libcerror.h"
32
#include "libfwevt_libcnotify.h"
33
#include "libfwevt_libfguid.h"
34
#include "libfwevt_libfvalue.h"
35
#include "libfwevt_types.h"
36
#include "libfwevt_xml_document.h"
37
#include "libfwevt_xml_template_value.h"
38
#include "libfwevt_xml_tag.h"
39
#include "libfwevt_xml_token.h"
40
41
/* Creates a binary XML document
42
 * Make sure the value xml_document is referencing, is set to NULL
43
 * Returns 1 if successful or -1 on error
44
 */
45
int libfwevt_xml_document_initialize(
46
     libfwevt_xml_document_t **xml_document,
47
     libcerror_error_t **error )
48
5.21k
{
49
5.21k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
50
5.21k
  static char *function                                   = "libfwevt_xml_document_initialize";
51
52
5.21k
  if( xml_document == NULL )
53
0
  {
54
0
    libcerror_error_set(
55
0
     error,
56
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
57
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
58
0
     "%s: invalid binary XML document.",
59
0
     function );
60
61
0
    return( -1 );
62
0
  }
63
5.21k
  if( *xml_document != NULL )
64
0
  {
65
0
    libcerror_error_set(
66
0
     error,
67
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
68
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
69
0
     "%s: invalid binary XML document value already set.",
70
0
     function );
71
72
0
    return( -1 );
73
0
  }
74
5.21k
  internal_xml_document = memory_allocate_structure(
75
5.21k
                           libfwevt_internal_xml_document_t );
76
77
5.21k
  if( internal_xml_document == NULL )
78
0
  {
79
0
    libcerror_error_set(
80
0
     error,
81
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
82
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
83
0
     "%s: unable to create binary XML document.",
84
0
     function );
85
86
0
    goto on_error;
87
0
  }
88
5.21k
  if( memory_set(
89
5.21k
       internal_xml_document,
90
5.21k
       0,
91
5.21k
       sizeof( libfwevt_internal_xml_document_t ) ) == NULL )
92
0
  {
93
0
    libcerror_error_set(
94
0
     error,
95
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
96
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
97
0
     "%s: unable to clear binary XML document.",
98
0
     function );
99
100
0
    goto on_error;
101
0
  }
102
5.21k
  *xml_document = (libfwevt_xml_document_t *) internal_xml_document;
103
104
5.21k
  return( 1 );
105
106
0
on_error:
107
0
  if( internal_xml_document != NULL )
108
0
  {
109
0
    memory_free(
110
0
     internal_xml_document );
111
0
  }
112
0
  return( -1 );
113
5.21k
}
114
115
/* Frees a binary XML document
116
 * Returns 1 if successful or -1 on error
117
 */
118
int libfwevt_xml_document_free(
119
     libfwevt_xml_document_t **xml_document,
120
     libcerror_error_t **error )
121
5.21k
{
122
5.21k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
123
5.21k
  static char *function                                   = "libfwevt_xml_document_free";
124
5.21k
  int result                                              = 1;
125
126
5.21k
  if( xml_document == NULL )
127
0
  {
128
0
    libcerror_error_set(
129
0
     error,
130
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
131
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
132
0
     "%s: invalid binary XML document.",
133
0
     function );
134
135
0
    return( -1 );
136
0
  }
137
5.21k
  if( *xml_document != NULL )
138
5.21k
  {
139
5.21k
    internal_xml_document = (libfwevt_internal_xml_document_t *) *xml_document;
140
5.21k
    *xml_document         = NULL;
141
142
5.21k
    if( internal_xml_document->root_xml_tag != NULL )
143
381
    {
144
381
      if( libfwevt_xml_tag_free(
145
381
           &( internal_xml_document->root_xml_tag ),
146
381
           error ) != 1 )
147
0
      {
148
0
        libcerror_error_set(
149
0
         error,
150
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
151
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
152
0
         "%s: unable to free root XML tag.",
153
0
         function );
154
155
0
        result = -1;
156
0
      }
157
381
    }
158
5.21k
    memory_free(
159
5.21k
     internal_xml_document );
160
5.21k
  }
161
5.21k
  return( result );
162
5.21k
}
163
164
/* Retrieves the root XML tag
165
 * Returns 1 if successful or -1 on error
166
 */
167
int libfwevt_xml_document_get_root_xml_tag(
168
     libfwevt_xml_document_t *xml_document,
169
     libfwevt_xml_tag_t **root_xml_tag,
170
     libcerror_error_t **error )
171
0
{
172
0
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
173
0
  static char *function                                   = "libfwevt_xml_document_get_root_xml_tag";
174
175
0
  if( xml_document == NULL )
176
0
  {
177
0
    libcerror_error_set(
178
0
     error,
179
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
180
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
181
0
     "%s: invalid binary XML document.",
182
0
     function );
183
184
0
    return( -1 );
185
0
  }
186
0
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
187
188
0
  if( root_xml_tag == NULL )
189
0
  {
190
0
    libcerror_error_set(
191
0
     error,
192
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
193
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
194
0
     "%s: invalid root XML tag.",
195
0
     function );
196
197
0
    return( -1 );
198
0
  }
199
0
  *root_xml_tag = internal_xml_document->root_xml_tag;
200
201
0
  return( 1 );
202
0
}
203
204
/* Reads a binary XML document
205
 * Returns 1 if successful or -1 on error
206
 */
207
int libfwevt_xml_document_read(
208
     libfwevt_xml_document_t *xml_document,
209
     const uint8_t *binary_data,
210
     size_t binary_data_size,
211
     size_t binary_data_offset,
212
     int ascii_codepage,
213
     uint8_t flags,
214
     libcerror_error_t **error )
215
5.21k
{
216
5.21k
  static char *function = "libfwevt_xml_document_read";
217
218
5.21k
  if( libfwevt_xml_document_read_with_template_values(
219
5.21k
       xml_document,
220
5.21k
       binary_data,
221
5.21k
       binary_data_size,
222
5.21k
       binary_data_offset,
223
5.21k
       ascii_codepage,
224
5.21k
       flags,
225
5.21k
       NULL,
226
5.21k
       error ) != 1 )
227
5.09k
  {
228
5.09k
    libcerror_error_set(
229
5.09k
     error,
230
5.09k
     LIBCERROR_ERROR_DOMAIN_IO,
231
5.09k
     LIBCERROR_IO_ERROR_READ_FAILED,
232
5.09k
     "%s: unable to read XML document.",
233
5.09k
     function );
234
235
5.09k
    return( -1 );
236
5.09k
  }
237
124
  return( 1 );
238
5.21k
}
239
240
/* Reads a binary XML document with template values
241
 * Returns 1 if successful or -1 on error
242
 */
243
int libfwevt_xml_document_read_with_template_values(
244
     libfwevt_xml_document_t *xml_document,
245
     const uint8_t *binary_data,
246
     size_t binary_data_size,
247
     size_t binary_data_offset,
248
     int ascii_codepage,
249
     uint8_t flags,
250
     libcdata_array_t *template_values_array,
251
     libcerror_error_t **error )
252
5.21k
{
253
5.21k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
254
5.21k
  libfwevt_xml_token_t *xml_token                         = NULL;
255
5.21k
  static char *function                                   = "libfwevt_xml_document_read_with_template_values";
256
5.21k
  uint8_t supported_flags                                 = 0;
257
258
5.21k
  if( xml_document == NULL )
259
0
  {
260
0
    libcerror_error_set(
261
0
     error,
262
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
263
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
264
0
     "%s: invalid binary XML document.",
265
0
     function );
266
267
0
    return( -1 );
268
0
  }
269
5.21k
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
270
271
5.21k
  if( internal_xml_document->root_xml_tag != NULL )
272
0
  {
273
0
    libcerror_error_set(
274
0
     error,
275
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
276
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
277
0
     "%s: invalid binary XML document - root XML tag already set.",
278
0
     function );
279
280
0
    return( -1 );
281
0
  }
282
5.21k
  if( binary_data == NULL )
283
0
  {
284
0
    libcerror_error_set(
285
0
     error,
286
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
287
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
288
0
     "%s: invalid binary data.",
289
0
     function );
290
291
0
    return( -1 );
292
0
  }
293
5.21k
  if( binary_data_size > (size_t) SSIZE_MAX )
294
0
  {
295
0
    libcerror_error_set(
296
0
     error,
297
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
298
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
299
0
     "%s: invalid binary XML document data size value exceeds maximum.",
300
0
     function );
301
302
0
    return( -1 );
303
0
  }
304
5.21k
  if( binary_data_offset >= binary_data_size )
305
0
  {
306
0
    libcerror_error_set(
307
0
     error,
308
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
309
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
310
0
     "%s: invalid binary data offset value out of bounds.",
311
0
     function );
312
313
0
    return( -1 );
314
0
  }
315
5.21k
  supported_flags = LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS
316
5.21k
                  | LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DEPENDENCY_IDENTIFIERS;
317
318
5.21k
  if( ( flags & ~( supported_flags ) ) != 0 )
319
0
  {
320
0
    libcerror_error_set(
321
0
     error,
322
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
323
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
324
0
     "%s: unsupported flags: 0x%02" PRIx8 ".",
325
0
     function,
326
0
     flags );
327
328
0
    return( -1 );
329
0
  }
330
5.21k
  if( libfwevt_xml_token_initialize(
331
5.21k
       &xml_token,
332
5.21k
       error ) != 1 )
333
0
  {
334
0
    libcerror_error_set(
335
0
     error,
336
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
337
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
338
0
     "%s: unable to create binary XML token.",
339
0
     function );
340
341
0
    goto on_error;
342
0
  }
343
17.9k
  while( binary_data_offset < binary_data_size )
344
17.9k
  {
345
17.9k
    if( libfwevt_xml_token_read_data(
346
17.9k
         xml_token,
347
17.9k
         binary_data,
348
17.9k
         binary_data_size,
349
17.9k
         binary_data_offset,
350
17.9k
         error ) != 1 )
351
26
    {
352
26
      libcerror_error_set(
353
26
       error,
354
26
       LIBCERROR_ERROR_DOMAIN_IO,
355
26
       LIBCERROR_IO_ERROR_READ_FAILED,
356
26
       "%s: unable to read binary XML token.",
357
26
       function );
358
359
26
      goto on_error;
360
26
    }
361
/* TODO check for prologue */
362
/* TODO validate the order */
363
/* TODO check for Miscellaneous before end of file token */
364
17.9k
    switch( xml_token->type & 0xbf )
365
17.9k
    {
366
127
      case LIBFWEVT_XML_TOKEN_END_OF_FILE:
367
127
        if( ( binary_data_size < 1 )
368
127
         || ( binary_data_offset >= ( binary_data_size - 1 ) ) )
369
12
        {
370
12
          libcerror_error_set(
371
12
           error,
372
12
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
373
12
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
374
12
           "%s: invalid binary XML document data size value too small.",
375
12
           function );
376
377
12
          goto on_error;
378
12
        }
379
#if defined( HAVE_DEBUG_OUTPUT )
380
        if( libcnotify_verbose != 0 )
381
        {
382
          libcnotify_printf(
383
           "%s: data offset\t\t: 0x%08" PRIzx "\n",
384
           function,
385
           binary_data_offset );
386
387
          libcnotify_printf(
388
           "%s: end of file data:\n",
389
           function );
390
          libcnotify_print_data(
391
           &( binary_data[ binary_data_offset ] ),
392
           1,
393
           0 );
394
        }
395
#endif
396
#if defined( HAVE_DEBUG_OUTPUT )
397
        if( libcnotify_verbose != 0 )
398
        {
399
          libcnotify_printf(
400
           "%s: type\t\t\t: 0x%02" PRIx8 "\n",
401
           function,
402
           binary_data[ binary_data_offset ] );
403
404
          libcnotify_printf(
405
           "\n" );
406
        }
407
#endif
408
115
        xml_token->size = 1;
409
410
115
        break;
411
412
17.7k
      case LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER:
413
17.7k
        if( libfwevt_xml_document_read_fragment(
414
17.7k
             internal_xml_document,
415
17.7k
             xml_token,
416
17.7k
             binary_data,
417
17.7k
             binary_data_size,
418
17.7k
             binary_data_offset,
419
17.7k
             ascii_codepage,
420
17.7k
             flags,
421
17.7k
             template_values_array,
422
17.7k
             internal_xml_document->root_xml_tag,
423
17.7k
             0,
424
17.7k
             0,
425
17.7k
             error ) != 1 )
426
4.99k
        {
427
4.99k
          libcerror_error_set(
428
4.99k
           error,
429
4.99k
           LIBCERROR_ERROR_DOMAIN_IO,
430
4.99k
           LIBCERROR_IO_ERROR_READ_FAILED,
431
4.99k
           "%s: unable to read fragment header.",
432
4.99k
           function );
433
434
4.99k
          goto on_error;
435
4.99k
        }
436
12.7k
        break;
437
438
12.7k
      default:
439
58
        libcerror_error_set(
440
58
         error,
441
58
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
442
58
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
443
58
         "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
444
58
         function,
445
58
         xml_token->type );
446
447
58
        goto on_error;
448
17.9k
    }
449
12.8k
    internal_xml_document->size += xml_token->size;
450
12.8k
    binary_data_offset          += xml_token->size;
451
452
12.8k
    if( xml_token->type == LIBFWEVT_XML_TOKEN_END_OF_FILE )
453
115
    {
454
115
      break;
455
115
    }
456
12.8k
  }
457
124
  if( libfwevt_xml_token_free(
458
124
       &xml_token,
459
124
       error ) != 1 )
460
0
  {
461
0
    libcerror_error_set(
462
0
     error,
463
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
464
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
465
0
     "%s: unable to free binary XML token.",
466
0
     function );
467
468
0
    goto on_error;
469
0
  }
470
124
  return( 1 );
471
472
5.09k
on_error:
473
5.09k
  if( xml_token != NULL )
474
5.09k
  {
475
5.09k
    libfwevt_xml_token_free(
476
5.09k
     &xml_token,
477
5.09k
     NULL );
478
5.09k
  }
479
5.09k
  return( -1 );
480
124
}
481
482
/* Reads an attribute from a binary XML document
483
 * Returns 1 if successful or -1 on error
484
 */
485
int libfwevt_xml_document_read_attribute(
486
     libfwevt_internal_xml_document_t *internal_xml_document,
487
     libfwevt_xml_token_t *xml_token,
488
     const uint8_t *binary_data,
489
     size_t binary_data_size,
490
     size_t binary_data_offset,
491
     int ascii_codepage,
492
     uint8_t flags,
493
     libcdata_array_t *template_values_array,
494
     libfwevt_xml_tag_t *xml_tag,
495
     int element_recursion_depth,
496
     int template_instance_recursion_depth,
497
     libcerror_error_t **error )
498
77.9k
{
499
77.9k
  libfwevt_xml_tag_t *attribute_xml_tag    = NULL;
500
77.9k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
501
77.9k
  const uint8_t *xml_document_data         = NULL;
502
77.9k
  static char *function                    = "libfwevt_xml_document_read_attribute";
503
77.9k
  size_t additional_value_size             = 0;
504
77.9k
  size_t template_value_offset             = 0;
505
77.9k
  size_t trailing_data_size                = 0;
506
77.9k
  size_t xml_document_data_offset          = 0;
507
77.9k
  size_t xml_document_data_size            = 0;
508
77.9k
  uint32_t attribute_name_offset           = 0;
509
77.9k
  uint32_t attribute_name_size             = 0;
510
77.9k
  int result                               = 0;
511
77.9k
  int template_value_array_recursion_depth = 0;
512
513
77.9k
  if( internal_xml_document == NULL )
514
0
  {
515
0
    libcerror_error_set(
516
0
     error,
517
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
518
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
519
0
     "%s: invalid binary XML document.",
520
0
     function );
521
522
0
    return( -1 );
523
0
  }
524
77.9k
  if( xml_token == NULL )
525
0
  {
526
0
    libcerror_error_set(
527
0
     error,
528
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
529
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
530
0
     "%s: invalid binary XML token.",
531
0
     function );
532
533
0
    return( -1 );
534
0
  }
535
77.9k
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_ATTRIBUTE )
536
38
  {
537
38
    libcerror_error_set(
538
38
     error,
539
38
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
540
38
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
541
38
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
542
38
     function,
543
38
     xml_token->type );
544
545
38
    return( -1 );
546
38
  }
547
77.9k
  if( binary_data == NULL )
548
0
  {
549
0
    libcerror_error_set(
550
0
     error,
551
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
552
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
553
0
     "%s: invalid binary data.",
554
0
     function );
555
556
0
    return( -1 );
557
0
  }
558
77.9k
  if( binary_data_size > (size_t) SSIZE_MAX )
559
0
  {
560
0
    libcerror_error_set(
561
0
     error,
562
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
563
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
564
0
     "%s: invalid binary XML document data size value exceeds maximum.",
565
0
     function );
566
567
0
    return( -1 );
568
0
  }
569
77.9k
  if( binary_data_offset >= binary_data_size )
570
0
  {
571
0
    libcerror_error_set(
572
0
     error,
573
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
574
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
575
0
     "%s: invalid binary data offset value out of bounds.",
576
0
     function );
577
578
0
    return( -1 );
579
0
  }
580
77.9k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) == 0 )
581
0
  {
582
0
    additional_value_size = 4;
583
584
0
    if( ( binary_data_size < 4 )
585
0
     || ( binary_data_offset > ( binary_data_size - 4 ) ) )
586
0
    {
587
0
      libcerror_error_set(
588
0
       error,
589
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
590
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
591
0
       "%s: invalid binary data offset value out of bounds.",
592
0
       function );
593
594
0
      return( -1 );
595
0
    }
596
0
  }
597
77.9k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
598
77.9k
  xml_document_data_size = binary_data_size - binary_data_offset;
599
600
77.9k
  if( libfwevt_xml_token_initialize(
601
77.9k
       &xml_sub_token,
602
77.9k
       error ) != 1 )
603
0
  {
604
0
    libcerror_error_set(
605
0
     error,
606
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
607
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
608
0
     "%s: unable to create binary XML sub token.",
609
0
     function );
610
611
0
    goto on_error;
612
0
  }
613
77.9k
  do
614
80.2k
  {
615
80.2k
    if( ( template_value_array_recursion_depth < 0 )
616
80.2k
     || ( template_value_array_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_VALUE_ARRAY_RECURSION_DEPTH ) )
617
1
    {
618
1
      libcerror_error_set(
619
1
       error,
620
1
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
621
1
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
622
1
       "%s: invalid template value array recursion depth value out of bounds.",
623
1
       function );
624
625
1
      goto on_error;
626
1
    }
627
80.2k
    if( ( xml_document_data_size < ( additional_value_size + 1 ) )
628
80.2k
     || ( xml_document_data_offset > ( xml_document_data_size - ( additional_value_size + 1 ) ) ) )
629
10
    {
630
10
      libcerror_error_set(
631
10
       error,
632
10
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
633
10
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
634
10
       "%s: invalid binary XML document data size value too small.",
635
10
       function );
636
637
10
      goto on_error;
638
10
    }
639
#if defined( HAVE_DEBUG_OUTPUT )
640
    if( libcnotify_verbose != 0 )
641
    {
642
      libcnotify_printf(
643
       "%s: data offset\t\t\t: 0x%08" PRIzx "\n",
644
       function,
645
       binary_data_offset + xml_document_data_offset );
646
647
      libcnotify_printf(
648
       "%s: attribute data:\n",
649
       function );
650
      libcnotify_print_data(
651
       &( xml_document_data[ xml_document_data_offset ] ),
652
       additional_value_size + 1,
653
       0 );
654
    }
655
#endif
656
#if defined( HAVE_DEBUG_OUTPUT )
657
    if( libcnotify_verbose != 0 )
658
    {
659
      libcnotify_printf(
660
       "%s: type\t\t\t\t: 0x%02" PRIx8 "\n",
661
       function,
662
       xml_document_data[ xml_document_data_offset ] );
663
    }
664
#endif
665
80.2k
    xml_document_data_offset += 1;
666
667
80.2k
    if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) == 0 )
668
0
    {
669
0
      attribute_name_offset = (uint32_t) ( binary_data_offset + xml_document_data_offset );
670
0
    }
671
80.2k
    else
672
80.2k
    {
673
80.2k
      if( ( xml_document_data_size < 4 )
674
80.2k
       || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
675
18
      {
676
18
        libcerror_error_set(
677
18
         error,
678
18
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
679
18
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
680
18
         "%s: invalid binary XML document data size value too small.",
681
18
         function );
682
683
18
        goto on_error;
684
18
      }
685
80.2k
      byte_stream_copy_to_uint32_little_endian(
686
80.2k
       &( xml_document_data[ xml_document_data_offset ] ),
687
80.2k
       attribute_name_offset );
688
689
#if defined( HAVE_DEBUG_OUTPUT )
690
      if( libcnotify_verbose != 0 )
691
      {
692
        libcnotify_printf(
693
         "%s: name offset\t\t\t: 0x%08" PRIx32 "\n",
694
         function,
695
         attribute_name_offset );
696
      }
697
#endif
698
80.2k
      xml_document_data_offset += 4;
699
80.2k
    }
700
#if defined( HAVE_DEBUG_OUTPUT )
701
    if( libcnotify_verbose != 0 )
702
    {
703
      libcnotify_printf(
704
       "\n" );
705
    }
706
#endif
707
80.2k
    if( attribute_name_offset > ( binary_data_offset + xml_document_data_offset ) )
708
165
    {
709
165
      libcerror_error_set(
710
165
       error,
711
165
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
712
165
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
713
165
       "%s: invalid attribute data offset value out of bounds.",
714
165
       function );
715
716
165
      goto on_error;
717
165
    }
718
80.0k
    if( ( binary_data_offset + xml_document_data_offset ) < attribute_name_offset )
719
0
    {
720
0
      trailing_data_size = attribute_name_offset - ( binary_data_offset - xml_document_data_offset );
721
722
#if defined( HAVE_DEBUG_OUTPUT )
723
      if( libcnotify_verbose != 0 )
724
      {
725
        libcnotify_printf(
726
         "%s: data offset\t\t: 0x%08" PRIzx "\n",
727
         function,
728
         binary_data_offset + xml_document_data_offset );
729
730
        libcnotify_printf(
731
         "%s: trailing data:\n",
732
         function );
733
        libcnotify_print_data(
734
         &( xml_document_data[ xml_document_data_offset ] ),
735
         trailing_data_size,
736
         0 );
737
      }
738
#endif
739
0
      xml_document_data_offset += trailing_data_size;
740
0
    }
741
80.0k
    if( libfwevt_xml_tag_initialize(
742
80.0k
         &attribute_xml_tag,
743
80.0k
         error ) != 1 )
744
0
    {
745
0
      libcerror_error_set(
746
0
       error,
747
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
748
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
749
0
       "%s: unable to create attribute XML tag.",
750
0
       function );
751
752
0
      goto on_error;
753
0
    }
754
80.0k
    if( libfwevt_xml_document_read_name(
755
80.0k
         internal_xml_document,
756
80.0k
         binary_data,
757
80.0k
         binary_data_size,
758
80.0k
         attribute_name_offset,
759
80.0k
         flags,
760
80.0k
         &attribute_name_size,
761
80.0k
         attribute_xml_tag,
762
80.0k
         error ) != 1 )
763
10
    {
764
10
      libcerror_error_set(
765
10
       error,
766
10
       LIBCERROR_ERROR_DOMAIN_IO,
767
10
       LIBCERROR_IO_ERROR_READ_FAILED,
768
10
       "%s: unable to read attribute name.",
769
10
       function );
770
771
10
      goto on_error;
772
10
    }
773
80.0k
    if( ( binary_data_offset + xml_document_data_offset ) == attribute_name_offset )
774
11.1k
    {
775
11.1k
      xml_document_data_offset += attribute_name_size;
776
11.1k
    }
777
80.0k
    if( libfwevt_xml_token_read_data(
778
80.0k
         xml_sub_token,
779
80.0k
         binary_data,
780
80.0k
         binary_data_size,
781
80.0k
         binary_data_offset + xml_document_data_offset,
782
80.0k
         error ) != 1 )
783
10
    {
784
10
      libcerror_error_set(
785
10
       error,
786
10
       LIBCERROR_ERROR_DOMAIN_IO,
787
10
       LIBCERROR_IO_ERROR_READ_FAILED,
788
10
       "%s: unable to read binary XML sub token.",
789
10
       function );
790
791
10
      goto on_error;
792
10
    }
793
80.0k
    result = 1;
794
795
80.0k
    switch( xml_sub_token->type & 0xbf )
796
80.0k
    {
797
23.4k
      case LIBFWEVT_XML_TOKEN_VALUE:
798
23.4k
        if( template_value_offset != 0 )
799
3
        {
800
3
          libcerror_error_set(
801
3
           error,
802
3
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
803
3
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
804
3
           "%s: invalid template value offset value out of bounds.",
805
3
           function );
806
807
3
          goto on_error;
808
3
        }
809
23.4k
        if( libfwevt_xml_document_read_value(
810
23.4k
             internal_xml_document,
811
23.4k
             xml_sub_token,
812
23.4k
             binary_data,
813
23.4k
             binary_data_size,
814
23.4k
             binary_data_offset + xml_document_data_offset,
815
23.4k
             attribute_xml_tag,
816
23.4k
             error ) != 1 )
817
46
        {
818
46
          libcerror_error_set(
819
46
           error,
820
46
           LIBCERROR_ERROR_DOMAIN_IO,
821
46
           LIBCERROR_IO_ERROR_READ_FAILED,
822
46
           "%s: unable to read value.",
823
46
           function );
824
825
46
          goto on_error;
826
46
        }
827
23.4k
        break;
828
829
23.4k
      case LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION:
830
6.65k
        result = libfwevt_xml_document_read_normal_substitution(
831
6.65k
                  internal_xml_document,
832
6.65k
                  xml_sub_token,
833
6.65k
                  binary_data,
834
6.65k
                  binary_data_size,
835
6.65k
                  binary_data_offset + xml_document_data_offset,
836
6.65k
                  ascii_codepage,
837
6.65k
                  flags,
838
6.65k
                  template_values_array,
839
6.65k
                  &template_value_offset,
840
6.65k
                  attribute_xml_tag,
841
6.65k
                  element_recursion_depth,
842
6.65k
                  template_instance_recursion_depth,
843
6.65k
                  error );
844
845
6.65k
        if( result == -1 )
846
2.06k
        {
847
2.06k
          libcerror_error_set(
848
2.06k
           error,
849
2.06k
           LIBCERROR_ERROR_DOMAIN_IO,
850
2.06k
           LIBCERROR_IO_ERROR_READ_FAILED,
851
2.06k
           "%s: unable to read normal substitution.",
852
2.06k
           function );
853
854
2.06k
          goto on_error;
855
2.06k
        }
856
4.58k
        break;
857
858
49.8k
      case LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION:
859
49.8k
        result = libfwevt_xml_document_read_optional_substitution(
860
49.8k
            internal_xml_document,
861
49.8k
            xml_sub_token,
862
49.8k
            binary_data,
863
49.8k
            binary_data_size,
864
49.8k
            binary_data_offset + xml_document_data_offset,
865
49.8k
            ascii_codepage,
866
49.8k
            flags,
867
49.8k
            template_values_array,
868
49.8k
            &template_value_offset,
869
49.8k
            attribute_xml_tag,
870
49.8k
                  element_recursion_depth,
871
49.8k
                  template_instance_recursion_depth,
872
49.8k
            error );
873
874
49.8k
        if( result == -1 )
875
1.42k
        {
876
1.42k
          libcerror_error_set(
877
1.42k
           error,
878
1.42k
           LIBCERROR_ERROR_DOMAIN_IO,
879
1.42k
           LIBCERROR_IO_ERROR_READ_FAILED,
880
1.42k
           "%s: unable to read optional substitution.",
881
1.42k
           function );
882
883
1.42k
          goto on_error;
884
1.42k
        }
885
48.4k
        break;
886
887
48.4k
      default:
888
22
        libcerror_error_set(
889
22
         error,
890
22
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
891
22
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
892
22
         "%s: invalid binary XML sub token - unsupported type: 0x%02" PRIx8 ".",
893
22
         function,
894
22
         xml_sub_token->type );
895
896
22
        goto on_error;
897
80.0k
    }
898
76.4k
    if( result != 0 )
899
65.8k
    {
900
65.8k
      if( libfwevt_xml_tag_append_attribute(
901
65.8k
           xml_tag,
902
65.8k
           attribute_xml_tag,
903
65.8k
           error ) != 1 )
904
0
      {
905
0
        libcerror_error_set(
906
0
         error,
907
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
908
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
909
0
         "%s: unable to append attribute to XML tag.",
910
0
         function );
911
912
0
        goto on_error;
913
0
      }
914
65.8k
      attribute_xml_tag = NULL;
915
65.8k
    }
916
76.4k
    xml_document_data_offset += xml_sub_token->size;
917
918
76.4k
    template_value_array_recursion_depth++;
919
76.4k
  }
920
77.9k
  while( template_value_offset > 0 );
921
922
74.1k
  xml_token->size = xml_document_data_offset;
923
924
74.1k
  if( attribute_xml_tag != NULL )
925
10.6k
  {
926
10.6k
    if( libfwevt_xml_tag_free(
927
10.6k
         &attribute_xml_tag,
928
10.6k
         error ) != 1 )
929
0
    {
930
0
      libcerror_error_set(
931
0
       error,
932
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
933
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
934
0
       "%s: unable to free attribute XML tag.",
935
0
       function );
936
937
0
      goto on_error;
938
0
    }
939
10.6k
  }
940
74.1k
  if( libfwevt_xml_token_free(
941
74.1k
       &xml_sub_token,
942
74.1k
       error ) != 1 )
943
0
  {
944
0
    libcerror_error_set(
945
0
     error,
946
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
947
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
948
0
     "%s: unable to free binary XML sub token.",
949
0
     function );
950
951
0
    goto on_error;
952
0
  }
953
74.1k
  return( 1 );
954
955
3.76k
on_error:
956
3.76k
  if( attribute_xml_tag != NULL )
957
3.57k
  {
958
3.57k
    libfwevt_xml_tag_free(
959
3.57k
     &attribute_xml_tag,
960
3.57k
     NULL );
961
3.57k
  }
962
3.76k
  if( xml_sub_token != NULL )
963
3.76k
  {
964
3.76k
    libfwevt_xml_token_free(
965
3.76k
     &xml_sub_token,
966
3.76k
     NULL );
967
3.76k
  }
968
3.76k
  return( -1 );
969
74.1k
}
970
971
/* Reads a CDATA section from a binary XML document
972
 * Returns 1 if successful or -1 on error
973
 */
974
int libfwevt_xml_document_read_cdata_section(
975
     libfwevt_internal_xml_document_t *internal_xml_document,
976
     libfwevt_xml_token_t *xml_token,
977
     const uint8_t *binary_data,
978
     size_t binary_data_size,
979
     size_t binary_data_offset,
980
     libfwevt_xml_tag_t *xml_tag,
981
     libcerror_error_t **error )
982
4.91k
{
983
4.91k
  const uint8_t *xml_document_data = NULL;
984
4.91k
  static char *function            = "libfwevt_xml_document_read_cdata_section";
985
4.91k
  size_t value_data_size           = 0;
986
4.91k
  size_t xml_document_data_size    = 0;
987
988
4.91k
  if( internal_xml_document == NULL )
989
0
  {
990
0
    libcerror_error_set(
991
0
     error,
992
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
993
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
994
0
     "%s: invalid binary XML document.",
995
0
     function );
996
997
0
    return( -1 );
998
0
  }
999
4.91k
  if( xml_token == NULL )
1000
0
  {
1001
0
    libcerror_error_set(
1002
0
     error,
1003
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1004
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1005
0
     "%s: invalid binary XML token.",
1006
0
     function );
1007
1008
0
    return( -1 );
1009
0
  }
1010
4.91k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_CDATA_SECTION )
1011
3
  {
1012
3
    libcerror_error_set(
1013
3
     error,
1014
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1015
3
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1016
3
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1017
3
     function,
1018
3
     xml_token->type );
1019
1020
3
    return( -1 );
1021
3
  }
1022
4.91k
  if( binary_data == NULL )
1023
0
  {
1024
0
    libcerror_error_set(
1025
0
     error,
1026
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1027
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1028
0
     "%s: invalid binary data.",
1029
0
     function );
1030
1031
0
    return( -1 );
1032
0
  }
1033
4.91k
  if( binary_data_size > (size_t) SSIZE_MAX )
1034
0
  {
1035
0
    libcerror_error_set(
1036
0
     error,
1037
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1038
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1039
0
     "%s: invalid binary XML document data size value exceeds maximum.",
1040
0
     function );
1041
1042
0
    return( -1 );
1043
0
  }
1044
4.91k
  if( binary_data_offset >= binary_data_size )
1045
0
  {
1046
0
    libcerror_error_set(
1047
0
     error,
1048
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1049
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1050
0
     "%s: invalid binary data offset value out of bounds.",
1051
0
     function );
1052
1053
0
    return( -1 );
1054
0
  }
1055
4.91k
  if( xml_tag == NULL )
1056
0
  {
1057
0
    libcerror_error_set(
1058
0
     error,
1059
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1060
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1061
0
     "%s: invalid XML tag.",
1062
0
     function );
1063
1064
0
    return( -1 );
1065
0
  }
1066
4.91k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1067
4.91k
  xml_document_data_size = binary_data_size - binary_data_offset;
1068
1069
4.91k
  if( xml_document_data_size < 3 )
1070
21
  {
1071
21
    libcerror_error_set(
1072
21
     error,
1073
21
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1074
21
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1075
21
     "%s: invalid binary XML document data size value too small.",
1076
21
     function );
1077
1078
21
    return( -1 );
1079
21
  }
1080
4.89k
  if( libfwevt_xml_tag_set_type(
1081
4.89k
       xml_tag,
1082
4.89k
       LIBFWEVT_XML_TAG_TYPE_CDATA,
1083
4.89k
       error ) != 1 )
1084
0
  {
1085
0
    libcerror_error_set(
1086
0
     error,
1087
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1088
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1089
0
     "%s: unable to set XML tag type.",
1090
0
     function );
1091
1092
0
    return( -1 );
1093
0
  }
1094
#if defined( HAVE_DEBUG_OUTPUT )
1095
  if( libcnotify_verbose != 0 )
1096
  {
1097
    libcnotify_printf(
1098
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
1099
     function,
1100
     binary_data_offset );
1101
1102
    libcnotify_printf(
1103
     "%s: cdata section data:\n",
1104
     function );
1105
    libcnotify_print_data(
1106
     xml_document_data,
1107
     3,
1108
     0 );
1109
  }
1110
#endif
1111
4.89k
  byte_stream_copy_to_uint16_little_endian(
1112
4.89k
   &( xml_document_data[ 1 ] ),
1113
4.89k
   value_data_size );
1114
1115
#if defined( HAVE_DEBUG_OUTPUT )
1116
  if( libcnotify_verbose != 0 )
1117
  {
1118
    libcnotify_printf(
1119
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
1120
     function,
1121
     xml_document_data[ 0 ] );
1122
1123
    libcnotify_printf(
1124
     "%s: number of characters\t: %" PRIzd "\n",
1125
     function,
1126
     value_data_size );
1127
  }
1128
#endif
1129
4.89k
  xml_token->size     = 3;
1130
4.89k
  binary_data_offset += 3;
1131
1132
4.89k
  value_data_size *= 2;
1133
1134
4.89k
  if( ( value_data_size > binary_data_size )
1135
4.89k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
1136
92
  {
1137
92
    libcerror_error_set(
1138
92
     error,
1139
92
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1140
92
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1141
92
     "%s: invalid value data size value out of bounds.",
1142
92
     function );
1143
1144
92
    return( -1 );
1145
92
  }
1146
#if defined( HAVE_DEBUG_OUTPUT )
1147
  if( libcnotify_verbose != 0 )
1148
  {
1149
    libcnotify_printf(
1150
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
1151
     function,
1152
     binary_data_offset );
1153
1154
    libcnotify_printf(
1155
     "%s: value data:\n",
1156
     function );
1157
    libcnotify_print_data(
1158
     &( xml_document_data[ 3 ] ),
1159
     value_data_size,
1160
     0 );
1161
  }
1162
#endif
1163
4.80k
  if( libfwevt_xml_tag_set_value_type(
1164
4.80k
       xml_tag,
1165
4.80k
       LIBFVALUE_VALUE_TYPE_STRING_UTF16,
1166
4.80k
       error ) != 1 )
1167
3
  {
1168
3
    libcerror_error_set(
1169
3
     error,
1170
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1171
3
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1172
3
     "%s: unable to set value type.",
1173
3
     function );
1174
1175
3
    return( -1 );
1176
3
  }
1177
4.79k
  if( libfwevt_xml_tag_set_value_data(
1178
4.79k
       xml_tag,
1179
4.79k
       &( binary_data[ binary_data_offset ] ),
1180
4.79k
       value_data_size,
1181
4.79k
       LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN,
1182
4.79k
       error ) != 1 )
1183
0
  {
1184
0
    libcerror_error_set(
1185
0
     error,
1186
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1187
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1188
0
     "%s: unable to set value data.",
1189
0
     function );
1190
1191
0
    return( -1 );
1192
0
  }
1193
#if defined( HAVE_DEBUG_OUTPUT )
1194
  if( libcnotify_verbose != 0 )
1195
  {
1196
    if( libfwevt_xml_tag_value_debug_print(
1197
         xml_tag,
1198
         0,
1199
         error ) != 1 )
1200
    {
1201
      libcerror_error_set(
1202
       error,
1203
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1204
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1205
       "%s: unable to print value.",
1206
       function );
1207
1208
      return( -1 );
1209
    }
1210
  }
1211
#endif
1212
4.79k
  xml_token->size += value_data_size;
1213
1214
4.79k
  return( 1 );
1215
4.79k
}
1216
1217
/* Reads a character entity reference from a binary XML document
1218
 * Returns 1 if successful or -1 on error
1219
 */
1220
int libfwevt_xml_document_read_character_reference(
1221
     libfwevt_internal_xml_document_t *internal_xml_document,
1222
     libfwevt_xml_token_t *xml_token,
1223
     const uint8_t *binary_data,
1224
     size_t binary_data_size,
1225
     size_t binary_data_offset,
1226
     libfwevt_xml_tag_t *xml_tag,
1227
     libcerror_error_t **error )
1228
4
{
1229
4
  libfwevt_xml_tag_t *character_xml_tag     = NULL;
1230
4
  uint16_t *character_value_string          = NULL;
1231
4
  uint8_t *character_value_utf16_stream     = NULL;
1232
4
  const uint8_t *xml_document_data          = NULL;
1233
4
  static char *function                     = "libfwevt_xml_document_read_character_reference";
1234
4
  size_t character_value_string_index       = 0;
1235
4
  size_t character_value_string_size        = 0;
1236
4
  size_t character_value_utf16_stream_index = 0;
1237
4
  size_t character_value_utf16_stream_size  = 0;
1238
4
  size_t xml_document_data_size             = 0;
1239
4
  uint16_t character_value                  = 0;
1240
4
  int value_entry_index                     = 0;
1241
1242
4
  if( internal_xml_document == NULL )
1243
0
  {
1244
0
    libcerror_error_set(
1245
0
     error,
1246
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1247
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1248
0
     "%s: invalid binary XML document.",
1249
0
     function );
1250
1251
0
    return( -1 );
1252
0
  }
1253
4
  if( xml_token == NULL )
1254
0
  {
1255
0
    libcerror_error_set(
1256
0
     error,
1257
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1258
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1259
0
     "%s: invalid binary XML token.",
1260
0
     function );
1261
1262
0
    return( -1 );
1263
0
  }
1264
4
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_ENTITY_REFERENCE )
1265
4
  {
1266
4
    libcerror_error_set(
1267
4
     error,
1268
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1269
4
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1270
4
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1271
4
     function,
1272
4
     xml_token->type );
1273
1274
4
    return( -1 );
1275
4
  }
1276
0
  if( binary_data == NULL )
1277
0
  {
1278
0
    libcerror_error_set(
1279
0
     error,
1280
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1281
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1282
0
     "%s: invalid binary data.",
1283
0
     function );
1284
1285
0
    return( -1 );
1286
0
  }
1287
0
  if( binary_data_size > (size_t) SSIZE_MAX )
1288
0
  {
1289
0
    libcerror_error_set(
1290
0
     error,
1291
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1292
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1293
0
     "%s: invalid binary XML document data size value exceeds maximum.",
1294
0
     function );
1295
1296
0
    return( -1 );
1297
0
  }
1298
0
  if( binary_data_offset >= binary_data_size )
1299
0
  {
1300
0
    libcerror_error_set(
1301
0
     error,
1302
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1303
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1304
0
     "%s: invalid binary data offset value out of bounds.",
1305
0
     function );
1306
1307
0
    return( -1 );
1308
0
  }
1309
0
  if( xml_tag == NULL )
1310
0
  {
1311
0
    libcerror_error_set(
1312
0
     error,
1313
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1314
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1315
0
     "%s: invalid XML tag.",
1316
0
     function );
1317
1318
0
    return( -1 );
1319
0
  }
1320
0
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1321
0
  xml_document_data_size = binary_data_size - binary_data_offset;
1322
1323
0
  if( xml_document_data_size < 3 )
1324
0
  {
1325
0
    libcerror_error_set(
1326
0
     error,
1327
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1328
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1329
0
     "%s: invalid binary XML document data size value too small.",
1330
0
     function );
1331
1332
0
    return( -1 );
1333
0
  }
1334
#if defined( HAVE_DEBUG_OUTPUT )
1335
  if( libcnotify_verbose != 0 )
1336
  {
1337
    libcnotify_printf(
1338
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
1339
     function,
1340
     binary_data_offset );
1341
1342
    libcnotify_printf(
1343
     "%s: character reference data:\n",
1344
     function );
1345
    libcnotify_print_data(
1346
     xml_document_data,
1347
     3,
1348
     0 );
1349
  }
1350
#endif
1351
0
  byte_stream_copy_to_uint16_little_endian(
1352
0
   &( xml_document_data[ 1 ] ),
1353
0
   character_value );
1354
1355
#if defined( HAVE_DEBUG_OUTPUT )
1356
  if( libcnotify_verbose != 0 )
1357
  {
1358
    libcnotify_printf(
1359
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
1360
     function,
1361
     xml_document_data[ 0 ] );
1362
1363
    libcnotify_printf(
1364
     "%s: character value\t\t: 0x%04" PRIx16 "\n",
1365
     function,
1366
     character_value );
1367
1368
    libcnotify_printf(
1369
     "\n" );
1370
  }
1371
#endif
1372
0
  xml_token->size = 3;
1373
1374
0
  if( libfvalue_string_size_from_integer(
1375
0
       &character_value_string_size,
1376
0
       (uint64_t) character_value,
1377
0
       16,
1378
0
       0,
1379
0
       error ) != 1 )
1380
0
  {
1381
0
    libcerror_error_set(
1382
0
     error,
1383
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1384
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1385
0
     "%s: unable to determine size of character value string.",
1386
0
     function );
1387
1388
0
    goto on_error;
1389
0
  }
1390
0
  character_value_string_size += 3;
1391
1392
0
  if( character_value_string_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( uint16_t ) ) )
1393
0
  {
1394
0
    libcerror_error_set(
1395
0
     error,
1396
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1397
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1398
0
     "%s: invalid character value string size value out of bounds.",
1399
0
     function );
1400
1401
0
    goto on_error;
1402
0
  }
1403
0
  character_value_string = (uint16_t *) memory_allocate(
1404
0
                                         sizeof( uint16_t ) * character_value_string_size );
1405
1406
0
  if( character_value_string == NULL )
1407
0
  {
1408
0
    libcerror_error_set(
1409
0
     error,
1410
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1411
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1412
0
     "%s: unable to create character value string.",
1413
0
     function );
1414
1415
0
    goto on_error;
1416
0
  }
1417
0
  character_value_string[ character_value_string_index++ ] = (uint16_t) '&';
1418
0
  character_value_string[ character_value_string_index++ ] = (uint16_t) '#';
1419
1420
0
  if( libfvalue_utf16_string_with_index_copy_from_integer(
1421
0
       character_value_string,
1422
0
       character_value_string_size,
1423
0
       &character_value_string_index,
1424
0
       (uint64_t) character_value,
1425
0
       16,
1426
0
       0,
1427
0
       error ) != 1 )
1428
0
  {
1429
0
    libcerror_error_set(
1430
0
     error,
1431
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1432
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1433
0
     "%s: unable to copy character value to UTF-16 string.",
1434
0
     function );
1435
1436
0
    goto on_error;
1437
0
  }
1438
0
  character_value_string[ character_value_string_size - 2 ] = (uint16_t) ';';
1439
0
  character_value_string[ character_value_string_size - 1 ] = 0;
1440
1441
0
  if( libfwevt_xml_tag_set_value_type(
1442
0
       xml_tag,
1443
0
       LIBFVALUE_VALUE_TYPE_STRING_UTF16,
1444
0
       error ) != 1 )
1445
0
  {
1446
0
    libcerror_error_set(
1447
0
     error,
1448
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1449
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1450
0
     "%s: unable to set value type.",
1451
0
     function );
1452
1453
0
    goto on_error;
1454
0
  }
1455
  /* Make sure the character value data is in UTF-16 litte-endian
1456
   */
1457
0
  if( ( character_value_utf16_stream_size == 0 )
1458
0
   || ( character_value_utf16_stream_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / 2 ) ) )
1459
0
  {
1460
0
    libcerror_error_set(
1461
0
     error,
1462
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1463
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1464
0
     "%s: invalid character value UTF-16 stream size value out of bounds.",
1465
0
     function );
1466
1467
0
    goto on_error;
1468
0
  }
1469
0
  character_value_utf16_stream_size = character_value_string_size * 2;
1470
1471
0
  character_value_utf16_stream = (uint8_t *) memory_allocate(
1472
0
                                              sizeof( uint8_t ) * character_value_utf16_stream_size );
1473
1474
0
  if( character_value_utf16_stream == NULL )
1475
0
  {
1476
0
    libcerror_error_set(
1477
0
     error,
1478
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1479
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1480
0
     "%s: unable to create character value UTF-16 stream.",
1481
0
     function );
1482
1483
0
    goto on_error;
1484
0
  }
1485
0
  for( character_value_string_index = 0;
1486
0
       character_value_string_index < character_value_string_size;
1487
0
       character_value_string_index++ )
1488
0
  {
1489
0
    byte_stream_copy_from_uint16_little_endian(
1490
0
     &( character_value_utf16_stream[ character_value_utf16_stream_index ] ),
1491
0
     character_value_string[ character_value_string_index ] );
1492
1493
0
    character_value_utf16_stream_index += 2;
1494
0
  }
1495
0
  memory_free(
1496
0
   character_value_string );
1497
1498
0
  character_value_string = NULL;
1499
1500
0
  if( libfwevt_xml_tag_append_value_data(
1501
0
       xml_tag,
1502
0
       character_value_utf16_stream,
1503
0
       character_value_utf16_stream_size,
1504
0
       LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN,
1505
0
       &value_entry_index,
1506
0
       error ) != 1 )
1507
0
  {
1508
0
    libcerror_error_set(
1509
0
     error,
1510
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1511
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1512
0
     "%s: unable to append value data.",
1513
0
     function );
1514
1515
0
    goto on_error;
1516
0
  }
1517
0
  memory_free(
1518
0
   character_value_utf16_stream );
1519
1520
0
  character_value_utf16_stream = NULL;
1521
1522
#if defined( HAVE_DEBUG_OUTPUT )
1523
  if( libcnotify_verbose != 0 )
1524
  {
1525
    if( libfwevt_xml_tag_value_debug_print(
1526
         xml_tag,
1527
         value_entry_index,
1528
         error ) != 1 )
1529
    {
1530
      libcerror_error_set(
1531
       error,
1532
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1533
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1534
       "%s: unable to print value: %d.",
1535
       function,
1536
       value_entry_index );
1537
1538
      goto on_error;
1539
    }
1540
  }
1541
#endif
1542
0
  if( libfwevt_xml_tag_free(
1543
0
       &character_xml_tag,
1544
0
       error ) != 1 )
1545
0
  {
1546
0
    libcerror_error_set(
1547
0
     error,
1548
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1549
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1550
0
     "%s: unable to free character XML tag.",
1551
0
     function );
1552
1553
0
    goto on_error;
1554
0
  }
1555
0
  return( 1 );
1556
1557
0
on_error:
1558
0
  if( character_value_utf16_stream != NULL )
1559
0
  {
1560
0
    memory_free(
1561
0
     character_value_utf16_stream );
1562
0
  }
1563
0
  if( character_value_string != NULL )
1564
0
  {
1565
0
    memory_free(
1566
0
     character_value_string );
1567
0
  }
1568
0
  if( character_xml_tag != NULL )
1569
0
  {
1570
0
    libfwevt_xml_tag_free(
1571
0
     &character_xml_tag,
1572
0
     NULL );
1573
0
  }
1574
0
  return( -1 );
1575
0
}
1576
1577
/* Reads an element from a binary XML document
1578
 * Returns 1 if successful or -1 on error
1579
 */
1580
int libfwevt_xml_document_read_element(
1581
     libfwevt_internal_xml_document_t *internal_xml_document,
1582
     libfwevt_xml_token_t *xml_token,
1583
     const uint8_t *binary_data,
1584
     size_t binary_data_size,
1585
     size_t binary_data_offset,
1586
     int ascii_codepage,
1587
     uint8_t flags,
1588
     libcdata_array_t *template_values_array,
1589
     libfwevt_xml_tag_t *xml_tag,
1590
     int element_recursion_depth,
1591
     int template_instance_recursion_depth,
1592
     libcerror_error_t **error )
1593
139k
{
1594
139k
  libfwevt_xml_tag_t *element_xml_tag      = NULL;
1595
139k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
1596
139k
  const uint8_t *xml_document_data         = NULL;
1597
139k
  static char *function                    = "libfwevt_xml_document_read_element";
1598
139k
  size_t additional_value_size             = 0;
1599
139k
  size_t element_size_offset               = 0;
1600
139k
  size_t template_value_offset             = 0;
1601
139k
  size_t trailing_data_size                = 0;
1602
139k
  size_t xml_document_data_offset          = 0;
1603
139k
  size_t xml_document_data_size            = 0;
1604
139k
  uint32_t attribute_list_size             = 0;
1605
139k
  uint32_t element_name_offset             = 0;
1606
139k
  uint32_t element_name_size               = 0;
1607
139k
  uint32_t element_size                    = 0;
1608
139k
  int result                               = 0;
1609
139k
  int template_value_array_recursion_depth = 0;
1610
1611
#if defined( HAVE_DEBUG_OUTPUT )
1612
  uint16_t value_16bit                     = 0;
1613
#endif
1614
1615
139k
  if( internal_xml_document == NULL )
1616
0
  {
1617
0
    libcerror_error_set(
1618
0
     error,
1619
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1620
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1621
0
     "%s: invalid binary XML document.",
1622
0
     function );
1623
1624
0
    return( -1 );
1625
0
  }
1626
139k
  if( xml_token == NULL )
1627
0
  {
1628
0
    libcerror_error_set(
1629
0
     error,
1630
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1631
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1632
0
     "%s: invalid binary XML token.",
1633
0
     function );
1634
1635
0
    return( -1 );
1636
0
  }
1637
139k
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG )
1638
11
  {
1639
11
    libcerror_error_set(
1640
11
     error,
1641
11
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1642
11
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1643
11
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1644
11
     function,
1645
11
     xml_token->type );
1646
1647
11
    return( -1 );
1648
11
  }
1649
139k
  if( binary_data == NULL )
1650
0
  {
1651
0
    libcerror_error_set(
1652
0
     error,
1653
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1654
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1655
0
     "%s: invalid binary data.",
1656
0
     function );
1657
1658
0
    return( -1 );
1659
0
  }
1660
139k
  if( binary_data_size > (size_t) SSIZE_MAX )
1661
0
  {
1662
0
    libcerror_error_set(
1663
0
     error,
1664
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1665
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1666
0
     "%s: invalid binary XML document data size value exceeds maximum.",
1667
0
     function );
1668
1669
0
    return( -1 );
1670
0
  }
1671
139k
  if( binary_data_offset >= binary_data_size )
1672
0
  {
1673
0
    libcerror_error_set(
1674
0
     error,
1675
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1676
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1677
0
     "%s: invalid binary data offset value out of bounds.",
1678
0
     function );
1679
1680
0
    return( -1 );
1681
0
  }
1682
139k
  if( ( element_recursion_depth < 0 )
1683
139k
   || ( element_recursion_depth > LIBFWEVT_XML_DOCUMENT_ELEMENT_RECURSION_DEPTH ) )
1684
98
  {
1685
98
    libcerror_error_set(
1686
98
     error,
1687
98
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1688
98
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1689
98
     "%s: invalid element recursion depth value out of bounds.",
1690
98
     function );
1691
1692
98
    return( -1 );
1693
98
  }
1694
139k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) == 0 )
1695
0
  {
1696
0
    additional_value_size = 4;
1697
0
  }
1698
139k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DEPENDENCY_IDENTIFIERS ) == 0 )
1699
58.1k
  {
1700
58.1k
    element_size_offset = 1;
1701
58.1k
  }
1702
81.3k
  else
1703
81.3k
  {
1704
81.3k
    element_size_offset = 3;
1705
81.3k
  }
1706
139k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1707
139k
  xml_document_data_size = binary_data_size - binary_data_offset;
1708
1709
139k
  if( xml_document_data_size < ( element_size_offset + 4 + additional_value_size ) )
1710
33
  {
1711
33
    libcerror_error_set(
1712
33
     error,
1713
33
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1714
33
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1715
33
     "%s: invalid binary XML document data size value too small.",
1716
33
     function );
1717
1718
33
    goto on_error;
1719
33
  }
1720
139k
  if( libfwevt_xml_token_initialize(
1721
139k
       &xml_sub_token,
1722
139k
       error ) != 1 )
1723
0
  {
1724
0
    libcerror_error_set(
1725
0
     error,
1726
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1727
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1728
0
     "%s: unable to create binary XML sub token.",
1729
0
     function );
1730
1731
0
    goto on_error;
1732
0
  }
1733
139k
  do
1734
493k
  {
1735
493k
    if( ( template_value_array_recursion_depth < 0 )
1736
493k
     || ( template_value_array_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_VALUE_ARRAY_RECURSION_DEPTH ) )
1737
66
    {
1738
66
      libcerror_error_set(
1739
66
       error,
1740
66
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1741
66
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1742
66
       "%s: invalid template value array recursion depth value out of bounds.",
1743
66
       function );
1744
1745
66
      goto on_error;
1746
66
    }
1747
493k
    if( libfwevt_xml_tag_initialize(
1748
493k
         &element_xml_tag,
1749
493k
         error ) != 1 )
1750
32
    {
1751
32
      libcerror_error_set(
1752
32
       error,
1753
32
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1754
32
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1755
32
       "%s: unable to create element XML tag.",
1756
32
       function );
1757
1758
32
      goto on_error;
1759
32
    }
1760
#if defined( HAVE_DEBUG_OUTPUT )
1761
    if( libcnotify_verbose != 0 )
1762
    {
1763
      libcnotify_printf(
1764
       "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
1765
       function,
1766
       binary_data_offset );
1767
1768
      libcnotify_printf(
1769
       "%s: element data:\n",
1770
       function );
1771
      libcnotify_print_data(
1772
       xml_document_data,
1773
       element_size_offset + 4 + additional_value_size,
1774
       0 );
1775
    }
1776
#endif
1777
493k
    byte_stream_copy_to_uint32_little_endian(
1778
493k
     &( xml_document_data[ element_size_offset ] ),
1779
493k
     element_size );
1780
1781
#if defined( HAVE_DEBUG_OUTPUT )
1782
    if( libcnotify_verbose != 0 )
1783
    {
1784
      libcnotify_printf(
1785
       "%s: type\t\t\t\t: 0x%02" PRIx8 "\n",
1786
       function,
1787
       xml_document_data[ 0 ] );
1788
1789
      if( element_size_offset == 3 )
1790
      {
1791
        byte_stream_copy_to_uint16_little_endian(
1792
         &( xml_document_data[ 1 ] ),
1793
         value_16bit );
1794
        libcnotify_printf(
1795
         "%s: dependency identifier\t\t: %" PRIi16 " (0x%04" PRIx16 ")\n",
1796
         function,
1797
         (int16_t) value_16bit,
1798
         value_16bit );
1799
      }
1800
      libcnotify_printf(
1801
       "%s: size\t\t\t\t: %" PRIu32 "\n",
1802
       function,
1803
       element_size );
1804
    }
1805
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1806
1807
493k
    xml_document_data_offset = element_size_offset + 4;
1808
1809
    /* The first 5 or 7 bytes are not included in the element size
1810
     */
1811
493k
    if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) == 0 )
1812
0
    {
1813
0
      element_name_offset = (uint32_t) ( binary_data_offset + xml_document_data_offset );
1814
0
    }
1815
493k
    else
1816
493k
    {
1817
493k
      if( xml_document_data_offset >= ( xml_document_data_size - 4 ) )
1818
22
      {
1819
22
        libcerror_error_set(
1820
22
         error,
1821
22
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1822
22
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1823
22
         "%s: invalid binary XML document data size value too small.",
1824
22
         function );
1825
1826
22
        goto on_error;
1827
22
      }
1828
493k
      byte_stream_copy_to_uint32_little_endian(
1829
493k
       &( xml_document_data[ xml_document_data_offset ] ),
1830
493k
       element_name_offset );
1831
1832
#if defined( HAVE_DEBUG_OUTPUT )
1833
      if( libcnotify_verbose != 0 )
1834
      {
1835
        libcnotify_printf(
1836
         "%s: name offset\t\t\t\t: 0x%08" PRIx32 "\n",
1837
         function,
1838
         element_name_offset );
1839
      }
1840
#endif
1841
493k
      xml_document_data_offset += 4;
1842
493k
      element_size             -= 4;
1843
493k
    }
1844
#if defined( HAVE_DEBUG_OUTPUT )
1845
    if( libcnotify_verbose != 0 )
1846
    {
1847
      libcnotify_printf(
1848
       "\n" );
1849
    }
1850
#endif
1851
493k
    if( element_name_offset > ( binary_data_offset + xml_document_data_offset ) )
1852
131
    {
1853
131
      libcerror_error_set(
1854
131
       error,
1855
131
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1856
131
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1857
131
       "%s: invalid element data offset value out of bounds.",
1858
131
       function );
1859
1860
131
      goto on_error;
1861
131
    }
1862
493k
    if( ( binary_data_offset + xml_document_data_offset ) < element_name_offset )
1863
0
    {
1864
0
      trailing_data_size = element_name_offset - ( binary_data_offset + xml_document_data_offset );
1865
1866
#if defined( HAVE_DEBUG_OUTPUT )
1867
      if( libcnotify_verbose != 0 )
1868
      {
1869
        libcnotify_printf(
1870
         "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
1871
         function,
1872
         binary_data_offset + xml_document_data_offset );
1873
1874
        libcnotify_printf(
1875
         "%s: trailing data:\n",
1876
         function );
1877
        libcnotify_print_data(
1878
         &( xml_document_data[ xml_document_data_offset ] ),
1879
         trailing_data_size,
1880
         0 );
1881
      }
1882
#endif
1883
0
      xml_document_data_offset += trailing_data_size;
1884
0
      element_size             -= (uint32_t) trailing_data_size;
1885
0
    }
1886
493k
    if( libfwevt_xml_document_read_name(
1887
493k
         internal_xml_document,
1888
493k
         binary_data,
1889
493k
         binary_data_size,
1890
493k
         element_name_offset,
1891
493k
         flags,
1892
493k
         &element_name_size,
1893
493k
         element_xml_tag,
1894
493k
         error ) != 1 )
1895
48
    {
1896
48
      libcerror_error_set(
1897
48
       error,
1898
48
       LIBCERROR_ERROR_DOMAIN_IO,
1899
48
       LIBCERROR_IO_ERROR_READ_FAILED,
1900
48
       "%s: unable to read element name.",
1901
48
       function );
1902
1903
48
      goto on_error;
1904
48
    }
1905
493k
    if( ( binary_data_offset + xml_document_data_offset ) == element_name_offset )
1906
13.0k
    {
1907
13.0k
      xml_document_data_offset += element_name_size;
1908
13.0k
      element_size             -= element_name_size;
1909
13.0k
    }
1910
493k
    if( ( xml_token->type & LIBFWEVT_XML_TOKEN_FLAG_HAS_MORE_DATA ) != 0 )
1911
58.9k
    {
1912
58.9k
      if( xml_document_data_offset >= ( xml_document_data_size - 4 ) )
1913
12
      {
1914
12
        libcerror_error_set(
1915
12
         error,
1916
12
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1917
12
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1918
12
         "%s: invalid binary XML document data size value too small.",
1919
12
         function );
1920
1921
12
        goto on_error;
1922
12
      }
1923
#if defined( HAVE_DEBUG_OUTPUT )
1924
      if( libcnotify_verbose != 0 )
1925
      {
1926
        libcnotify_printf(
1927
         "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
1928
         function,
1929
         binary_data_offset + xml_document_data_offset );
1930
1931
        libcnotify_printf(
1932
         "%s: attribute list data:\n",
1933
         function );
1934
        libcnotify_print_data(
1935
         &( xml_document_data[ xml_document_data_offset ] ),
1936
         4,
1937
         0 );
1938
      }
1939
#endif
1940
58.9k
      byte_stream_copy_to_uint32_little_endian(
1941
58.9k
       &( xml_document_data[ xml_document_data_offset ] ),
1942
58.9k
       attribute_list_size );
1943
1944
#if defined( HAVE_DEBUG_OUTPUT )
1945
      if( libcnotify_verbose != 0 )
1946
      {
1947
        libcnotify_printf(
1948
         "%s: attribute list size\t\t\t: %" PRIu32 "\n",
1949
         function,
1950
         attribute_list_size );
1951
1952
        libcnotify_printf(
1953
         "\n" );
1954
      }
1955
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1956
1957
58.9k
      xml_document_data_offset += 4;
1958
58.9k
      element_size             -= 4;
1959
1960
58.9k
      if( attribute_list_size > ( binary_data_size - ( binary_data_offset + xml_document_data_offset ) ) )
1961
60
      {
1962
60
        libcerror_error_set(
1963
60
         error,
1964
60
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1965
60
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1966
60
         "%s: invalid attribute list size value out of bounds.",
1967
60
         function );
1968
1969
60
        goto on_error;
1970
60
      }
1971
133k
      while( attribute_list_size > 0 )
1972
78.0k
      {
1973
78.0k
        if( libfwevt_xml_token_read_data(
1974
78.0k
             xml_sub_token,
1975
78.0k
             binary_data,
1976
78.0k
             binary_data_size,
1977
78.0k
             binary_data_offset + xml_document_data_offset,
1978
78.0k
             error ) != 1 )
1979
20
        {
1980
20
          libcerror_error_set(
1981
20
           error,
1982
20
           LIBCERROR_ERROR_DOMAIN_IO,
1983
20
           LIBCERROR_IO_ERROR_READ_FAILED,
1984
20
           "%s: unable to read binary XML sub token.",
1985
20
           function );
1986
1987
20
          goto on_error;
1988
20
        }
1989
77.9k
        if( libfwevt_xml_document_read_attribute(
1990
77.9k
             internal_xml_document,
1991
77.9k
             xml_sub_token,
1992
77.9k
             binary_data,
1993
77.9k
             binary_data_size,
1994
77.9k
             binary_data_offset + xml_document_data_offset,
1995
77.9k
             ascii_codepage,
1996
77.9k
             flags,
1997
77.9k
             template_values_array,
1998
77.9k
             element_xml_tag,
1999
77.9k
             element_recursion_depth,
2000
77.9k
             template_instance_recursion_depth,
2001
77.9k
             error ) != 1 )
2002
3.80k
        {
2003
3.80k
          libcerror_error_set(
2004
3.80k
           error,
2005
3.80k
           LIBCERROR_ERROR_DOMAIN_IO,
2006
3.80k
           LIBCERROR_IO_ERROR_READ_FAILED,
2007
3.80k
           "%s: unable to read attribute.",
2008
3.80k
           function );
2009
2010
3.80k
          goto on_error;
2011
3.80k
        }
2012
74.1k
        xml_document_data_offset += xml_sub_token->size;
2013
74.1k
        element_size             -= (uint32_t) xml_sub_token->size;
2014
2015
74.1k
        if( attribute_list_size < xml_sub_token->size )
2016
60
        {
2017
60
          libcerror_error_set(
2018
60
           error,
2019
60
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2020
60
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2021
60
           "%s: invalid attribute list size value too small.",
2022
60
           function );
2023
2024
60
          goto on_error;
2025
60
        }
2026
74.1k
        attribute_list_size -= (uint32_t) xml_sub_token->size;
2027
74.1k
      }
2028
58.9k
    }
2029
489k
    if( libfwevt_xml_token_read_data(
2030
489k
         xml_sub_token,
2031
489k
         binary_data,
2032
489k
         binary_data_size,
2033
489k
         binary_data_offset + xml_document_data_offset,
2034
489k
         error ) != 1 )
2035
25
    {
2036
25
      libcerror_error_set(
2037
25
       error,
2038
25
       LIBCERROR_ERROR_DOMAIN_IO,
2039
25
       LIBCERROR_IO_ERROR_READ_FAILED,
2040
25
       "%s: unable to read binary XML sub token.",
2041
25
       function );
2042
2043
25
      goto on_error;
2044
25
    }
2045
489k
    if( ( xml_sub_token->type != LIBFWEVT_XML_TOKEN_CLOSE_START_ELEMENT_TAG )
2046
489k
     && ( xml_sub_token->type != LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG ) )
2047
67
    {
2048
67
      libcerror_error_set(
2049
67
       error,
2050
67
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2051
67
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2052
67
       "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
2053
67
       function,
2054
67
       xml_token->type );
2055
2056
67
      goto on_error;
2057
67
    }
2058
489k
    if( xml_document_data_offset >= xml_document_data_size )
2059
0
    {
2060
0
      libcerror_error_set(
2061
0
       error,
2062
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2063
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2064
0
       "%s: invalid binary XML document data size value too small.",
2065
0
       function );
2066
2067
0
      goto on_error;
2068
0
    }
2069
#if defined( HAVE_DEBUG_OUTPUT )
2070
    if( libcnotify_verbose != 0 )
2071
    {
2072
      libcnotify_printf(
2073
       "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
2074
       function,
2075
       binary_data_offset + xml_document_data_offset );
2076
2077
      libcnotify_printf(
2078
       "%s: close element tag data:\n",
2079
       function );
2080
      libcnotify_print_data(
2081
       &( xml_document_data[ xml_document_data_offset ] ),
2082
       1,
2083
       0 );
2084
    }
2085
#endif
2086
#if defined( HAVE_DEBUG_OUTPUT )
2087
    if( libcnotify_verbose != 0 )
2088
    {
2089
      libcnotify_printf(
2090
       "%s: type\t\t\t\t: 0x%02" PRIx8 "\n",
2091
       function,
2092
       xml_document_data[ xml_document_data_offset ] );
2093
2094
      libcnotify_printf(
2095
       "\n" );
2096
    }
2097
#endif
2098
489k
    xml_document_data_offset += 1;
2099
489k
    element_size             -= 1;
2100
2101
489k
    if( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_START_ELEMENT_TAG )
2102
451k
    {
2103
451k
      result = 1;
2104
2105
1.15M
      while( element_size > 0 )
2106
820k
      {
2107
820k
        if( libfwevt_xml_token_read_data(
2108
820k
             xml_sub_token,
2109
820k
             binary_data,
2110
820k
             binary_data_size,
2111
820k
             binary_data_offset + xml_document_data_offset,
2112
820k
             error ) != 1 )
2113
312
        {
2114
312
          libcerror_error_set(
2115
312
           error,
2116
312
           LIBCERROR_ERROR_DOMAIN_IO,
2117
312
           LIBCERROR_IO_ERROR_READ_FAILED,
2118
312
           "%s: unable to read binary XML sub token.",
2119
312
           function );
2120
2121
312
          goto on_error;
2122
312
        }
2123
820k
        switch( xml_sub_token->type & 0xbf )
2124
820k
        {
2125
88.4k
          case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
2126
88.4k
            if( libfwevt_xml_document_read_element(
2127
88.4k
                 internal_xml_document,
2128
88.4k
                 xml_sub_token,
2129
88.4k
                 binary_data,
2130
88.4k
                 binary_data_size,
2131
88.4k
                 binary_data_offset + xml_document_data_offset,
2132
88.4k
                 ascii_codepage,
2133
88.4k
                 flags,
2134
88.4k
                 template_values_array,
2135
88.4k
                 element_xml_tag,
2136
88.4k
                 element_recursion_depth + 1,
2137
88.4k
                 template_instance_recursion_depth,
2138
88.4k
                 error ) != 1 )
2139
10.0k
            {
2140
10.0k
              libcerror_error_set(
2141
10.0k
               error,
2142
10.0k
               LIBCERROR_ERROR_DOMAIN_IO,
2143
10.0k
               LIBCERROR_IO_ERROR_READ_FAILED,
2144
10.0k
               "%s: unable to read element.",
2145
10.0k
               function );
2146
2147
10.0k
              goto on_error;
2148
10.0k
            }
2149
78.3k
            break;
2150
2151
78.3k
          case LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG:
2152
81.1k
          case LIBFWEVT_XML_TOKEN_END_ELEMENT_TAG:
2153
81.1k
            if( xml_document_data_offset >= xml_document_data_size )
2154
0
            {
2155
0
              libcerror_error_set(
2156
0
               error,
2157
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
2158
0
               LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2159
0
               "%s: invalid binary XML document data size value too small.",
2160
0
               function );
2161
2162
0
              goto on_error;
2163
0
            }
2164
#if defined( HAVE_DEBUG_OUTPUT )
2165
            if( libcnotify_verbose != 0 )
2166
            {
2167
              libcnotify_printf(
2168
               "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
2169
               function,
2170
               binary_data_offset + xml_document_data_offset );
2171
2172
              libcnotify_printf(
2173
               "%s: end element tag data:\n",
2174
               function );
2175
              libcnotify_print_data(
2176
               &( xml_document_data[ xml_document_data_offset ] ),
2177
               1,
2178
               0 );
2179
            }
2180
#endif
2181
#if defined( HAVE_DEBUG_OUTPUT )
2182
            if( libcnotify_verbose != 0 )
2183
            {
2184
              libcnotify_printf(
2185
               "%s: type\t\t\t\t: 0x%02" PRIx8 "\n",
2186
               function,
2187
               xml_document_data[ xml_document_data_offset ] );
2188
2189
              libcnotify_printf(
2190
               "\n" );
2191
            }
2192
#endif
2193
81.1k
            xml_sub_token->size = 1;
2194
2195
81.1k
            break;
2196
2197
4.94k
          case LIBFWEVT_XML_TOKEN_CDATA_SECTION:
2198
4.94k
            if( template_value_offset != 0 )
2199
27
            {
2200
27
              libcerror_error_set(
2201
27
               error,
2202
27
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2203
27
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2204
27
               "%s: invalid template value offset value out of bounds.",
2205
27
               function );
2206
2207
27
              goto on_error;
2208
27
            }
2209
4.91k
            if( libfwevt_xml_document_read_cdata_section(
2210
4.91k
                 internal_xml_document,
2211
4.91k
                 xml_sub_token,
2212
4.91k
                 binary_data,
2213
4.91k
                 binary_data_size,
2214
4.91k
                 binary_data_offset + xml_document_data_offset,
2215
4.91k
                 element_xml_tag,
2216
4.91k
                 error ) != 1 )
2217
119
            {
2218
119
              libcerror_error_set(
2219
119
               error,
2220
119
               LIBCERROR_ERROR_DOMAIN_IO,
2221
119
               LIBCERROR_IO_ERROR_READ_FAILED,
2222
119
               "%s: unable to read CDATA section.",
2223
119
               function );
2224
2225
119
              goto on_error;
2226
119
            }
2227
4.79k
            break;
2228
2229
4.79k
          case LIBFWEVT_XML_TOKEN_PI_TARGET:
2230
2.25k
            if( template_value_offset != 0 )
2231
17
            {
2232
17
              libcerror_error_set(
2233
17
               error,
2234
17
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2235
17
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2236
17
               "%s: invalid template value offset value out of bounds.",
2237
17
               function );
2238
2239
17
              goto on_error;
2240
17
            }
2241
2.23k
            if( libfwevt_xml_document_read_pi_target(
2242
2.23k
                 internal_xml_document,
2243
2.23k
                 xml_sub_token,
2244
2.23k
                 binary_data,
2245
2.23k
                 binary_data_size,
2246
2.23k
                 binary_data_offset + xml_document_data_offset,
2247
2.23k
                 flags,
2248
2.23k
                 element_xml_tag,
2249
2.23k
                 error ) != 1 )
2250
355
            {
2251
355
              libcerror_error_set(
2252
355
               error,
2253
355
               LIBCERROR_ERROR_DOMAIN_IO,
2254
355
               LIBCERROR_IO_ERROR_READ_FAILED,
2255
355
               "%s: unable to read PI target.",
2256
355
               function );
2257
2258
355
              goto on_error;
2259
355
            }
2260
1.88k
            break;
2261
2262
1.88k
          case LIBFWEVT_XML_TOKEN_CHARACTER_REFERENCE:
2263
32
            if( template_value_offset != 0 )
2264
28
            {
2265
28
              libcerror_error_set(
2266
28
               error,
2267
28
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2268
28
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2269
28
               "%s: invalid template value offset value out of bounds.",
2270
28
               function );
2271
2272
28
              goto on_error;
2273
28
            }
2274
4
            if( libfwevt_xml_document_read_character_reference(
2275
4
                 internal_xml_document,
2276
4
                 xml_sub_token,
2277
4
                 binary_data,
2278
4
                 binary_data_size,
2279
4
                 binary_data_offset + xml_document_data_offset,
2280
4
                 element_xml_tag,
2281
4
                 error ) != 1 )
2282
4
            {
2283
4
              libcerror_error_set(
2284
4
               error,
2285
4
               LIBCERROR_ERROR_DOMAIN_IO,
2286
4
               LIBCERROR_IO_ERROR_READ_FAILED,
2287
4
               "%s: unable to read character reference.",
2288
4
               function );
2289
2290
4
              goto on_error;
2291
4
            }
2292
0
            break;
2293
2294
78.3k
          case LIBFWEVT_XML_TOKEN_ENTITY_REFERENCE:
2295
78.3k
            if( template_value_offset != 0 )
2296
33
            {
2297
33
              libcerror_error_set(
2298
33
               error,
2299
33
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2300
33
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2301
33
               "%s: invalid template value offset value out of bounds.",
2302
33
               function );
2303
2304
33
              goto on_error;
2305
33
            }
2306
78.2k
            if( libfwevt_xml_document_read_entity_reference(
2307
78.2k
                 internal_xml_document,
2308
78.2k
                 xml_sub_token,
2309
78.2k
                 binary_data,
2310
78.2k
                 binary_data_size,
2311
78.2k
                 binary_data_offset + xml_document_data_offset,
2312
78.2k
                 flags,
2313
78.2k
                 element_xml_tag,
2314
78.2k
                 error ) != 1 )
2315
907
            {
2316
907
              libcerror_error_set(
2317
907
               error,
2318
907
               LIBCERROR_ERROR_DOMAIN_IO,
2319
907
               LIBCERROR_IO_ERROR_READ_FAILED,
2320
907
               "%s: unable to read entity reference.",
2321
907
               function );
2322
2323
907
              goto on_error;
2324
907
            }
2325
77.3k
            break;
2326
2327
112k
          case LIBFWEVT_XML_TOKEN_VALUE:
2328
112k
            if( template_value_offset != 0 )
2329
27
            {
2330
27
              libcerror_error_set(
2331
27
               error,
2332
27
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2333
27
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2334
27
               "%s: invalid template value offset value out of bounds.",
2335
27
               function );
2336
2337
27
              goto on_error;
2338
27
            }
2339
112k
            if( libfwevt_xml_document_read_value(
2340
112k
                 internal_xml_document,
2341
112k
                 xml_sub_token,
2342
112k
                 binary_data,
2343
112k
                 binary_data_size,
2344
112k
                 binary_data_offset + xml_document_data_offset,
2345
112k
                 element_xml_tag,
2346
112k
                 error ) != 1 )
2347
159
            {
2348
159
              libcerror_error_set(
2349
159
               error,
2350
159
               LIBCERROR_ERROR_DOMAIN_IO,
2351
159
               LIBCERROR_IO_ERROR_READ_FAILED,
2352
159
               "%s: unable to read value.",
2353
159
               function );
2354
2355
159
              goto on_error;
2356
159
            }
2357
112k
            break;
2358
2359
112k
          case LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION:
2360
27.5k
            result = libfwevt_xml_document_read_normal_substitution(
2361
27.5k
                internal_xml_document,
2362
27.5k
                xml_sub_token,
2363
27.5k
                binary_data,
2364
27.5k
                binary_data_size,
2365
27.5k
                binary_data_offset + xml_document_data_offset,
2366
27.5k
                ascii_codepage,
2367
27.5k
                flags,
2368
27.5k
                template_values_array,
2369
27.5k
                &template_value_offset,
2370
27.5k
                element_xml_tag,
2371
27.5k
                element_recursion_depth,
2372
27.5k
                template_instance_recursion_depth,
2373
27.5k
                error );
2374
2375
27.5k
            if( result == -1 )
2376
5.09k
            {
2377
5.09k
              libcerror_error_set(
2378
5.09k
               error,
2379
5.09k
               LIBCERROR_ERROR_DOMAIN_IO,
2380
5.09k
               LIBCERROR_IO_ERROR_READ_FAILED,
2381
5.09k
               "%s: unable to read normal substitution.",
2382
5.09k
               function );
2383
2384
5.09k
              goto on_error;
2385
5.09k
            }
2386
22.4k
            break;
2387
2388
425k
          case LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION:
2389
425k
            result = libfwevt_xml_document_read_optional_substitution(
2390
425k
                internal_xml_document,
2391
425k
                xml_sub_token,
2392
425k
                binary_data,
2393
425k
                binary_data_size,
2394
425k
                binary_data_offset + xml_document_data_offset,
2395
425k
                ascii_codepage,
2396
425k
                flags,
2397
425k
                template_values_array,
2398
425k
                &template_value_offset,
2399
425k
                element_xml_tag,
2400
425k
                      element_recursion_depth,
2401
425k
                template_instance_recursion_depth,
2402
425k
                error );
2403
2404
425k
            if( result == -1 )
2405
16.7k
            {
2406
16.7k
              libcerror_error_set(
2407
16.7k
               error,
2408
16.7k
               LIBCERROR_ERROR_DOMAIN_IO,
2409
16.7k
               LIBCERROR_IO_ERROR_READ_FAILED,
2410
16.7k
               "%s: unable to read optional substitution.",
2411
16.7k
               function );
2412
2413
16.7k
              goto on_error;
2414
16.7k
            }
2415
408k
            break;
2416
2417
408k
          default:
2418
148
            libcerror_error_set(
2419
148
             error,
2420
148
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2421
148
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2422
148
             "%s: invalid binary XML sub token - unsupported type: 0x%02" PRIx8 ".",
2423
148
             function,
2424
148
             xml_sub_token->type );
2425
2426
148
            goto on_error;
2427
820k
        }
2428
786k
        xml_document_data_offset += xml_sub_token->size;
2429
2430
786k
        if( element_size < xml_sub_token->size )
2431
44
        {
2432
44
          libcerror_error_set(
2433
44
           error,
2434
44
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2435
44
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2436
44
           "%s: invalid element size value too small.",
2437
44
           function );
2438
2439
44
          goto on_error;
2440
44
        }
2441
786k
        element_size -= (uint32_t) xml_sub_token->size;
2442
2443
786k
        if( ( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG )
2444
786k
         || ( xml_sub_token->type == LIBFWEVT_XML_TOKEN_END_ELEMENT_TAG ) )
2445
81.1k
        {
2446
81.1k
          break;
2447
81.1k
        }
2448
786k
      }
2449
451k
    }
2450
37.4k
    else if( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG )
2451
37.4k
    {
2452
37.4k
      result = 1;
2453
37.4k
    }
2454
455k
    if( element_size > 0 )
2455
197
    {
2456
197
      libcerror_error_set(
2457
197
       error,
2458
197
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2459
197
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2460
197
       "%s: invalid element size value out of bounds.",
2461
197
       function );
2462
2463
197
      goto on_error;
2464
197
    }
2465
454k
    if( result != 0 )
2466
452k
    {
2467
452k
      if( xml_tag != NULL )
2468
451k
      {
2469
451k
        if( libfwevt_xml_tag_append_element(
2470
451k
             xml_tag,
2471
451k
             element_xml_tag,
2472
451k
             error ) != 1 )
2473
0
        {
2474
0
          libcerror_error_set(
2475
0
           error,
2476
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2477
0
           LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2478
0
           "%s: unable to append element to XML tag.",
2479
0
           function );
2480
2481
0
          goto on_error;
2482
0
        }
2483
451k
        element_xml_tag = NULL;
2484
451k
      }
2485
421
      else if( internal_xml_document->root_xml_tag == NULL )
2486
381
      {
2487
381
        internal_xml_document->root_xml_tag = element_xml_tag;
2488
2489
381
        element_xml_tag = NULL;
2490
381
      }
2491
452k
    }
2492
454k
    template_value_array_recursion_depth++;
2493
454k
  }
2494
454k
  while( template_value_offset > 0 );
2495
2496
100k
  xml_token->size = xml_document_data_offset;
2497
2498
100k
  if( element_xml_tag != NULL )
2499
2.60k
  {
2500
2.60k
    if( libfwevt_xml_tag_free(
2501
2.60k
         &element_xml_tag,
2502
2.60k
         error ) != 1 )
2503
0
    {
2504
0
      libcerror_error_set(
2505
0
       error,
2506
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2507
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2508
0
       "%s: unable to free element XML tag.",
2509
0
       function );
2510
2511
0
      goto on_error;
2512
0
    }
2513
2.60k
  }
2514
100k
  if( libfwevt_xml_token_free(
2515
100k
       &xml_sub_token,
2516
100k
       error ) != 1 )
2517
0
  {
2518
0
    libcerror_error_set(
2519
0
     error,
2520
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2521
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2522
0
     "%s: unable to free binary XML sub token.",
2523
0
     function );
2524
2525
0
    goto on_error;
2526
0
  }
2527
100k
  return( 1 );
2528
2529
38.6k
on_error:
2530
38.6k
  if( ( element_xml_tag != NULL )
2531
38.6k
   && ( element_xml_tag != internal_xml_document->root_xml_tag ) )
2532
38.5k
  {
2533
38.5k
    libfwevt_xml_tag_free(
2534
38.5k
     &element_xml_tag,
2535
38.5k
     NULL );
2536
38.5k
  }
2537
38.6k
  if( xml_sub_token != NULL )
2538
38.6k
  {
2539
38.6k
    libfwevt_xml_token_free(
2540
38.6k
     &xml_sub_token,
2541
38.6k
     NULL );
2542
38.6k
  }
2543
38.6k
  return( -1 );
2544
100k
}
2545
2546
/* Reads an entity reference from a binary XML document
2547
 * Returns 1 if successful or -1 on error
2548
 */
2549
int libfwevt_xml_document_read_entity_reference(
2550
     libfwevt_internal_xml_document_t *internal_xml_document,
2551
     libfwevt_xml_token_t *xml_token,
2552
     const uint8_t *binary_data,
2553
     size_t binary_data_size,
2554
     size_t binary_data_offset,
2555
     uint8_t flags,
2556
     libfwevt_xml_tag_t *xml_tag,
2557
     libcerror_error_t **error )
2558
78.2k
{
2559
78.2k
  libfwevt_xml_tag_t *entity_xml_tag = NULL;
2560
78.2k
  uint8_t *entity_name               = NULL;
2561
78.2k
  uint8_t *entity_value_utf16_stream = NULL;
2562
78.2k
  const uint8_t *xml_document_data   = NULL;
2563
78.2k
  static char *function              = "libfwevt_xml_document_read_entity_reference";
2564
78.2k
  size_t additional_value_size       = 0;
2565
78.2k
  size_t trailing_data_size          = 0;
2566
78.2k
  size_t utf8_string_size            = 0;
2567
78.2k
  size_t xml_document_data_offset    = 0;
2568
78.2k
  size_t xml_document_data_size      = 0;
2569
78.2k
  uint32_t entity_name_offset        = 0;
2570
78.2k
  uint32_t entity_name_size          = 0;
2571
78.2k
  uint8_t entity_name_match          = 0;
2572
78.2k
  int value_entry_index              = 0;
2573
2574
78.2k
  if( internal_xml_document == NULL )
2575
0
  {
2576
0
    libcerror_error_set(
2577
0
     error,
2578
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2579
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2580
0
     "%s: invalid binary XML document.",
2581
0
     function );
2582
2583
0
    return( -1 );
2584
0
  }
2585
78.2k
  if( xml_token == NULL )
2586
0
  {
2587
0
    libcerror_error_set(
2588
0
     error,
2589
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2590
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2591
0
     "%s: invalid binary XML token.",
2592
0
     function );
2593
2594
0
    return( -1 );
2595
0
  }
2596
78.2k
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_ENTITY_REFERENCE )
2597
0
  {
2598
0
    libcerror_error_set(
2599
0
     error,
2600
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2601
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2602
0
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
2603
0
     function,
2604
0
     xml_token->type );
2605
2606
0
    return( -1 );
2607
0
  }
2608
78.2k
  if( binary_data == NULL )
2609
0
  {
2610
0
    libcerror_error_set(
2611
0
     error,
2612
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2613
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2614
0
     "%s: invalid binary data.",
2615
0
     function );
2616
2617
0
    return( -1 );
2618
0
  }
2619
78.2k
  if( binary_data_size > (size_t) SSIZE_MAX )
2620
0
  {
2621
0
    libcerror_error_set(
2622
0
     error,
2623
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2624
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2625
0
     "%s: invalid binary XML document data size value exceeds maximum.",
2626
0
     function );
2627
2628
0
    return( -1 );
2629
0
  }
2630
78.2k
  if( binary_data_offset >= binary_data_size )
2631
0
  {
2632
0
    libcerror_error_set(
2633
0
     error,
2634
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2635
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2636
0
     "%s: invalid binary data offset value out of bounds.",
2637
0
     function );
2638
2639
0
    return( -1 );
2640
0
  }
2641
78.2k
  if( xml_tag == NULL )
2642
0
  {
2643
0
    libcerror_error_set(
2644
0
     error,
2645
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2646
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2647
0
     "%s: invalid XML tag.",
2648
0
     function );
2649
2650
0
    return( -1 );
2651
0
  }
2652
78.2k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) == 0 )
2653
0
  {
2654
0
    additional_value_size = 4;
2655
0
  }
2656
78.2k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
2657
78.2k
  xml_document_data_size = binary_data_size - binary_data_offset;
2658
2659
78.2k
  if( xml_document_data_size < ( 1 + additional_value_size ) )
2660
0
  {
2661
0
    libcerror_error_set(
2662
0
     error,
2663
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2664
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2665
0
     "%s: invalid binary XML document data size value too small.",
2666
0
     function );
2667
2668
0
    goto on_error;
2669
0
  }
2670
#if defined( HAVE_DEBUG_OUTPUT )
2671
  if( libcnotify_verbose != 0 )
2672
  {
2673
    libcnotify_printf(
2674
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
2675
     function,
2676
     binary_data_offset );
2677
2678
    libcnotify_printf(
2679
     "%s: entity reference data:\n",
2680
     function );
2681
    libcnotify_print_data(
2682
     xml_document_data,
2683
     1 + additional_value_size,
2684
     0 );
2685
  }
2686
#endif
2687
#if defined( HAVE_DEBUG_OUTPUT )
2688
  if( libcnotify_verbose != 0 )
2689
  {
2690
    libcnotify_printf(
2691
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
2692
     function,
2693
     xml_document_data[ 0 ] );
2694
  }
2695
#endif
2696
78.2k
  xml_token->size          = 1;
2697
78.2k
  xml_document_data_offset = 1;
2698
2699
78.2k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) == 0 )
2700
0
  {
2701
0
    entity_name_offset = (uint32_t) ( binary_data_offset + xml_document_data_offset );
2702
0
  }
2703
78.2k
  else
2704
78.2k
  {
2705
78.2k
    if( ( xml_document_data_size < 4 )
2706
78.2k
     || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
2707
70
    {
2708
70
      libcerror_error_set(
2709
70
       error,
2710
70
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2711
70
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2712
70
       "%s: invalid binary XML document data size value too small.",
2713
70
       function );
2714
2715
70
      goto on_error;
2716
70
    }
2717
78.2k
    byte_stream_copy_to_uint32_little_endian(
2718
78.2k
     &( xml_document_data[ xml_document_data_offset ] ),
2719
78.2k
     entity_name_offset );
2720
2721
#if defined( HAVE_DEBUG_OUTPUT )
2722
    if( libcnotify_verbose != 0 )
2723
    {
2724
      libcnotify_printf(
2725
       "%s: name offset\t\t: 0x%08" PRIx32 "\n",
2726
       function,
2727
       entity_name_offset );
2728
    }
2729
#endif
2730
78.2k
    xml_token->size          += 4;
2731
78.2k
    xml_document_data_offset += 4;
2732
78.2k
  }
2733
#if defined( HAVE_DEBUG_OUTPUT )
2734
  if( libcnotify_verbose != 0 )
2735
  {
2736
    libcnotify_printf(
2737
     "\n" );
2738
  }
2739
#endif
2740
78.2k
  if( entity_name_offset > ( binary_data_offset + xml_document_data_offset ) )
2741
88
  {
2742
88
    libcerror_error_set(
2743
88
     error,
2744
88
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2745
88
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2746
88
     "%s: invalid entity name offset value out of bounds.",
2747
88
     function );
2748
2749
88
    goto on_error;
2750
88
  }
2751
78.1k
  if( ( binary_data_offset + xml_document_data_offset ) < entity_name_offset )
2752
0
  {
2753
0
    trailing_data_size = entity_name_offset - ( binary_data_offset + xml_document_data_offset );
2754
2755
#if defined( HAVE_DEBUG_OUTPUT )
2756
    if( libcnotify_verbose != 0 )
2757
    {
2758
      libcnotify_printf(
2759
       "%s: data offset\t\t: 0x%08" PRIzx "\n",
2760
       function,
2761
       binary_data_offset + xml_document_data_offset );
2762
2763
      libcnotify_printf(
2764
       "%s: trailing data:\n",
2765
       function );
2766
      libcnotify_print_data(
2767
       &( xml_document_data[ xml_document_data_offset ] ),
2768
       trailing_data_size,
2769
       0 );
2770
    }
2771
#endif
2772
0
    xml_token->size          += trailing_data_size;
2773
0
    xml_document_data_offset += trailing_data_size;
2774
0
  }
2775
78.1k
  if( libfwevt_xml_tag_initialize(
2776
78.1k
       &entity_xml_tag,
2777
78.1k
       error ) != 1 )
2778
0
  {
2779
0
    libcerror_error_set(
2780
0
     error,
2781
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2782
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2783
0
     "%s: unable to create entity XML tag.",
2784
0
     function );
2785
2786
0
    goto on_error;
2787
0
  }
2788
78.1k
  if( libfwevt_xml_document_read_name(
2789
78.1k
       internal_xml_document,
2790
78.1k
       binary_data,
2791
78.1k
       binary_data_size,
2792
78.1k
       entity_name_offset,
2793
78.1k
       flags,
2794
78.1k
       &entity_name_size,
2795
78.1k
       entity_xml_tag,
2796
78.1k
       error ) != 1 )
2797
24
  {
2798
24
    libcerror_error_set(
2799
24
     error,
2800
24
     LIBCERROR_ERROR_DOMAIN_IO,
2801
24
     LIBCERROR_IO_ERROR_READ_FAILED,
2802
24
     "%s: unable to read entity name.",
2803
24
     function );
2804
2805
24
    goto on_error;
2806
24
  }
2807
78.0k
  if( ( binary_data_offset + xml_document_data_offset ) == entity_name_offset )
2808
183
  {
2809
183
    xml_token->size += entity_name_size;
2810
183
  }
2811
78.0k
  if( libfwevt_xml_tag_get_utf8_name_size(
2812
78.0k
       entity_xml_tag,
2813
78.0k
       &utf8_string_size,
2814
78.0k
       error ) != 1 )
2815
106
  {
2816
106
    libcerror_error_set(
2817
106
     error,
2818
106
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2819
106
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2820
106
     "%s: unable to retrieve UTF-8 string size of entity name.",
2821
106
     function );
2822
2823
106
    goto on_error;
2824
106
  }
2825
77.9k
  if( ( utf8_string_size == 0 )
2826
77.9k
   || ( utf8_string_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( uint8_t ) ) ) )
2827
0
  {
2828
0
    libcerror_error_set(
2829
0
     error,
2830
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2831
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2832
0
     "%s: invalid UTF-8 string size value out of bounds.",
2833
0
     function );
2834
2835
0
    goto on_error;
2836
0
  }
2837
77.9k
  entity_name = (uint8_t *) memory_allocate(
2838
77.9k
                             sizeof( uint8_t ) * utf8_string_size );
2839
2840
77.9k
  if( entity_name == NULL )
2841
0
  {
2842
0
    libcerror_error_set(
2843
0
     error,
2844
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2845
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
2846
0
     "%s: unable to create entity name.",
2847
0
     function );
2848
2849
0
    goto on_error;
2850
0
  }
2851
77.9k
  if( libfwevt_xml_tag_get_utf8_name(
2852
77.9k
       entity_xml_tag,
2853
77.9k
       entity_name,
2854
77.9k
       utf8_string_size,
2855
77.9k
       error ) != 1 )
2856
0
  {
2857
0
    libcerror_error_set(
2858
0
     error,
2859
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2860
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2861
0
     "%s: unable to copy entity name to UTF-16 string.",
2862
0
     function );
2863
2864
0
    goto on_error;
2865
0
  }
2866
77.9k
  if( libfwevt_xml_tag_set_value_type(
2867
77.9k
       xml_tag,
2868
77.9k
       LIBFVALUE_VALUE_TYPE_STRING_UTF16,
2869
77.9k
       error ) != 1 )
2870
2
  {
2871
2
    libcerror_error_set(
2872
2
     error,
2873
2
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2874
2
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2875
2
     "%s: unable to set value type.",
2876
2
     function );
2877
2878
2
    goto on_error;
2879
2
  }
2880
  /* Make sure the character value data is in UTF-16 litte-endian
2881
   */
2882
77.9k
  entity_value_utf16_stream = (uint8_t *) memory_allocate(
2883
77.9k
                                           sizeof( uint8_t ) * 4 );
2884
2885
77.9k
  if( entity_value_utf16_stream == NULL )
2886
0
  {
2887
0
    libcerror_error_set(
2888
0
     error,
2889
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2890
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
2891
0
     "%s: unable to create entity value UTF-16 stream.",
2892
0
     function );
2893
2894
0
    goto on_error;
2895
0
  }
2896
77.9k
  if( utf8_string_size == 3 )
2897
76.4k
  {
2898
76.4k
    if( ( entity_name[ 0 ] == (uint8_t) 'g' )
2899
76.4k
     && ( entity_name[ 1 ] == (uint8_t) 't' ) )
2900
75.4k
    {
2901
75.4k
      entity_value_utf16_stream[ 0 ] = (uint8_t) '>';
2902
75.4k
      entity_value_utf16_stream[ 1 ] = 0;
2903
2904
75.4k
      entity_name_match = 1;
2905
75.4k
    }
2906
1.06k
    else if( ( entity_name[ 0 ] == (uint8_t) 'l' )
2907
1.06k
          && ( entity_name[ 1 ] == (uint8_t) 't' ) )
2908
980
    {
2909
980
      entity_value_utf16_stream[ 0 ] = (uint8_t) '<';
2910
980
      entity_value_utf16_stream[ 1 ] = 0;
2911
2912
980
      entity_name_match = 1;
2913
980
    }
2914
76.4k
  }
2915
1.51k
  else if( utf8_string_size == 4 )
2916
278
  {
2917
278
    if( ( entity_name[ 0 ] == (uint8_t) 'a' )
2918
278
     && ( entity_name[ 1 ] == (uint8_t) 'm' )
2919
278
     && ( entity_name[ 2 ] == (uint8_t) 'p' ) )
2920
227
    {
2921
227
      entity_value_utf16_stream[ 0 ] = (uint8_t) '&';
2922
227
      entity_value_utf16_stream[ 1 ] = 0;
2923
2924
227
      entity_name_match = 1;
2925
227
    }
2926
278
  }
2927
1.23k
  else if( utf8_string_size == 5 )
2928
893
  {
2929
893
    if( ( entity_name[ 0 ] == (uint8_t) 'a' )
2930
893
     && ( entity_name[ 1 ] == (uint8_t) 'p' )
2931
893
     && ( entity_name[ 2 ] == (uint8_t) 'o' )
2932
893
     && ( entity_name[ 3 ] == (uint8_t) 's' ) )
2933
304
    {
2934
304
      entity_value_utf16_stream[ 0 ] = (uint8_t) '\'';
2935
304
      entity_value_utf16_stream[ 1 ] = 0;
2936
2937
304
      entity_name_match = 1;
2938
304
    }
2939
589
    else if( ( entity_name[ 0 ] == (uint8_t) 'q' )
2940
589
          && ( entity_name[ 1 ] == (uint8_t) 'u' )
2941
589
          && ( entity_name[ 2 ] == (uint8_t) 'o' )
2942
589
          && ( entity_name[ 3 ] == (uint8_t) 't' ) )
2943
451
    {
2944
451
      entity_value_utf16_stream[ 0 ] = (uint8_t) '"';
2945
451
      entity_value_utf16_stream[ 1 ] = 0;
2946
2947
451
      entity_name_match = 1;
2948
451
    }
2949
893
  }
2950
77.9k
  if( entity_name_match == 0 )
2951
616
  {
2952
616
    libcerror_error_set(
2953
616
     error,
2954
616
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2955
616
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2956
616
     "%s: unsupported entity name: %s\n",
2957
616
     function,
2958
616
     entity_name );
2959
2960
616
    goto on_error;
2961
616
  }
2962
77.3k
  entity_value_utf16_stream[ 2 ] = 0;
2963
77.3k
  entity_value_utf16_stream[ 3 ] = 0;
2964
2965
77.3k
  memory_free(
2966
77.3k
   entity_name );
2967
2968
77.3k
  entity_name = NULL;
2969
2970
77.3k
  if( libfwevt_xml_tag_append_value_data(
2971
77.3k
       xml_tag,
2972
77.3k
       entity_value_utf16_stream,
2973
77.3k
       4,
2974
77.3k
       LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN,
2975
77.3k
       &value_entry_index,
2976
77.3k
       error ) != 1 )
2977
1
  {
2978
1
    libcerror_error_set(
2979
1
     error,
2980
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2981
1
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2982
1
     "%s: unable to append value data.",
2983
1
     function );
2984
2985
1
    goto on_error;
2986
1
  }
2987
77.3k
  memory_free(
2988
77.3k
   entity_value_utf16_stream );
2989
2990
77.3k
  entity_value_utf16_stream = NULL;
2991
2992
#if defined( HAVE_DEBUG_OUTPUT )
2993
  if( libcnotify_verbose != 0 )
2994
  {
2995
    if( libfwevt_xml_tag_value_debug_print(
2996
         xml_tag,
2997
         value_entry_index,
2998
         error ) != 1 )
2999
    {
3000
      libcerror_error_set(
3001
       error,
3002
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3003
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
3004
       "%s: unable to print value: %d.",
3005
       function,
3006
       value_entry_index );
3007
3008
      goto on_error;
3009
    }
3010
  }
3011
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3012
3013
77.3k
  if( libfwevt_xml_tag_free(
3014
77.3k
       &entity_xml_tag,
3015
77.3k
       error ) != 1 )
3016
0
  {
3017
0
    libcerror_error_set(
3018
0
     error,
3019
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3020
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3021
0
     "%s: unable to free entity XML tag.",
3022
0
     function );
3023
3024
0
    goto on_error;
3025
0
  }
3026
77.3k
  return( 1 );
3027
3028
907
on_error:
3029
907
  if( entity_value_utf16_stream != NULL )
3030
617
  {
3031
617
    memory_free(
3032
617
     entity_value_utf16_stream );
3033
617
  }
3034
907
  if( entity_name != NULL )
3035
618
  {
3036
618
    memory_free(
3037
618
     entity_name );
3038
618
  }
3039
907
  if( entity_xml_tag != NULL )
3040
749
  {
3041
749
    libfwevt_xml_tag_free(
3042
749
     &entity_xml_tag,
3043
749
     NULL );
3044
749
  }
3045
907
  return( -1 );
3046
77.3k
}
3047
3048
/* Reads a fragment from a binary XML document
3049
 * Returns 1 if successful or -1 on error
3050
 */
3051
int libfwevt_xml_document_read_fragment(
3052
     libfwevt_internal_xml_document_t *internal_xml_document,
3053
     libfwevt_xml_token_t *xml_token,
3054
     const uint8_t *binary_data,
3055
     size_t binary_data_size,
3056
     size_t binary_data_offset,
3057
     int ascii_codepage,
3058
     uint8_t flags,
3059
     libcdata_array_t *template_values_array,
3060
     libfwevt_xml_tag_t *xml_tag,
3061
     int element_recursion_depth,
3062
     int template_instance_recursion_depth,
3063
     libcerror_error_t **error )
3064
23.2k
{
3065
23.2k
  libfwevt_xml_token_t *xml_sub_token = NULL;
3066
23.2k
  static char *function               = "libfwevt_xml_document_read_fragment";
3067
3068
23.2k
  if( internal_xml_document == NULL )
3069
0
  {
3070
0
    libcerror_error_set(
3071
0
     error,
3072
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3073
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3074
0
     "%s: invalid binary XML document.",
3075
0
     function );
3076
3077
0
    return( -1 );
3078
0
  }
3079
23.2k
  if( xml_token == NULL )
3080
0
  {
3081
0
    libcerror_error_set(
3082
0
     error,
3083
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3084
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3085
0
     "%s: invalid binary XML token.",
3086
0
     function );
3087
3088
0
    return( -1 );
3089
0
  }
3090
23.2k
  if( libfwevt_xml_document_read_fragment_header(
3091
23.2k
       internal_xml_document,
3092
23.2k
       xml_token,
3093
23.2k
       binary_data,
3094
23.2k
       binary_data_size,
3095
23.2k
       binary_data_offset,
3096
23.2k
       error ) != 1 )
3097
16
  {
3098
16
    libcerror_error_set(
3099
16
     error,
3100
16
     LIBCERROR_ERROR_DOMAIN_IO,
3101
16
     LIBCERROR_IO_ERROR_READ_FAILED,
3102
16
     "%s: unable to read fragment header.",
3103
16
     function );
3104
3105
16
    goto on_error;
3106
16
  }
3107
23.2k
  binary_data_offset += xml_token->size;
3108
3109
23.2k
  if( libfwevt_xml_token_initialize(
3110
23.2k
       &xml_sub_token,
3111
23.2k
       error ) != 1 )
3112
0
  {
3113
0
    libcerror_error_set(
3114
0
     error,
3115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3116
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3117
0
     "%s: unable to create binary XML sub token.",
3118
0
     function );
3119
3120
0
    goto on_error;
3121
0
  }
3122
23.2k
  if( libfwevt_xml_token_read_data(
3123
23.2k
       xml_sub_token,
3124
23.2k
       binary_data,
3125
23.2k
       binary_data_size,
3126
23.2k
       binary_data_offset,
3127
23.2k
       error ) != 1 )
3128
9
  {
3129
9
    libcerror_error_set(
3130
9
     error,
3131
9
     LIBCERROR_ERROR_DOMAIN_IO,
3132
9
     LIBCERROR_IO_ERROR_READ_FAILED,
3133
9
     "%s: unable to read binary XML sub token.",
3134
9
     function );
3135
3136
9
    goto on_error;
3137
9
  }
3138
23.2k
  switch( xml_sub_token->type & 0xbf )
3139
23.2k
  {
3140
2.71k
    case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
3141
2.71k
      if( libfwevt_xml_document_read_element(
3142
2.71k
           internal_xml_document,
3143
2.71k
           xml_sub_token,
3144
2.71k
           binary_data,
3145
2.71k
           binary_data_size,
3146
2.71k
           binary_data_offset,
3147
2.71k
           ascii_codepage,
3148
2.71k
           flags,
3149
2.71k
           template_values_array,
3150
2.71k
           xml_tag,
3151
2.71k
           element_recursion_depth + 1,
3152
2.71k
           template_instance_recursion_depth,
3153
2.71k
           error ) != 1 )
3154
2.00k
      {
3155
2.00k
        libcerror_error_set(
3156
2.00k
         error,
3157
2.00k
         LIBCERROR_ERROR_DOMAIN_IO,
3158
2.00k
         LIBCERROR_IO_ERROR_READ_FAILED,
3159
2.00k
         "%s: unable to read element.",
3160
2.00k
         function );
3161
3162
2.00k
        goto on_error;
3163
2.00k
      }
3164
718
      break;
3165
3166
20.5k
    case LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE:
3167
20.5k
      if( libfwevt_xml_document_read_template_instance(
3168
20.5k
           internal_xml_document,
3169
20.5k
           xml_sub_token,
3170
20.5k
           binary_data,
3171
20.5k
           binary_data_size,
3172
20.5k
           binary_data_offset,
3173
20.5k
           ascii_codepage,
3174
20.5k
           flags,
3175
20.5k
           xml_tag,
3176
20.5k
           element_recursion_depth,
3177
20.5k
           template_instance_recursion_depth + 1,
3178
20.5k
           error ) != 1 )
3179
6.20k
      {
3180
6.20k
        libcerror_error_set(
3181
6.20k
         error,
3182
6.20k
         LIBCERROR_ERROR_DOMAIN_IO,
3183
6.20k
         LIBCERROR_IO_ERROR_READ_FAILED,
3184
6.20k
         "%s: unable to read document template instance.",
3185
6.20k
         function );
3186
3187
6.20k
        goto on_error;
3188
6.20k
      }
3189
14.3k
      break;
3190
3191
14.3k
    default:
3192
11
      libcerror_error_set(
3193
11
       error,
3194
11
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3195
11
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3196
11
       "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3197
11
       function,
3198
11
       xml_sub_token->type );
3199
3200
11
      goto on_error;
3201
23.2k
  }
3202
15.0k
  xml_token->size += xml_sub_token->size;
3203
3204
15.0k
  if( libfwevt_xml_token_free(
3205
15.0k
       &xml_sub_token,
3206
15.0k
       error ) != 1 )
3207
0
  {
3208
0
    libcerror_error_set(
3209
0
     error,
3210
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3211
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3212
0
     "%s: unable to free binary XML sub token.",
3213
0
     function );
3214
3215
0
    goto on_error;
3216
0
  }
3217
15.0k
  return( 1 );
3218
3219
8.24k
on_error:
3220
8.24k
  if( xml_sub_token != NULL )
3221
8.22k
  {
3222
8.22k
    libfwevt_xml_token_free(
3223
8.22k
     &xml_sub_token,
3224
8.22k
     NULL );
3225
8.22k
  }
3226
8.24k
  return( -1 );
3227
15.0k
}
3228
3229
/* Reads a fragment header from a binary XML document
3230
 * Returns 1 if successful or -1 on error
3231
 */
3232
int libfwevt_xml_document_read_fragment_header(
3233
     libfwevt_internal_xml_document_t *internal_xml_document,
3234
     libfwevt_xml_token_t *xml_token,
3235
     const uint8_t *binary_data,
3236
     size_t binary_data_size,
3237
     size_t binary_data_offset,
3238
     libcerror_error_t **error )
3239
44.6k
{
3240
44.6k
  static char *function            = "libfwevt_xml_document_read_fragment_header";
3241
44.6k
  size_t xml_document_data_size    = 0;
3242
3243
#if defined( HAVE_DEBUG_OUTPUT )
3244
  const uint8_t *xml_document_data = NULL;
3245
#endif
3246
3247
44.6k
  if( internal_xml_document == NULL )
3248
0
  {
3249
0
    libcerror_error_set(
3250
0
     error,
3251
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3252
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3253
0
     "%s: invalid binary XML document.",
3254
0
     function );
3255
3256
0
    return( -1 );
3257
0
  }
3258
44.6k
  if( xml_token == NULL )
3259
0
  {
3260
0
    libcerror_error_set(
3261
0
     error,
3262
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3263
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3264
0
     "%s: invalid binary XML token.",
3265
0
     function );
3266
3267
0
    return( -1 );
3268
0
  }
3269
44.6k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER )
3270
88
  {
3271
88
    libcerror_error_set(
3272
88
     error,
3273
88
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3274
88
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3275
88
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3276
88
     function,
3277
88
     xml_token->type );
3278
3279
88
    return( -1 );
3280
88
  }
3281
44.5k
  if( binary_data == NULL )
3282
0
  {
3283
0
    libcerror_error_set(
3284
0
     error,
3285
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3286
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3287
0
     "%s: invalid binary data.",
3288
0
     function );
3289
3290
0
    return( -1 );
3291
0
  }
3292
44.5k
  if( binary_data_size > (size_t) SSIZE_MAX )
3293
0
  {
3294
0
    libcerror_error_set(
3295
0
     error,
3296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3297
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3298
0
     "%s: invalid binary XML document data size value exceeds maximum.",
3299
0
     function );
3300
3301
0
    return( -1 );
3302
0
  }
3303
44.5k
  if( binary_data_offset >= binary_data_size )
3304
0
  {
3305
0
    libcerror_error_set(
3306
0
     error,
3307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3308
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3309
0
     "%s: invalid binary data offset value out of bounds.",
3310
0
     function );
3311
3312
0
    return( -1 );
3313
0
  }
3314
#if defined( HAVE_DEBUG_OUTPUT )
3315
  xml_document_data = &( binary_data[ binary_data_offset ] );
3316
#endif
3317
3318
44.5k
  xml_document_data_size = binary_data_size - binary_data_offset;
3319
3320
44.5k
  if( xml_document_data_size < 4 )
3321
16
  {
3322
16
    libcerror_error_set(
3323
16
     error,
3324
16
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3325
16
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3326
16
     "%s: invalid binary XML document data size value too small.",
3327
16
     function );
3328
3329
16
    return( -1 );
3330
16
  }
3331
#if defined( HAVE_DEBUG_OUTPUT )
3332
  if( libcnotify_verbose != 0 )
3333
  {
3334
    libcnotify_printf(
3335
     "%s: data offset\t\t\t: 0x%08" PRIzx "\n",
3336
     function,
3337
     binary_data_offset );
3338
3339
    libcnotify_printf(
3340
     "%s: fragment header data:\n",
3341
     function );
3342
    libcnotify_print_data(
3343
     xml_document_data,
3344
     4,
3345
     0 );
3346
  }
3347
#endif
3348
#if defined( HAVE_DEBUG_OUTPUT )
3349
  if( libcnotify_verbose != 0 )
3350
  {
3351
    libcnotify_printf(
3352
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
3353
     function,
3354
     xml_document_data[ 0 ] );
3355
3356
    libcnotify_printf(
3357
     "%s: major version\t\t: %" PRIu8 "\n",
3358
     function,
3359
     xml_document_data[ 1 ] );
3360
3361
    libcnotify_printf(
3362
     "%s: minor version\t\t: %" PRIu8 "\n",
3363
     function,
3364
     xml_document_data[ 2 ] );
3365
3366
    libcnotify_printf(
3367
     "%s: flags\t\t\t: 0x%02" PRIx8 "\n",
3368
     function,
3369
     xml_document_data[ 3 ] );
3370
3371
    libcnotify_printf(
3372
     "\n" );
3373
  }
3374
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3375
3376
/* TODO check values */
3377
44.5k
  xml_token->size = 4;
3378
  
3379
44.5k
  return( 1 );
3380
44.5k
}
3381
3382
/* Reads a name from a binary XML document
3383
 * Returns 1 if successful or -1 on error
3384
 */
3385
int libfwevt_xml_document_read_name(
3386
     libfwevt_internal_xml_document_t *internal_xml_document,
3387
     const uint8_t *binary_data,
3388
     size_t binary_data_size,
3389
     size_t binary_data_offset,
3390
     uint8_t flags,
3391
     uint32_t *name_data_size,
3392
     libfwevt_xml_tag_t *xml_tag,
3393
     libcerror_error_t **error )
3394
653k
{
3395
653k
  const uint8_t *xml_document_data = NULL;
3396
653k
  static char *function            = "libfwevt_xml_document_read_name";
3397
653k
  size_t additional_value_size     = 0;
3398
653k
  size_t xml_document_data_offset  = 0;
3399
653k
  size_t xml_document_data_size    = 0;
3400
653k
  uint32_t name_size               = 0;
3401
3402
#if defined( HAVE_DEBUG_OUTPUT )
3403
  uint32_t value_32bit             = 0;
3404
  uint16_t value_16bit             = 0;
3405
#endif
3406
3407
653k
  if( internal_xml_document == NULL )
3408
0
  {
3409
0
    libcerror_error_set(
3410
0
     error,
3411
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3412
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3413
0
     "%s: invalid binary XML document.",
3414
0
     function );
3415
3416
0
    return( -1 );
3417
0
  }
3418
653k
  if( binary_data == NULL )
3419
0
  {
3420
0
    libcerror_error_set(
3421
0
     error,
3422
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3423
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3424
0
     "%s: invalid binary data.",
3425
0
     function );
3426
3427
0
    return( -1 );
3428
0
  }
3429
653k
  if( ( binary_data_size < 4 )
3430
653k
   || ( binary_data_size > (size_t) SSIZE_MAX ) )
3431
0
  {
3432
0
    libcerror_error_set(
3433
0
     error,
3434
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3435
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3436
0
     "%s: invalid binary XML document data size value out of bounds.",
3437
0
     function );
3438
3439
0
    return( -1 );
3440
0
  }
3441
653k
  if( binary_data_offset >= binary_data_size )
3442
0
  {
3443
0
    libcerror_error_set(
3444
0
     error,
3445
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3446
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3447
0
     "%s: invalid binary data offset value out of bounds.",
3448
0
     function );
3449
3450
0
    return( -1 );
3451
0
  }
3452
653k
  if( name_data_size == NULL )
3453
0
  {
3454
0
    libcerror_error_set(
3455
0
     error,
3456
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3457
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3458
0
     "%s: invalid name data size.",
3459
0
     function );
3460
3461
0
    return( -1 );
3462
0
  }
3463
653k
  if( xml_tag == NULL )
3464
0
  {
3465
0
    libcerror_error_set(
3466
0
     error,
3467
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3468
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3469
0
     "%s: invalid XML tag.",
3470
0
     function );
3471
3472
0
    return( -1 );
3473
0
  }
3474
653k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3475
653k
  xml_document_data_size = binary_data_size - binary_data_offset;
3476
3477
653k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
3478
653k
  {
3479
653k
    additional_value_size += 4;
3480
653k
  }
3481
653k
  if( ( additional_value_size + 4 ) > xml_document_data_size )
3482
13
  {
3483
13
    libcerror_error_set(
3484
13
     error,
3485
13
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3486
13
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3487
13
     "%s: invalid binary XML document data size value too small.",
3488
13
     function );
3489
3490
13
    return( -1 );
3491
13
  }
3492
#if defined( HAVE_DEBUG_OUTPUT )
3493
  if( libcnotify_verbose != 0 )
3494
  {
3495
    libcnotify_printf(
3496
     "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
3497
     function,
3498
     binary_data_offset );
3499
3500
    libcnotify_printf(
3501
     "%s: name header data:\n",
3502
     function );
3503
    libcnotify_print_data(
3504
     xml_document_data,
3505
     additional_value_size + 4,
3506
     0 );
3507
  }
3508
#endif
3509
653k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
3510
653k
  {
3511
/* TODO determine if this used */
3512
#if defined( HAVE_DEBUG_OUTPUT )
3513
    if( libcnotify_verbose != 0 )
3514
    {
3515
      byte_stream_copy_to_uint32_little_endian(
3516
       xml_document_data,
3517
       value_32bit );
3518
      libcnotify_printf(
3519
       "%s: name unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
3520
       function,
3521
       value_32bit );
3522
    }
3523
#endif
3524
653k
    xml_document_data_offset += 4;
3525
653k
  }
3526
653k
  byte_stream_copy_to_uint16_little_endian(
3527
653k
   &( xml_document_data[ xml_document_data_offset + 2 ] ),
3528
653k
   name_size );
3529
3530
#if defined( HAVE_DEBUG_OUTPUT )
3531
  if( libcnotify_verbose != 0 )
3532
  {
3533
    byte_stream_copy_to_uint16_little_endian(
3534
     &( xml_document_data[ xml_document_data_offset ] ),
3535
     value_16bit );
3536
    libcnotify_printf(
3537
     "%s: name hash\t\t\t\t: 0x%04" PRIx16 "\n",
3538
     function,
3539
     value_16bit );
3540
3541
    libcnotify_printf(
3542
     "%s: name number of characters\t\t: %" PRIu16 "\n",
3543
     function,
3544
     name_size );
3545
  }
3546
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3547
3548
653k
  xml_document_data_offset += 4;
3549
3550
653k
  if( ( name_size == 0 )
3551
653k
   || ( (size_t) name_size > ( ( MEMORY_MAXIMUM_ALLOCATION_SIZE - 1 ) / 2 ) ) )
3552
26
  {
3553
26
    libcerror_error_set(
3554
26
     error,
3555
26
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3556
26
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3557
26
     "%s: invalid name size value out of bounds.",
3558
26
     function );
3559
3560
26
    return( -1 );
3561
26
  }
3562
653k
  name_size = ( name_size + 1 ) * 2;
3563
3564
653k
  if( (size_t) name_size > ( xml_document_data_size - xml_document_data_offset ) )
3565
54
  {
3566
54
    libcerror_error_set(
3567
54
     error,
3568
54
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3569
54
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3570
54
     "%s: invalid binary XML document data size value too small.",
3571
54
     function );
3572
3573
54
    return( -1 );
3574
54
  }
3575
#if defined( HAVE_DEBUG_OUTPUT )
3576
  if( libcnotify_verbose != 0 )
3577
  {
3578
    libcnotify_printf(
3579
     "%s: name data:\n",
3580
     function );
3581
    libcnotify_print_data(
3582
     &( xml_document_data[ xml_document_data_offset ] ),
3583
     name_size,
3584
     0 );
3585
  }
3586
#endif
3587
653k
  if( libfwevt_xml_tag_set_name_data(
3588
653k
       xml_tag,
3589
653k
       &( xml_document_data[ xml_document_data_offset ] ),
3590
653k
       name_size,
3591
653k
       LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN,
3592
653k
       error ) != 1 )
3593
0
  {
3594
0
    libcerror_error_set(
3595
0
     error,
3596
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3597
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3598
0
     "%s: unable to set name data.",
3599
0
     function );
3600
3601
0
    return( -1 );
3602
0
  }
3603
#if defined( HAVE_DEBUG_OUTPUT )
3604
  if( libcnotify_verbose != 0 )
3605
  {
3606
    if( libfwevt_xml_tag_name_debug_print(
3607
         xml_tag,
3608
         error ) != 1 )
3609
    {
3610
      libcerror_error_set(
3611
       error,
3612
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3613
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
3614
       "%s: unable to print name.",
3615
       function );
3616
3617
      return( -1 );
3618
    }
3619
  }
3620
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3621
3622
653k
  *name_data_size = (uint32_t) ( xml_document_data_offset + name_size );
3623
3624
653k
  return( 1 );
3625
653k
}
3626
3627
/* Reads a normal substitution from a binary XML document
3628
 * Returns 1 if successful or -1 on error
3629
 */
3630
int libfwevt_xml_document_read_normal_substitution(
3631
     libfwevt_internal_xml_document_t *internal_xml_document,
3632
     libfwevt_xml_token_t *xml_token,
3633
     const uint8_t *binary_data,
3634
     size_t binary_data_size,
3635
     size_t binary_data_offset,
3636
     int ascii_codepage,
3637
     uint8_t flags,
3638
     libcdata_array_t *template_values_array,
3639
     size_t *template_value_offset,
3640
     libfwevt_xml_tag_t *xml_tag,
3641
     int element_recursion_depth,
3642
     int template_instance_recursion_depth,
3643
     libcerror_error_t **error )
3644
34.1k
{
3645
34.1k
  const uint8_t *xml_document_data = NULL;
3646
34.1k
  static char *function            = "libfwevt_xml_document_read_normal_substitution";
3647
34.1k
  size_t xml_document_data_size    = 0;
3648
34.1k
  uint16_t template_value_index    = 0;
3649
34.1k
  uint8_t template_value_type      = 0;
3650
34.1k
  int result                       = 0;
3651
3652
34.1k
  if( internal_xml_document == NULL )
3653
0
  {
3654
0
    libcerror_error_set(
3655
0
     error,
3656
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3657
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3658
0
     "%s: invalid binary XML document.",
3659
0
     function );
3660
3661
0
    return( -1 );
3662
0
  }
3663
34.1k
  if( xml_token == NULL )
3664
0
  {
3665
0
    libcerror_error_set(
3666
0
     error,
3667
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3668
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3669
0
     "%s: invalid binary XML token.",
3670
0
     function );
3671
3672
0
    return( -1 );
3673
0
  }
3674
34.1k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION )
3675
0
  {
3676
0
    libcerror_error_set(
3677
0
     error,
3678
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3679
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3680
0
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3681
0
     function,
3682
0
     xml_token->type );
3683
3684
0
    return( -1 );
3685
0
  }
3686
34.1k
  if( binary_data == NULL )
3687
0
  {
3688
0
    libcerror_error_set(
3689
0
     error,
3690
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3691
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3692
0
     "%s: invalid binary data.",
3693
0
     function );
3694
3695
0
    return( -1 );
3696
0
  }
3697
34.1k
  if( binary_data_size > (size_t) SSIZE_MAX )
3698
0
  {
3699
0
    libcerror_error_set(
3700
0
     error,
3701
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3702
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3703
0
     "%s: invalid binary XML document data size value exceeds maximum.",
3704
0
     function );
3705
3706
0
    return( -1 );
3707
0
  }
3708
34.1k
  if( binary_data_offset >= binary_data_size )
3709
0
  {
3710
0
    libcerror_error_set(
3711
0
     error,
3712
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3713
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3714
0
     "%s: invalid binary data offset value out of bounds.",
3715
0
     function );
3716
3717
0
    return( -1 );
3718
0
  }
3719
34.1k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3720
34.1k
  xml_document_data_size = binary_data_size - binary_data_offset;
3721
3722
34.1k
  if( xml_document_data_size < 4 )
3723
16
  {
3724
16
    libcerror_error_set(
3725
16
     error,
3726
16
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3727
16
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3728
16
     "%s: invalid binary XML document data size value too small.",
3729
16
     function );
3730
3731
16
    return( -1 );
3732
16
  }
3733
#if defined( HAVE_DEBUG_OUTPUT )
3734
  if( libcnotify_verbose != 0 )
3735
  {
3736
    libcnotify_printf(
3737
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
3738
     function,
3739
     binary_data_offset );
3740
3741
    libcnotify_printf(
3742
     "%s: normal substitution data:\n",
3743
     function );
3744
    libcnotify_print_data(
3745
     xml_document_data,
3746
     4,
3747
     0 );
3748
  }
3749
#endif
3750
34.1k
  byte_stream_copy_to_uint16_little_endian(
3751
34.1k
   &( xml_document_data[ 1 ] ),
3752
34.1k
   template_value_index );
3753
3754
34.1k
  template_value_type = xml_document_data[ 3 ];
3755
3756
#if defined( HAVE_DEBUG_OUTPUT )
3757
  if( libcnotify_verbose != 0 )
3758
  {
3759
    libcnotify_printf(
3760
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
3761
     function,
3762
     xml_document_data[ 0 ] );
3763
3764
    libcnotify_printf(
3765
     "%s: identifier\t\t: %" PRIu16 "\n",
3766
     function,
3767
     template_value_index );
3768
3769
    libcnotify_printf(
3770
     "%s: value type\t\t: 0x%02" PRIx8 " (",
3771
     function,
3772
     template_value_type );
3773
    libfwevt_debug_print_value_type(
3774
     template_value_type );
3775
    libcnotify_printf(
3776
     ")\n" );
3777
3778
    libcnotify_printf(
3779
     "\n" );
3780
  }
3781
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3782
3783
34.1k
  xml_token->size = 4;
3784
3785
34.1k
  result = libfwevt_xml_document_substitute_template_value(
3786
34.1k
            internal_xml_document,
3787
34.1k
            binary_data,
3788
34.1k
            binary_data_size,
3789
34.1k
            ascii_codepage,
3790
34.1k
            flags,
3791
34.1k
            template_values_array,
3792
34.1k
            template_value_index,
3793
34.1k
            template_value_type,
3794
34.1k
            template_value_offset,
3795
34.1k
            xml_tag,
3796
34.1k
            element_recursion_depth,
3797
34.1k
            template_instance_recursion_depth,
3798
34.1k
            error );
3799
3800
34.1k
  if( result != 1 )
3801
7.14k
  {
3802
7.14k
    libcerror_error_set(
3803
7.14k
     error,
3804
7.14k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3805
7.14k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3806
7.14k
     "%s: unable to substitute template value.",
3807
7.14k
     function );
3808
3809
7.14k
    return( -1 );
3810
7.14k
  }
3811
27.0k
  return( 1 );
3812
34.1k
}
3813
3814
/* Reads an optional substitution from a binary XML document
3815
 * Returns 1 if successful, 0 if no substitution or -1 on error
3816
 */
3817
int libfwevt_xml_document_read_optional_substitution(
3818
     libfwevt_internal_xml_document_t *internal_xml_document,
3819
     libfwevt_xml_token_t *xml_token,
3820
     const uint8_t *binary_data,
3821
     size_t binary_data_size,
3822
     size_t binary_data_offset,
3823
     int ascii_codepage,
3824
     uint8_t flags,
3825
     libcdata_array_t *template_values_array,
3826
     size_t *template_value_offset,
3827
     libfwevt_xml_tag_t *xml_tag,
3828
     int element_recursion_depth,
3829
     int template_instance_recursion_depth,
3830
     libcerror_error_t **error )
3831
475k
{
3832
475k
  const uint8_t *xml_document_data = NULL;
3833
475k
  static char *function            = "libfwevt_xml_document_read_optional_substitution";
3834
475k
  size_t xml_document_data_size    = 0;
3835
475k
  uint16_t template_value_index    = 0;
3836
475k
  uint8_t template_value_type      = 0;
3837
475k
  int result                       = 0;
3838
3839
475k
  if( internal_xml_document == NULL )
3840
0
  {
3841
0
    libcerror_error_set(
3842
0
     error,
3843
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3844
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3845
0
     "%s: invalid binary XML document.",
3846
0
     function );
3847
3848
0
    return( -1 );
3849
0
  }
3850
475k
  if( xml_token == NULL )
3851
0
  {
3852
0
    libcerror_error_set(
3853
0
     error,
3854
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3855
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3856
0
     "%s: invalid binary XML token.",
3857
0
     function );
3858
3859
0
    return( -1 );
3860
0
  }
3861
475k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION )
3862
0
  {
3863
0
    libcerror_error_set(
3864
0
     error,
3865
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3866
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3867
0
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3868
0
     function,
3869
0
     xml_token->type );
3870
3871
0
    return( -1 );
3872
0
  }
3873
475k
  if( binary_data == NULL )
3874
0
  {
3875
0
    libcerror_error_set(
3876
0
     error,
3877
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3878
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3879
0
     "%s: invalid binary data.",
3880
0
     function );
3881
3882
0
    return( -1 );
3883
0
  }
3884
475k
  if( binary_data_size > (size_t) SSIZE_MAX )
3885
0
  {
3886
0
    libcerror_error_set(
3887
0
     error,
3888
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3889
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3890
0
     "%s: invalid binary XML document data size value exceeds maximum.",
3891
0
     function );
3892
3893
0
    return( -1 );
3894
0
  }
3895
475k
  if( binary_data_offset >= binary_data_size )
3896
0
  {
3897
0
    libcerror_error_set(
3898
0
     error,
3899
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3900
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3901
0
     "%s: invalid binary data offset value out of bounds.",
3902
0
     function );
3903
3904
0
    return( -1 );
3905
0
  }
3906
475k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3907
475k
  xml_document_data_size = binary_data_size - binary_data_offset;
3908
3909
475k
  if( xml_document_data_size < 4 )
3910
13
  {
3911
13
    libcerror_error_set(
3912
13
     error,
3913
13
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3914
13
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3915
13
     "%s: invalid binary XML document data size value too small.",
3916
13
     function );
3917
3918
13
    return( -1 );
3919
13
  }
3920
#if defined( HAVE_DEBUG_OUTPUT )
3921
  if( libcnotify_verbose != 0 )
3922
  {
3923
    libcnotify_printf(
3924
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
3925
     function,
3926
     binary_data_offset );
3927
3928
    libcnotify_printf(
3929
     "%s: optional substitution data:\n",
3930
     function );
3931
    libcnotify_print_data(
3932
     xml_document_data,
3933
     4,
3934
     0 );
3935
  }
3936
#endif
3937
475k
  byte_stream_copy_to_uint16_little_endian(
3938
475k
   &( xml_document_data[ 1 ] ),
3939
475k
   template_value_index );
3940
3941
475k
  template_value_type = xml_document_data[ 3 ];
3942
3943
#if defined( HAVE_DEBUG_OUTPUT )
3944
  if( libcnotify_verbose != 0 )
3945
  {
3946
    libcnotify_printf(
3947
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
3948
     function,
3949
     xml_document_data[ 0 ] );
3950
3951
    libcnotify_printf(
3952
     "%s: identifier\t\t: %" PRIu16 "\n",
3953
     function,
3954
     template_value_index );
3955
3956
    libcnotify_printf(
3957
     "%s: value type\t\t: 0x%02" PRIx8 " (",
3958
     function,
3959
     template_value_type );
3960
    libfwevt_debug_print_value_type(
3961
     template_value_type );
3962
    libcnotify_printf(
3963
     ")\n" );
3964
3965
    libcnotify_printf(
3966
     "\n" );
3967
  }
3968
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3969
3970
475k
  xml_token->size = 4;
3971
3972
475k
  result = libfwevt_xml_document_substitute_template_value(
3973
475k
            internal_xml_document,
3974
475k
            binary_data,
3975
475k
            binary_data_size,
3976
475k
            ascii_codepage,
3977
475k
            flags,
3978
475k
            template_values_array,
3979
475k
            template_value_index,
3980
475k
            template_value_type,
3981
475k
            template_value_offset,
3982
475k
            xml_tag,
3983
475k
            element_recursion_depth,
3984
475k
            template_instance_recursion_depth,
3985
475k
            error );
3986
3987
475k
  if( result == -1 )
3988
18.1k
  {
3989
18.1k
    libcerror_error_set(
3990
18.1k
     error,
3991
18.1k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3992
18.1k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3993
18.1k
     "%s: unable to substitute template value.",
3994
18.1k
     function );
3995
3996
18.1k
    return( -1 );
3997
18.1k
  }
3998
456k
  return( result );
3999
475k
}
4000
4001
/* Reads a PI data from a binary XML document
4002
 * Returns 1 if successful or -1 on error
4003
 */
4004
int libfwevt_xml_document_read_pi_data(
4005
     libfwevt_internal_xml_document_t *internal_xml_document,
4006
     libfwevt_xml_token_t *xml_token,
4007
     const uint8_t *binary_data,
4008
     size_t binary_data_size,
4009
     size_t binary_data_offset,
4010
     libfwevt_xml_tag_t *xml_tag,
4011
     libcerror_error_t **error )
4012
2.05k
{
4013
2.05k
  const uint8_t *xml_document_data = NULL;
4014
2.05k
  static char *function            = "libfwevt_xml_document_read_pi_data";
4015
2.05k
  size_t value_data_size           = 0;
4016
2.05k
  size_t xml_document_data_size    = 0;
4017
4018
2.05k
  if( internal_xml_document == NULL )
4019
0
  {
4020
0
    libcerror_error_set(
4021
0
     error,
4022
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4023
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4024
0
     "%s: invalid binary XML document.",
4025
0
     function );
4026
4027
0
    return( -1 );
4028
0
  }
4029
2.05k
  if( xml_token == NULL )
4030
0
  {
4031
0
    libcerror_error_set(
4032
0
     error,
4033
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4034
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4035
0
     "%s: invalid binary XML token.",
4036
0
     function );
4037
4038
0
    return( -1 );
4039
0
  }
4040
2.05k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_PI_DATA )
4041
50
  {
4042
50
    libcerror_error_set(
4043
50
     error,
4044
50
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4045
50
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4046
50
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
4047
50
     function,
4048
50
     xml_token->type );
4049
4050
50
    return( -1 );
4051
50
  }
4052
2.00k
  if( binary_data == NULL )
4053
0
  {
4054
0
    libcerror_error_set(
4055
0
     error,
4056
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4057
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4058
0
     "%s: invalid binary data.",
4059
0
     function );
4060
4061
0
    return( -1 );
4062
0
  }
4063
2.00k
  if( binary_data_size > (size_t) SSIZE_MAX )
4064
0
  {
4065
0
    libcerror_error_set(
4066
0
     error,
4067
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4068
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4069
0
     "%s: invalid binary XML document data size value exceeds maximum.",
4070
0
     function );
4071
4072
0
    return( -1 );
4073
0
  }
4074
2.00k
  if( binary_data_offset >= binary_data_size )
4075
0
  {
4076
0
    libcerror_error_set(
4077
0
     error,
4078
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4079
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4080
0
     "%s: invalid binary data offset value out of bounds.",
4081
0
     function );
4082
4083
0
    return( -1 );
4084
0
  }
4085
2.00k
  if( xml_tag == NULL )
4086
0
  {
4087
0
    libcerror_error_set(
4088
0
     error,
4089
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4090
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4091
0
     "%s: invalid XML tag.",
4092
0
     function );
4093
4094
0
    return( -1 );
4095
0
  }
4096
2.00k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4097
2.00k
  xml_document_data_size = binary_data_size - binary_data_offset;
4098
4099
2.00k
  if( xml_document_data_size < 3 )
4100
16
  {
4101
16
    libcerror_error_set(
4102
16
     error,
4103
16
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4104
16
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4105
16
     "%s: invalid binary XML document data size value too small.",
4106
16
     function );
4107
4108
16
    return( -1 );
4109
16
  }
4110
#if defined( HAVE_DEBUG_OUTPUT )
4111
  if( libcnotify_verbose != 0 )
4112
  {
4113
    libcnotify_printf(
4114
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
4115
     function,
4116
     binary_data_offset );
4117
4118
    libcnotify_printf(
4119
     "%s: PI data:\n",
4120
     function );
4121
    libcnotify_print_data(
4122
     xml_document_data,
4123
     3,
4124
     0 );
4125
  }
4126
#endif
4127
1.98k
  byte_stream_copy_to_uint16_little_endian(
4128
1.98k
   &( xml_document_data[ 1 ] ),
4129
1.98k
   value_data_size );
4130
4131
#if defined( HAVE_DEBUG_OUTPUT )
4132
  if( libcnotify_verbose != 0 )
4133
  {
4134
    libcnotify_printf(
4135
     "%s: type\t\t\t\t: 0x%02" PRIx8 "\n",
4136
     function,
4137
     xml_document_data[ 0 ] );
4138
4139
    libcnotify_printf(
4140
     "%s: number of characters\t\t: %" PRIzd "\n",
4141
     function,
4142
     value_data_size );
4143
  }
4144
#endif
4145
1.98k
  xml_token->size     = 3;
4146
1.98k
  binary_data_offset += 3;
4147
4148
1.98k
  value_data_size *= 2;
4149
4150
1.98k
  if( ( value_data_size > binary_data_size )
4151
1.98k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
4152
107
  {
4153
107
    libcerror_error_set(
4154
107
     error,
4155
107
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4156
107
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4157
107
     "%s: invalid value data size value out of bounds.",
4158
107
     function );
4159
4160
107
    return( -1 );
4161
107
  }
4162
#if defined( HAVE_DEBUG_OUTPUT )
4163
  if( libcnotify_verbose != 0 )
4164
  {
4165
    libcnotify_printf(
4166
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
4167
     function,
4168
     binary_data_offset );
4169
4170
    libcnotify_printf(
4171
     "%s: value data:\n",
4172
     function );
4173
    libcnotify_print_data(
4174
     &( xml_document_data[ 3 ] ),
4175
     value_data_size,
4176
     0 );
4177
  }
4178
#endif
4179
1.88k
  if( libfwevt_xml_tag_set_value_type(
4180
1.88k
       xml_tag,
4181
1.88k
       LIBFVALUE_VALUE_TYPE_STRING_UTF16,
4182
1.88k
       error ) != 1 )
4183
0
  {
4184
0
    libcerror_error_set(
4185
0
     error,
4186
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4187
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4188
0
     "%s: unable to set value type.",
4189
0
     function );
4190
4191
0
    return( -1 );
4192
0
  }
4193
1.88k
  if( libfwevt_xml_tag_set_value_data(
4194
1.88k
       xml_tag,
4195
1.88k
       &( binary_data[ binary_data_offset ] ),
4196
1.88k
       value_data_size,
4197
1.88k
       LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN,
4198
1.88k
       error ) != 1 )
4199
0
  {
4200
0
    libcerror_error_set(
4201
0
     error,
4202
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4203
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4204
0
     "%s: unable to set value data.",
4205
0
     function );
4206
4207
0
    return( -1 );
4208
0
  }
4209
#if defined( HAVE_DEBUG_OUTPUT )
4210
  if( libcnotify_verbose != 0 )
4211
  {
4212
    if( libfwevt_xml_tag_value_debug_print(
4213
         xml_tag,
4214
         0,
4215
         error ) != 1 )
4216
    {
4217
      libcerror_error_set(
4218
       error,
4219
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4220
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
4221
       "%s: unable to print value.",
4222
       function );
4223
4224
      return( -1 );
4225
    }
4226
  }
4227
#endif
4228
1.88k
  xml_token->size += value_data_size;
4229
4230
1.88k
  return( 1 );
4231
1.88k
}
4232
4233
/* Reads a PI target from a binary XML document
4234
 * Returns 1 if successful or -1 on error
4235
 */
4236
int libfwevt_xml_document_read_pi_target(
4237
     libfwevt_internal_xml_document_t *internal_xml_document,
4238
     libfwevt_xml_token_t *xml_token,
4239
     const uint8_t *binary_data,
4240
     size_t binary_data_size,
4241
     size_t binary_data_offset,
4242
     uint8_t flags,
4243
     libfwevt_xml_tag_t *xml_tag,
4244
     libcerror_error_t **error )
4245
2.23k
{
4246
2.23k
  libfwevt_xml_tag_t *pi_xml_tag      = NULL;
4247
2.23k
  libfwevt_xml_token_t *xml_sub_token = NULL;
4248
2.23k
  const uint8_t *xml_document_data    = NULL;
4249
2.23k
  static char *function               = "libfwevt_xml_document_read_pi_target";
4250
2.23k
  size_t additional_value_size        = 0;
4251
2.23k
  size_t trailing_data_size           = 0;
4252
2.23k
  size_t xml_document_data_offset     = 0;
4253
2.23k
  size_t xml_document_data_size       = 0;
4254
2.23k
  uint32_t pi_name_offset             = 0;
4255
2.23k
  uint32_t pi_name_size               = 0;
4256
4257
2.23k
  if( internal_xml_document == NULL )
4258
0
  {
4259
0
    libcerror_error_set(
4260
0
     error,
4261
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4262
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4263
0
     "%s: invalid binary XML document.",
4264
0
     function );
4265
4266
0
    return( -1 );
4267
0
  }
4268
2.23k
  if( xml_token == NULL )
4269
0
  {
4270
0
    libcerror_error_set(
4271
0
     error,
4272
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4273
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4274
0
     "%s: invalid binary XML token.",
4275
0
     function );
4276
4277
0
    return( -1 );
4278
0
  }
4279
2.23k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_PI_TARGET )
4280
0
  {
4281
0
    libcerror_error_set(
4282
0
     error,
4283
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4284
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4285
0
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
4286
0
     function,
4287
0
     xml_token->type );
4288
4289
0
    return( -1 );
4290
0
  }
4291
2.23k
  if( binary_data == NULL )
4292
0
  {
4293
0
    libcerror_error_set(
4294
0
     error,
4295
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4296
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4297
0
     "%s: invalid binary data.",
4298
0
     function );
4299
4300
0
    return( -1 );
4301
0
  }
4302
2.23k
  if( binary_data_size > (size_t) SSIZE_MAX )
4303
0
  {
4304
0
    libcerror_error_set(
4305
0
     error,
4306
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4307
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4308
0
     "%s: invalid binary XML document data size value exceeds maximum.",
4309
0
     function );
4310
4311
0
    return( -1 );
4312
0
  }
4313
2.23k
  if( binary_data_offset >= binary_data_size )
4314
0
  {
4315
0
    libcerror_error_set(
4316
0
     error,
4317
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4318
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4319
0
     "%s: invalid binary data offset value out of bounds.",
4320
0
     function );
4321
4322
0
    return( -1 );
4323
0
  }
4324
2.23k
  if( xml_tag == NULL )
4325
0
  {
4326
0
    libcerror_error_set(
4327
0
     error,
4328
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4329
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4330
0
     "%s: invalid XML tag.",
4331
0
     function );
4332
4333
0
    return( -1 );
4334
0
  }
4335
2.23k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) == 0 )
4336
0
  {
4337
0
    additional_value_size = 4;
4338
0
  }
4339
2.23k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4340
2.23k
  xml_document_data_size = binary_data_size - binary_data_offset;
4341
4342
2.23k
  if( xml_document_data_size < ( 1 + additional_value_size ) )
4343
0
  {
4344
0
    libcerror_error_set(
4345
0
     error,
4346
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4347
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4348
0
     "%s: invalid binary XML document data size value too small.",
4349
0
     function );
4350
4351
0
    return( -1 );
4352
0
  }
4353
2.23k
  if( libfwevt_xml_tag_initialize(
4354
2.23k
       &pi_xml_tag,
4355
2.23k
       error ) != 1 )
4356
0
  {
4357
0
    libcerror_error_set(
4358
0
     error,
4359
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4360
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4361
0
     "%s: unable to create PI XML tag.",
4362
0
     function );
4363
4364
0
    goto on_error;
4365
0
  }
4366
2.23k
  if( libfwevt_xml_tag_set_type(
4367
2.23k
       pi_xml_tag,
4368
2.23k
       LIBFWEVT_XML_TAG_TYPE_PI,
4369
2.23k
       error ) != 1 )
4370
0
  {
4371
0
    libcerror_error_set(
4372
0
     error,
4373
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4374
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4375
0
     "%s: unable to set XML tag type.",
4376
0
     function );
4377
4378
0
    goto on_error;
4379
0
  }
4380
#if defined( HAVE_DEBUG_OUTPUT )
4381
  if( libcnotify_verbose != 0 )
4382
  {
4383
    libcnotify_printf(
4384
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
4385
     function,
4386
     binary_data_offset );
4387
4388
    libcnotify_printf(
4389
     "%s: PI target data:\n",
4390
     function );
4391
    libcnotify_print_data(
4392
     xml_document_data,
4393
     1 + additional_value_size,
4394
     0 );
4395
  }
4396
#endif
4397
#if defined( HAVE_DEBUG_OUTPUT )
4398
  if( libcnotify_verbose != 0 )
4399
  {
4400
    libcnotify_printf(
4401
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
4402
     function,
4403
     xml_document_data[ 0 ] );
4404
  }
4405
#endif
4406
2.23k
  xml_token->size          = 1;
4407
2.23k
  xml_document_data_offset = 1;
4408
4409
2.23k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) == 0 )
4410
0
  {
4411
    /* TODO double check if this needs to be binary_data_offset + xml_document_data_offset + 1
4412
     */
4413
0
    pi_name_offset = (uint32_t) ( binary_data_offset + xml_document_data_offset );
4414
0
  }
4415
2.23k
  else
4416
2.23k
  {
4417
2.23k
    if( ( xml_document_data_size < 4 )
4418
2.23k
     || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
4419
31
    {
4420
31
      libcerror_error_set(
4421
31
       error,
4422
31
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4423
31
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4424
31
       "%s: invalid binary XML document data size value too small.",
4425
31
       function );
4426
4427
31
      goto on_error;
4428
31
    }
4429
2.20k
    byte_stream_copy_to_uint32_little_endian(
4430
2.20k
     &( xml_document_data[ xml_document_data_offset ] ),
4431
2.20k
     pi_name_offset );
4432
4433
#if defined( HAVE_DEBUG_OUTPUT )
4434
    if( libcnotify_verbose != 0 )
4435
    {
4436
      libcnotify_printf(
4437
       "%s: name offset\t\t\t: 0x%08" PRIx32 "\n",
4438
       function,
4439
       pi_name_offset );
4440
    }
4441
#endif
4442
2.20k
    xml_token->size           = 4;
4443
2.20k
    xml_document_data_offset += 4;
4444
2.20k
  }
4445
#if defined( HAVE_DEBUG_OUTPUT )
4446
  if( libcnotify_verbose != 0 )
4447
  {
4448
    libcnotify_printf(
4449
     "\n" );
4450
  }
4451
#endif
4452
4453
  /* TODO double check setting this to 5 but this is currently needed
4454
   * likely because of additional_value_size when LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS is not set
4455
   */
4456
2.20k
  xml_token->size          = 5;
4457
2.20k
  xml_document_data_offset = 5;
4458
4459
2.20k
  if( pi_name_offset > ( binary_data_offset + xml_document_data_offset ) )
4460
129
  {
4461
129
    libcerror_error_set(
4462
129
     error,
4463
129
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4464
129
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4465
129
     "%s: invalid PI name offset value out of bounds.",
4466
129
     function );
4467
4468
129
    goto on_error;
4469
129
  }
4470
2.07k
  if( ( binary_data_offset + xml_document_data_offset ) < pi_name_offset )
4471
0
  {
4472
0
    trailing_data_size = pi_name_offset - ( binary_data_offset + xml_document_data_offset );
4473
4474
#if defined( HAVE_DEBUG_OUTPUT )
4475
    if( libcnotify_verbose != 0 )
4476
    {
4477
      libcnotify_printf(
4478
       "%s: data offset\t\t: 0x%08" PRIzx "\n",
4479
       function,
4480
       binary_data_offset + 5 );
4481
4482
      libcnotify_printf(
4483
       "%s: trailing data:\n",
4484
       function );
4485
      libcnotify_print_data(
4486
       &( xml_document_data[ 5 ] ),
4487
       trailing_data_size,
4488
       0 );
4489
    }
4490
#endif
4491
0
    xml_token->size          += trailing_data_size;
4492
0
    xml_document_data_offset += trailing_data_size;
4493
0
  }
4494
2.07k
  if( libfwevt_xml_document_read_name(
4495
2.07k
       internal_xml_document,
4496
2.07k
       binary_data,
4497
2.07k
       binary_data_size,
4498
2.07k
       pi_name_offset,
4499
2.07k
       flags,
4500
2.07k
       &pi_name_size,
4501
2.07k
       pi_xml_tag,
4502
2.07k
       error ) != 1 )
4503
11
  {
4504
11
    libcerror_error_set(
4505
11
     error,
4506
11
     LIBCERROR_ERROR_DOMAIN_IO,
4507
11
     LIBCERROR_IO_ERROR_READ_FAILED,
4508
11
     "%s: unable to read PI name.",
4509
11
     function );
4510
4511
11
    goto on_error;
4512
11
  }
4513
2.06k
  if( ( binary_data_offset + xml_document_data_offset ) == pi_name_offset )
4514
418
  {
4515
418
    xml_token->size          += pi_name_size;
4516
418
    xml_document_data_offset += pi_name_size;
4517
418
  }
4518
2.06k
  if( libfwevt_xml_token_initialize(
4519
2.06k
       &xml_sub_token,
4520
2.06k
       error ) != 1 )
4521
0
  {
4522
0
    libcerror_error_set(
4523
0
     error,
4524
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4525
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4526
0
     "%s: unable to create binary XML sub token.",
4527
0
     function );
4528
4529
0
    goto on_error;
4530
0
  }
4531
2.06k
  if( libfwevt_xml_token_read_data(
4532
2.06k
       xml_sub_token,
4533
2.06k
       binary_data,
4534
2.06k
       binary_data_size,
4535
2.06k
       binary_data_offset + xml_document_data_offset,
4536
2.06k
       error ) != 1 )
4537
11
  {
4538
11
    libcerror_error_set(
4539
11
     error,
4540
11
     LIBCERROR_ERROR_DOMAIN_IO,
4541
11
     LIBCERROR_IO_ERROR_READ_FAILED,
4542
11
     "%s: unable to read binary XML sub token.",
4543
11
     function );
4544
4545
11
    goto on_error;
4546
11
  }
4547
2.05k
  if( libfwevt_xml_document_read_pi_data(
4548
2.05k
       internal_xml_document,
4549
2.05k
       xml_sub_token,
4550
2.05k
       binary_data,
4551
2.05k
       binary_data_size,
4552
2.05k
       binary_data_offset + xml_document_data_offset,
4553
2.05k
       pi_xml_tag,
4554
2.05k
       error ) != 1 )
4555
173
  {
4556
173
    libcerror_error_set(
4557
173
     error,
4558
173
     LIBCERROR_ERROR_DOMAIN_IO,
4559
173
     LIBCERROR_IO_ERROR_READ_FAILED,
4560
173
     "%s: unable to read PI target.",
4561
173
     function );
4562
4563
173
    goto on_error;
4564
173
  }
4565
1.88k
  xml_token->size += xml_sub_token->size;
4566
4567
1.88k
  if( libfwevt_xml_token_free(
4568
1.88k
       &xml_sub_token,
4569
1.88k
       error ) != 1 )
4570
0
  {
4571
0
    libcerror_error_set(
4572
0
     error,
4573
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4574
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4575
0
     "%s: unable to free binary XML sub token.",
4576
0
     function );
4577
4578
0
    goto on_error;
4579
0
  }
4580
1.88k
  if( libfwevt_xml_tag_append_element(
4581
1.88k
       xml_tag,
4582
1.88k
       pi_xml_tag,
4583
1.88k
       error ) != 1 )
4584
0
  {
4585
0
    libcerror_error_set(
4586
0
     error,
4587
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4588
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4589
0
     "%s: unable to append PI to XML tag.",
4590
0
     function );
4591
4592
0
    goto on_error;
4593
0
  }
4594
1.88k
  pi_xml_tag = NULL;
4595
4596
1.88k
  return( 1 );
4597
4598
355
on_error:
4599
355
  if( xml_sub_token != NULL )
4600
184
  {
4601
184
    libfwevt_xml_token_free(
4602
184
     &xml_sub_token,
4603
184
     NULL );
4604
184
  }
4605
355
  if( pi_xml_tag != NULL )
4606
355
  {
4607
355
    libfwevt_xml_tag_free(
4608
355
     &pi_xml_tag,
4609
355
     NULL );
4610
355
  }
4611
355
  return( -1 );
4612
1.88k
}
4613
4614
/* Reads a template instance from a binary XML document
4615
 * Returns 1 if successful or -1 on error
4616
 */
4617
int libfwevt_xml_document_read_template_instance(
4618
     libfwevt_internal_xml_document_t *internal_xml_document,
4619
     libfwevt_xml_token_t *xml_token,
4620
     const uint8_t *binary_data,
4621
     size_t binary_data_size,
4622
     size_t binary_data_offset,
4623
     int ascii_codepage,
4624
     uint8_t flags,
4625
     libfwevt_xml_tag_t *xml_tag,
4626
     int element_recursion_depth,
4627
     int template_instance_recursion_depth,
4628
     libcerror_error_t **error )
4629
22.3k
{
4630
22.3k
  libcdata_array_t *template_values_array  = NULL;
4631
22.3k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
4632
22.3k
  const uint8_t *xml_document_data         = NULL;
4633
22.3k
  static char *function                    = "libfwevt_xml_document_read_template_instance";
4634
22.3k
  size_t template_data_offset              = 0;
4635
22.3k
  size_t template_data_size                = 0;
4636
22.3k
  size_t template_values_data_offset       = 0;
4637
22.3k
  size_t template_values_data_size         = 0;
4638
22.3k
  size_t trailing_data_size                = 0;
4639
22.3k
  size_t xml_document_data_size            = 0;
4640
22.3k
  uint32_t template_definition_data_offset = 0;
4641
22.3k
  uint32_t template_definition_data_size   = 0;
4642
4643
#if defined( HAVE_DEBUG_OUTPUT )
4644
  uint32_t value_32bit                     = 0;
4645
#endif
4646
4647
22.3k
  if( internal_xml_document == NULL )
4648
0
  {
4649
0
    libcerror_error_set(
4650
0
     error,
4651
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4652
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4653
0
     "%s: invalid binary XML document.",
4654
0
     function );
4655
4656
0
    return( -1 );
4657
0
  }
4658
22.3k
  if( xml_token == NULL )
4659
0
  {
4660
0
    libcerror_error_set(
4661
0
     error,
4662
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4663
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4664
0
     "%s: invalid binary XML token.",
4665
0
     function );
4666
4667
0
    return( -1 );
4668
0
  }
4669
22.3k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE )
4670
0
  {
4671
0
    libcerror_error_set(
4672
0
     error,
4673
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4674
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4675
0
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
4676
0
     function,
4677
0
     xml_token->type );
4678
4679
0
    return( -1 );
4680
0
  }
4681
22.3k
  if( binary_data == NULL )
4682
0
  {
4683
0
    libcerror_error_set(
4684
0
     error,
4685
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4686
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4687
0
     "%s: invalid binary data.",
4688
0
     function );
4689
4690
0
    return( -1 );
4691
0
  }
4692
22.3k
  if( binary_data_size > (size_t) SSIZE_MAX )
4693
0
  {
4694
0
    libcerror_error_set(
4695
0
     error,
4696
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4697
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4698
0
     "%s: invalid binary XML document data size value exceeds maximum.",
4699
0
     function );
4700
4701
0
    return( -1 );
4702
0
  }
4703
22.3k
  if( binary_data_offset >= binary_data_size )
4704
0
  {
4705
0
    libcerror_error_set(
4706
0
     error,
4707
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4708
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4709
0
     "%s: invalid binary data offset value out of bounds.",
4710
0
     function );
4711
4712
0
    return( -1 );
4713
0
  }
4714
22.3k
  if( ( template_instance_recursion_depth < 0 )
4715
22.3k
   || ( template_instance_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_INSTANCE_RECURSION_DEPTH ) )
4716
196
  {
4717
196
    libcerror_error_set(
4718
196
     error,
4719
196
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4720
196
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4721
196
     "%s: invalid template instance recursion depth value out of bounds.",
4722
196
     function );
4723
4724
196
    return( -1 );
4725
196
  }
4726
22.1k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4727
22.1k
  xml_document_data_size = binary_data_size - binary_data_offset;
4728
4729
22.1k
  if( ( binary_data_size < 10 )
4730
22.1k
   || ( binary_data_offset >= ( binary_data_size - 10 ) ) )
4731
20
  {
4732
20
    libcerror_error_set(
4733
20
     error,
4734
20
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4735
20
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4736
20
     "%s: invalid binary XML document data size value too small.",
4737
20
     function );
4738
4739
20
    goto on_error;
4740
20
  }
4741
#if defined( HAVE_DEBUG_OUTPUT )
4742
  if( libcnotify_verbose != 0 )
4743
  {
4744
    libcnotify_printf(
4745
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
4746
     function,
4747
     binary_data_offset );
4748
4749
    libcnotify_printf(
4750
     "%s: template instance header data:\n",
4751
     function );
4752
    libcnotify_print_data(
4753
     xml_document_data,
4754
     10,
4755
     0 );
4756
  }
4757
#endif
4758
22.1k
  byte_stream_copy_to_uint32_little_endian(
4759
22.1k
   &( xml_document_data[ 6 ] ),
4760
22.1k
   template_definition_data_offset );
4761
4762
#if defined( HAVE_DEBUG_OUTPUT )
4763
  if( libcnotify_verbose != 0 )
4764
  {
4765
    libcnotify_printf(
4766
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
4767
     function,
4768
     xml_document_data[ 0 ] );
4769
4770
    libcnotify_printf(
4771
     "%s: unknown1\t\t\t: %" PRIu8 "\n",
4772
     function,
4773
     xml_document_data[ 1 ] );
4774
4775
    byte_stream_copy_to_uint32_little_endian(
4776
     &( xml_document_data[ 2 ] ),
4777
     value_32bit );
4778
    libcnotify_printf(
4779
     "%s: unknown2\t\t\t: 0x%08" PRIx32 "\n",
4780
     function,
4781
     value_32bit );
4782
4783
    libcnotify_printf(
4784
     "%s: data offset\t\t: 0x%08" PRIx32 "\n",
4785
     function,
4786
     template_definition_data_offset );
4787
4788
    libcnotify_printf(
4789
     "\n" );
4790
  }
4791
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4792
4793
22.1k
  xml_token->size     = 10;
4794
22.1k
  binary_data_offset += 10;
4795
4796
22.1k
  if( template_definition_data_offset >= binary_data_size )
4797
100
  {
4798
100
    libcerror_error_set(
4799
100
     error,
4800
100
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4801
100
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4802
100
     "%s: invalid template definition data offset value out of bounds.",
4803
100
     function );
4804
4805
100
    goto on_error;
4806
100
  }
4807
22.0k
  if( template_definition_data_offset > binary_data_offset )
4808
1.00k
  {
4809
1.00k
    trailing_data_size = template_definition_data_offset - binary_data_offset;
4810
4811
#if defined( HAVE_DEBUG_OUTPUT )
4812
    if( libcnotify_verbose != 0 )
4813
    {
4814
      libcnotify_printf(
4815
       "%s: data offset\t\t: 0x%08" PRIzx "\n",
4816
       function,
4817
       binary_data_offset );
4818
4819
      libcnotify_printf(
4820
       "%s: trailing data:\n",
4821
       function );
4822
      libcnotify_print_data(
4823
       &( binary_data[ binary_data_offset ] ),
4824
       trailing_data_size,
4825
       0 );
4826
    }
4827
#endif
4828
1.00k
    xml_token->size    += trailing_data_size;
4829
1.00k
    binary_data_offset += trailing_data_size;
4830
1.00k
  }
4831
22.0k
  template_data_offset = template_definition_data_offset;
4832
4833
22.0k
  if( ( binary_data_size < 24 )
4834
22.0k
   || ( template_data_offset >= ( binary_data_size - 24 ) ) )
4835
77
  {
4836
77
    libcerror_error_set(
4837
77
     error,
4838
77
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4839
77
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4840
77
     "%s: invalid binary XML document data size value too small.",
4841
77
     function );
4842
4843
77
    goto on_error;
4844
77
  }
4845
21.9k
  byte_stream_copy_to_uint32_little_endian(
4846
21.9k
   &( binary_data[ template_data_offset + 20 ] ),
4847
21.9k
   template_definition_data_size );
4848
4849
#if defined( HAVE_DEBUG_OUTPUT )
4850
  if( libcnotify_verbose != 0 )
4851
  {
4852
    byte_stream_copy_to_uint32_little_endian(
4853
     &( binary_data[ template_data_offset ] ),
4854
     value_32bit );
4855
    libcnotify_printf(
4856
     "%s: offset next\t\t: 0x%08" PRIx32 "\n",
4857
     function,
4858
     value_32bit );
4859
4860
    if( libfwevt_debug_print_guid_value(
4861
         function,
4862
         "identifier\t\t",
4863
         &( binary_data[ template_data_offset + 4 ] ),
4864
         16,
4865
         LIBFGUID_ENDIAN_LITTLE,
4866
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
4867
         error ) != 1 )
4868
    {
4869
      libcerror_error_set(
4870
       error,
4871
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4872
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
4873
       "%s: unable to print GUID value.",
4874
       function );
4875
4876
      return( -1 );
4877
    }
4878
    libcnotify_printf(
4879
     "%s: definition size\t\t: %" PRIu32 "\n",
4880
     function,
4881
     template_definition_data_size );
4882
4883
    libcnotify_printf(
4884
     "\n" );
4885
  }
4886
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4887
4888
21.9k
  if( template_definition_data_size > binary_data_size )
4889
181
  {
4890
181
    libcerror_error_set(
4891
181
     error,
4892
181
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4893
181
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4894
181
     "%s: invalid template definition data size value out of bounds.",
4895
181
     function );
4896
4897
181
    goto on_error;
4898
181
  }
4899
21.8k
  if( template_data_offset == binary_data_offset )
4900
1.81k
  {
4901
1.81k
    template_values_data_offset = 24 + template_definition_data_size;
4902
1.81k
  }
4903
20.0k
  else
4904
20.0k
  {
4905
20.0k
    template_values_data_offset = 0;
4906
20.0k
  }
4907
21.8k
  template_data_offset += 24;
4908
4909
21.8k
  if( template_values_data_offset >= xml_document_data_size )
4910
44
  {
4911
44
    libcerror_error_set(
4912
44
     error,
4913
44
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4914
44
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4915
44
     "%s: invalid template values data offset value out of bounds.",
4916
44
     function );
4917
4918
44
    goto on_error;
4919
44
  }
4920
21.7k
  if( libfwevt_xml_document_read_template_instance_values(
4921
21.7k
       internal_xml_document,
4922
21.7k
       binary_data,
4923
21.7k
       binary_data_size,
4924
21.7k
       binary_data_offset + template_values_data_offset,
4925
21.7k
       &template_values_array,
4926
21.7k
       &template_values_data_size,
4927
21.7k
       error ) != 1 )
4928
379
  {
4929
379
    libcerror_error_set(
4930
379
     error,
4931
379
     LIBCERROR_ERROR_DOMAIN_IO,
4932
379
     LIBCERROR_IO_ERROR_READ_FAILED,
4933
379
     "%s: unable to read document template instance values.",
4934
379
     function );
4935
4936
379
    goto on_error;
4937
379
  }
4938
21.3k
  xml_token->size += template_values_data_size;
4939
4940
21.3k
  if( libfwevt_xml_token_initialize(
4941
21.3k
       &xml_sub_token,
4942
21.3k
       error ) != 1 )
4943
0
  {
4944
0
    libcerror_error_set(
4945
0
     error,
4946
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4947
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4948
0
     "%s: unable to create binary XML sub token.",
4949
0
     function );
4950
4951
0
    goto on_error;
4952
0
  }
4953
21.3k
  if( libfwevt_xml_token_read_data(
4954
21.3k
       xml_sub_token,
4955
21.3k
       binary_data,
4956
21.3k
       binary_data_size,
4957
21.3k
       template_data_offset,
4958
21.3k
       error ) != 1 )
4959
19
  {
4960
19
    libcerror_error_set(
4961
19
     error,
4962
19
     LIBCERROR_ERROR_DOMAIN_IO,
4963
19
     LIBCERROR_IO_ERROR_READ_FAILED,
4964
19
     "%s: unable to read binary XML sub token.",
4965
19
     function );
4966
4967
19
    goto on_error;
4968
19
  }
4969
21.3k
  if( libfwevt_xml_document_read_fragment_header(
4970
21.3k
       internal_xml_document,
4971
21.3k
       xml_sub_token,
4972
21.3k
       binary_data,
4973
21.3k
       binary_data_size,
4974
21.3k
       template_data_offset,
4975
21.3k
       error ) != 1 )
4976
88
  {
4977
88
    libcerror_error_set(
4978
88
     error,
4979
88
     LIBCERROR_ERROR_DOMAIN_IO,
4980
88
     LIBCERROR_IO_ERROR_READ_FAILED,
4981
88
     "%s: unable to read fragment header.",
4982
88
     function );
4983
4984
88
    goto on_error;
4985
88
  }
4986
21.2k
  template_data_offset += xml_sub_token->size;
4987
4988
21.2k
  if( libfwevt_xml_token_read_data(
4989
21.2k
       xml_sub_token,
4990
21.2k
       binary_data,
4991
21.2k
       binary_data_size,
4992
21.2k
       template_data_offset,
4993
21.2k
       error ) != 1 )
4994
5
  {
4995
5
    libcerror_error_set(
4996
5
     error,
4997
5
     LIBCERROR_ERROR_DOMAIN_IO,
4998
5
     LIBCERROR_IO_ERROR_READ_FAILED,
4999
5
     "%s: unable to read binary XML sub token.",
5000
5
     function );
5001
5002
5
    goto on_error;
5003
5
  }
5004
21.2k
  if( libfwevt_xml_document_read_element(
5005
21.2k
       internal_xml_document,
5006
21.2k
       xml_sub_token,
5007
21.2k
       binary_data,
5008
21.2k
       binary_data_size,
5009
21.2k
       template_data_offset,
5010
21.2k
       ascii_codepage,
5011
21.2k
       flags,
5012
21.2k
       template_values_array,
5013
21.2k
       xml_tag,
5014
21.2k
       element_recursion_depth + 1,
5015
21.2k
       template_instance_recursion_depth,
5016
21.2k
       error ) != 1 )
5017
5.49k
  {
5018
5.49k
    libcerror_error_set(
5019
5.49k
     error,
5020
5.49k
     LIBCERROR_ERROR_DOMAIN_IO,
5021
5.49k
     LIBCERROR_IO_ERROR_READ_FAILED,
5022
5.49k
     "%s: unable to read element.",
5023
5.49k
     function );
5024
5025
5.49k
    goto on_error;
5026
5.49k
  }
5027
15.7k
  template_data_offset += xml_sub_token->size;
5028
5029
15.7k
  if( libfwevt_xml_token_read_data(
5030
15.7k
       xml_sub_token,
5031
15.7k
       binary_data,
5032
15.7k
       binary_data_size,
5033
15.7k
       template_data_offset,
5034
15.7k
       error ) != 1 )
5035
17
  {
5036
17
    libcerror_error_set(
5037
17
     error,
5038
17
     LIBCERROR_ERROR_DOMAIN_IO,
5039
17
     LIBCERROR_IO_ERROR_READ_FAILED,
5040
17
     "%s: unable to read binary XML sub token.",
5041
17
     function );
5042
5043
17
    goto on_error;
5044
17
  }
5045
15.7k
  if( xml_sub_token->type != LIBFWEVT_XML_TOKEN_END_OF_FILE )
5046
14
  {
5047
14
    libcerror_error_set(
5048
14
     error,
5049
14
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5050
14
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5051
14
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
5052
14
     function,
5053
14
     xml_token->type );
5054
5055
14
    goto on_error;
5056
14
  }
5057
15.7k
  if( binary_data_offset >= ( binary_data_size - 1 ) )
5058
0
  {
5059
0
    libcerror_error_set(
5060
0
     error,
5061
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5062
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5063
0
     "%s: invalid binary XML document data size value too small.",
5064
0
     function );
5065
5066
0
    goto on_error;
5067
0
  }
5068
#if defined( HAVE_DEBUG_OUTPUT )
5069
  if( libcnotify_verbose != 0 )
5070
  {
5071
    libcnotify_printf(
5072
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
5073
     function,
5074
     binary_data_offset );
5075
5076
    libcnotify_printf(
5077
     "%s: end of file data:\n",
5078
     function );
5079
    libcnotify_print_data(
5080
     &( binary_data[ binary_data_offset ] ),
5081
     1,
5082
     0 );
5083
  }
5084
#endif
5085
#if defined( HAVE_DEBUG_OUTPUT )
5086
  if( libcnotify_verbose != 0 )
5087
  {
5088
    libcnotify_printf(
5089
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
5090
     function,
5091
     binary_data[ binary_data_offset ] );
5092
5093
    libcnotify_printf(
5094
     "\n" );
5095
  }
5096
#endif
5097
15.7k
  template_data_offset += 1;
5098
5099
15.7k
  if( libfwevt_xml_token_free(
5100
15.7k
       &xml_sub_token,
5101
15.7k
       error ) != 1 )
5102
0
  {
5103
0
    libcerror_error_set(
5104
0
     error,
5105
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5106
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5107
0
     "%s: unable to free binary XML sub token.",
5108
0
     function );
5109
5110
0
    goto on_error;
5111
0
  }
5112
15.7k
  if( template_definition_data_offset == binary_data_offset )
5113
453
  {
5114
453
    template_data_size = template_data_offset
5115
453
                       - template_definition_data_offset;
5116
5117
453
    xml_token->size += template_data_size;
5118
5119
    /* The template data size does not include the first 33 bytes
5120
     * of the template definition
5121
     * In this case the template data size contains 24 of the 33 bytes
5122
     */
5123
453
    if( template_definition_data_size < ( template_data_size - 24 ) )
5124
6
    {
5125
6
      libcerror_error_set(
5126
6
       error,
5127
6
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5128
6
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5129
6
       "%s: invalid template definition data size value too small.",
5130
6
       function );
5131
5132
6
      goto on_error;
5133
6
    }
5134
447
    template_definition_data_size -= (uint32_t) ( template_data_size - 24 );
5135
447
  }
5136
/* TODO check if template_definition_data_size is 0 */
5137
5138
15.7k
  if( libcdata_array_free(
5139
15.7k
       &template_values_array,
5140
15.7k
       (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5141
15.7k
       error ) != 1 )
5142
0
  {
5143
0
    libcerror_error_set(
5144
0
     error,
5145
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5146
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5147
0
     "%s: unable to free template values array.",
5148
0
     function );
5149
5150
0
    goto on_error;
5151
0
  }
5152
15.7k
  return( 1 );
5153
5154
6.44k
on_error:
5155
6.44k
  if( template_values_array != NULL )
5156
5.64k
  {
5157
5.64k
    libcdata_array_free(
5158
5.64k
     &template_values_array,
5159
5.64k
     (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5160
5.64k
     NULL );
5161
5.64k
  }
5162
6.44k
  if( xml_sub_token != NULL )
5163
5.63k
  {
5164
5.63k
    libfwevt_xml_token_free(
5165
5.63k
     &xml_sub_token,
5166
5.63k
     NULL );
5167
5.63k
  }
5168
6.44k
  return( -1 );
5169
15.7k
}
5170
5171
/* Reads the template instance values from a binary XML document
5172
 * Returns 1 if successful or -1 on error
5173
 */
5174
int libfwevt_xml_document_read_template_instance_values(
5175
     libfwevt_internal_xml_document_t *internal_xml_document,
5176
     const uint8_t *binary_data,
5177
     size_t binary_data_size,
5178
     size_t binary_data_offset,
5179
     libcdata_array_t **template_values_array,
5180
     size_t *template_values_size,
5181
     libcerror_error_t **error )
5182
21.7k
{
5183
21.7k
  libfwevt_xml_template_value_t *template_value = NULL;
5184
21.7k
  static char *function                         = "libfwevt_xml_document_read_template_instance_values";
5185
21.7k
  size_t safe_template_values_size              = 0;
5186
21.7k
  size_t template_value_definitions_data_size   = 0;
5187
21.7k
  size_t template_values_data_size              = 0;
5188
21.7k
  uint32_t number_of_template_values            = 0;
5189
21.7k
  uint32_t template_value_index                 = 0;
5190
21.7k
  uint16_t template_value_data_size             = 0;
5191
21.7k
  uint8_t template_value_type                   = 0;
5192
5193
21.7k
  if( internal_xml_document == NULL )
5194
0
  {
5195
0
    libcerror_error_set(
5196
0
     error,
5197
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5198
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5199
0
     "%s: invalid binary XML document.",
5200
0
     function );
5201
5202
0
    return( -1 );
5203
0
  }
5204
21.7k
  if( ( binary_data_size < 4 )
5205
21.7k
   || ( binary_data_offset >= ( binary_data_size - 4 ) ) )
5206
37
  {
5207
37
    libcerror_error_set(
5208
37
     error,
5209
37
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5210
37
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5211
37
     "%s: invalid binary data size value out of bounds.",
5212
37
     function );
5213
5214
37
    return( -1 );
5215
37
  }
5216
21.7k
  if( template_values_size == NULL )
5217
0
  {
5218
0
    libcerror_error_set(
5219
0
     error,
5220
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5221
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5222
0
     "%s: invalid template values size.",
5223
0
     function );
5224
5225
0
    return( -1 );
5226
0
  }
5227
#if defined( HAVE_DEBUG_OUTPUT )
5228
  if( libcnotify_verbose != 0 )
5229
  {
5230
    libcnotify_printf(
5231
     "%s: data offset\t: 0x%08" PRIzx "\n",
5232
     function,
5233
     binary_data_offset );
5234
5235
    libcnotify_printf(
5236
     "%s: template instance data:\n",
5237
     function );
5238
    libcnotify_print_data(
5239
     &( binary_data[ binary_data_offset ] ),
5240
     4,
5241
     0 );
5242
  }
5243
#endif
5244
21.7k
  byte_stream_copy_to_uint32_little_endian(
5245
21.7k
   &( binary_data[ binary_data_offset ] ),
5246
21.7k
   number_of_template_values );
5247
5248
#if defined( HAVE_DEBUG_OUTPUT )
5249
  if( libcnotify_verbose != 0 )
5250
  {
5251
    libcnotify_printf(
5252
     "%s: number of values\t: %" PRIu32 "\n",
5253
     function,
5254
     number_of_template_values );
5255
5256
    libcnotify_printf(
5257
     "\n" );
5258
  }
5259
#endif
5260
21.7k
  safe_template_values_size = 4;
5261
21.7k
  binary_data_offset       += 4;
5262
5263
21.7k
  template_value_definitions_data_size = number_of_template_values * 4;
5264
5265
21.7k
  if( ( template_value_definitions_data_size > binary_data_size )
5266
21.7k
   || ( binary_data_offset >= ( binary_data_size - template_value_definitions_data_size ) ) )
5267
138
  {
5268
138
    libcerror_error_set(
5269
138
     error,
5270
138
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5271
138
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5272
138
     "%s: invalid template value definitions data size value out of bounds.",
5273
138
     function );
5274
5275
138
    goto on_error;
5276
138
  }
5277
#if defined( HAVE_DEBUG_OUTPUT )
5278
  if( libcnotify_verbose != 0 )
5279
  {
5280
    libcnotify_printf(
5281
     "%s: data offset\t: 0x%08" PRIzx "\n",
5282
     function,
5283
     binary_data_offset );
5284
5285
    libcnotify_printf(
5286
     "%s: template instance value descriptor data:\n",
5287
     function );
5288
    libcnotify_print_data(
5289
     &( binary_data[ binary_data_offset ] ),
5290
     template_value_definitions_data_size,
5291
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
5292
  }
5293
#endif
5294
21.5k
  if( libcdata_array_initialize(
5295
21.5k
       template_values_array,
5296
21.5k
       number_of_template_values,
5297
21.5k
       error ) != 1 )
5298
26
  {
5299
26
    libcerror_error_set(
5300
26
     error,
5301
26
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5302
26
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5303
26
     "%s: unable to create template values array.",
5304
26
     function );
5305
5306
26
    goto on_error;
5307
26
  }
5308
21.5k
  for( template_value_index = 0;
5309
2.63M
       template_value_index < number_of_template_values;
5310
2.60M
       template_value_index++ )
5311
2.60M
  {
5312
2.60M
    byte_stream_copy_to_uint16_little_endian(
5313
2.60M
     &( binary_data[ binary_data_offset ] ),
5314
2.60M
     template_value_data_size );
5315
5316
2.60M
    template_value_type = binary_data[ binary_data_offset + 2 ];
5317
5318
#if defined( HAVE_DEBUG_OUTPUT )
5319
    if( libcnotify_verbose != 0 )
5320
    {
5321
      libcnotify_printf(
5322
       "%s: value: %02" PRIu32 " size\t: %" PRIu16 "\n",
5323
       function,
5324
       template_value_index,
5325
       template_value_data_size );
5326
5327
      libcnotify_printf(
5328
       "%s: value: %02" PRIu32 " type\t: 0x%02" PRIx8 " (",
5329
       function,
5330
       template_value_index,
5331
       template_value_type );
5332
      libfwevt_debug_print_value_type(
5333
       template_value_type );
5334
      libcnotify_printf(
5335
       ")\n" );
5336
5337
      libcnotify_printf(
5338
       "%s: value: %02" PRIu32 " unknown1\t: 0x%02" PRIx8 "\n",
5339
       function,
5340
       template_value_index,
5341
       binary_data[ binary_data_offset + 3 ] );
5342
5343
      libcnotify_printf(
5344
       "\n" );
5345
    }
5346
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5347
5348
2.60M
    safe_template_values_size += 4;
5349
2.60M
    binary_data_offset        += 4;
5350
5351
2.60M
    template_values_data_size += template_value_data_size;
5352
5353
2.60M
    if( libfwevt_xml_template_value_initialize(
5354
2.60M
         &template_value,
5355
2.60M
         error ) != 1 )
5356
0
    {
5357
0
      libcerror_error_set(
5358
0
       error,
5359
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5360
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5361
0
       "%s: unable to create template value.",
5362
0
       function );
5363
5364
0
      goto on_error;
5365
0
    }
5366
2.60M
    if( libfwevt_xml_template_value_set_type(
5367
2.60M
         template_value,
5368
2.60M
         template_value_type,
5369
2.60M
         error ) != 1 )
5370
0
    {
5371
0
      libcerror_error_set(
5372
0
       error,
5373
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5374
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5375
0
       "%s: unable to set template value type.",
5376
0
       function );
5377
5378
0
      libfwevt_xml_template_value_free(
5379
0
       &template_value,
5380
0
       NULL );
5381
5382
0
      goto on_error;
5383
0
    }
5384
2.60M
    if( libfwevt_xml_template_value_set_size(
5385
2.60M
         template_value,
5386
2.60M
         template_value_data_size,
5387
2.60M
         error ) != 1 )
5388
0
    {
5389
0
      libcerror_error_set(
5390
0
       error,
5391
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5392
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5393
0
       "%s: unable to set template value data size.",
5394
0
       function );
5395
5396
0
      libfwevt_xml_template_value_free(
5397
0
       &template_value,
5398
0
       NULL );
5399
5400
0
      goto on_error;
5401
0
    }
5402
2.60M
    if( libcdata_array_set_entry_by_index(
5403
2.60M
         *template_values_array,
5404
2.60M
         (int) template_value_index,
5405
2.60M
         (intptr_t *) template_value,
5406
2.60M
         error ) != 1 )
5407
0
    {
5408
0
      libcerror_error_set(
5409
0
       error,
5410
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5411
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5412
0
       "%s: unable to set template value: %" PRIu32 " in array.",
5413
0
       function,
5414
0
       template_value_index );
5415
5416
0
      libfwevt_xml_template_value_free(
5417
0
       &template_value,
5418
0
       NULL );
5419
5420
0
      goto on_error;
5421
0
    }
5422
2.60M
    template_value = NULL;
5423
2.60M
  }
5424
21.5k
  if( ( template_values_data_size > binary_data_size )
5425
21.5k
   || ( binary_data_offset >= ( binary_data_size - template_values_data_size ) ) )
5426
178
  {
5427
178
    libcerror_error_set(
5428
178
     error,
5429
178
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5430
178
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5431
178
     "%s: invalid template values data size value out of bounds.",
5432
178
     function );
5433
5434
178
    goto on_error;
5435
178
  }
5436
#if defined( HAVE_DEBUG_OUTPUT )
5437
  if( libcnotify_verbose != 0 )
5438
  {
5439
    libcnotify_printf(
5440
     "%s: data offset\t: 0x%08" PRIzx "\n",
5441
     function,
5442
     binary_data_offset );
5443
5444
    libcnotify_printf(
5445
     "%s: values data:\n",
5446
     function );
5447
    libcnotify_print_data(
5448
     &( binary_data[ binary_data_offset ] ),
5449
     template_values_data_size,
5450
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
5451
  }
5452
#endif
5453
21.3k
  for( template_value_index = 0;
5454
772k
       template_value_index < number_of_template_values;
5455
751k
       template_value_index++ )
5456
751k
  {
5457
751k
    if( libcdata_array_get_entry_by_index(
5458
751k
         *template_values_array,
5459
751k
         (int) template_value_index,
5460
751k
         (intptr_t **) &template_value,
5461
751k
         error ) != 1 )
5462
0
    {
5463
0
      libcerror_error_set(
5464
0
       error,
5465
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5466
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5467
0
       "%s: unable to retrieve template value: %" PRIu32 " from array.",
5468
0
       function,
5469
0
       template_value_index );
5470
5471
0
      goto on_error;
5472
0
    }
5473
751k
    if( libfwevt_xml_template_value_get_size(
5474
751k
         template_value,
5475
751k
         &template_value_data_size,
5476
751k
         error ) != 1 )
5477
0
    {
5478
0
      libcerror_error_set(
5479
0
       error,
5480
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5481
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5482
0
       "%s: unable to retrieve template value data size.",
5483
0
       function );
5484
5485
0
      goto on_error;
5486
0
    }
5487
#if defined( HAVE_DEBUG_OUTPUT )
5488
    if( libcnotify_verbose != 0 )
5489
    {
5490
      libcnotify_printf(
5491
       "%s: data offset\t: 0x%08" PRIzx "\n",
5492
       function,
5493
       binary_data_offset );
5494
5495
      libcnotify_printf(
5496
       "%s: value: %02" PRIu32 " data:\n",
5497
       function,
5498
       template_value_index );
5499
      libcnotify_print_data(
5500
       &( binary_data[ binary_data_offset ] ),
5501
       template_value_data_size,
5502
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
5503
    }
5504
#endif
5505
    /* Note that template_value_data_size is allowed to be 0.
5506
     * Don't set the template value offset in such a case.
5507
     */
5508
751k
    if( template_value_data_size == 0 )
5509
702k
    {
5510
702k
      continue;
5511
702k
    }
5512
48.8k
    if( libfwevt_xml_template_value_set_offset(
5513
48.8k
         template_value,
5514
48.8k
         binary_data_offset,
5515
48.8k
         error ) != 1 )
5516
0
    {
5517
0
      libcerror_error_set(
5518
0
       error,
5519
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5520
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5521
0
       "%s: unable to set template value data offset.",
5522
0
       function );
5523
5524
0
      goto on_error;
5525
0
    }
5526
48.8k
    binary_data_offset += template_value_data_size;
5527
48.8k
  }
5528
21.3k
  *template_values_size = safe_template_values_size + template_values_data_size;
5529
5530
21.3k
  return( 1 );
5531
5532
342
on_error:
5533
342
  if( template_values_array != NULL )
5534
342
  {
5535
342
    libcdata_array_free(
5536
342
     template_values_array,
5537
342
     (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5538
342
     NULL );
5539
342
  }
5540
342
  return( -1 );
5541
21.3k
}
5542
5543
/* Reads a value from a binary XML document
5544
 * Returns 1 if successful or -1 on error
5545
 */
5546
int libfwevt_xml_document_read_value(
5547
     libfwevt_internal_xml_document_t *internal_xml_document,
5548
     libfwevt_xml_token_t *xml_token,
5549
     const uint8_t *binary_data,
5550
     size_t binary_data_size,
5551
     size_t binary_data_offset,
5552
     libfwevt_xml_tag_t *xml_tag,
5553
     libcerror_error_t **error )
5554
135k
{
5555
135k
  const uint8_t *xml_document_data = NULL;
5556
135k
  static char *function            = "libfwevt_xml_document_read_value";
5557
135k
  size_t value_data_size           = 0;
5558
135k
  size_t xml_document_data_size    = 0;
5559
135k
  uint8_t xml_value_type           = 0;
5560
135k
  int value_encoding               = 0;
5561
135k
  int value_entry_index            = 0;
5562
135k
  int value_type                   = 0;
5563
5564
135k
  if( internal_xml_document == NULL )
5565
0
  {
5566
0
    libcerror_error_set(
5567
0
     error,
5568
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5569
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5570
0
     "%s: invalid binary XML document.",
5571
0
     function );
5572
5573
0
    return( -1 );
5574
0
  }
5575
135k
  if( xml_token == NULL )
5576
0
  {
5577
0
    libcerror_error_set(
5578
0
     error,
5579
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5580
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5581
0
     "%s: invalid binary XML token.",
5582
0
     function );
5583
5584
0
    return( -1 );
5585
0
  }
5586
135k
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_VALUE )
5587
0
  {
5588
0
    libcerror_error_set(
5589
0
     error,
5590
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5591
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5592
0
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
5593
0
     function,
5594
0
     xml_token->type );
5595
5596
0
    return( -1 );
5597
0
  }
5598
135k
  if( binary_data == NULL )
5599
0
  {
5600
0
    libcerror_error_set(
5601
0
     error,
5602
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5603
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5604
0
     "%s: invalid binary data.",
5605
0
     function );
5606
5607
0
    return( -1 );
5608
0
  }
5609
135k
  if( binary_data_size > (size_t) SSIZE_MAX )
5610
0
  {
5611
0
    libcerror_error_set(
5612
0
     error,
5613
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5614
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
5615
0
     "%s: invalid binary XML document data size value exceeds maximum.",
5616
0
     function );
5617
5618
0
    return( -1 );
5619
0
  }
5620
135k
  if( binary_data_offset >= binary_data_size )
5621
0
  {
5622
0
    libcerror_error_set(
5623
0
     error,
5624
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5625
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5626
0
     "%s: invalid binary data offset value out of bounds.",
5627
0
     function );
5628
5629
0
    return( -1 );
5630
0
  }
5631
135k
  if( xml_tag == NULL )
5632
0
  {
5633
0
    libcerror_error_set(
5634
0
     error,
5635
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5636
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5637
0
     "%s: invalid XML tag.",
5638
0
     function );
5639
5640
0
    return( -1 );
5641
0
  }
5642
135k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
5643
135k
  xml_document_data_size = binary_data_size - binary_data_offset;
5644
5645
135k
  if( xml_document_data_size < 4 )
5646
47
  {
5647
47
    libcerror_error_set(
5648
47
     error,
5649
47
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5650
47
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5651
47
     "%s: invalid binary XML document data size value too small.",
5652
47
     function );
5653
5654
47
    return( -1 );
5655
47
  }
5656
#if defined( HAVE_DEBUG_OUTPUT )
5657
  if( libcnotify_verbose != 0 )
5658
  {
5659
    libcnotify_printf(
5660
     "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
5661
     function,
5662
     binary_data_offset );
5663
5664
    libcnotify_printf(
5665
     "%s: value data:\n",
5666
     function );
5667
    libcnotify_print_data(
5668
     xml_document_data,
5669
     4,
5670
     0 );
5671
  }
5672
#endif
5673
135k
  xml_value_type = xml_document_data[ 1 ];
5674
5675
#if defined( HAVE_DEBUG_OUTPUT )
5676
  if( libcnotify_verbose != 0 )
5677
  {
5678
    libcnotify_printf(
5679
     "%s: type\t\t\t\t\t: 0x%02" PRIx8 "\n",
5680
     function,
5681
     xml_document_data[ 0 ] );
5682
5683
    libcnotify_printf(
5684
     "%s: value type\t\t\t\t: 0x%02" PRIx8 " (",
5685
     function,
5686
     xml_value_type );
5687
    libfwevt_debug_print_value_type(
5688
     xml_value_type );
5689
    libcnotify_printf(
5690
     ")\n" );
5691
  }
5692
#endif
5693
135k
  xml_token->size     = 4;
5694
135k
  binary_data_offset += 4;
5695
5696
135k
  switch( xml_value_type )
5697
135k
  {
5698
135k
    case LIBFWEVT_VALUE_TYPE_STRING_UTF16:
5699
135k
      byte_stream_copy_to_uint16_little_endian(
5700
135k
       &( xml_document_data[ 2 ] ),
5701
135k
       value_data_size );
5702
5703
#if defined( HAVE_DEBUG_OUTPUT )
5704
      if( libcnotify_verbose != 0 )
5705
      {
5706
        libcnotify_printf(
5707
         "%s: number of characters\t\t\t: %" PRIzd "\n",
5708
         function,
5709
         value_data_size );
5710
      }
5711
#endif
5712
135k
      value_data_size *= 2;
5713
5714
135k
      value_encoding = LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN;
5715
135k
      value_type     = LIBFVALUE_VALUE_TYPE_STRING_UTF16;
5716
5717
135k
      break;
5718
5719
38
    default:
5720
38
      libcerror_error_set(
5721
38
       error,
5722
38
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5723
38
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5724
38
       "%s: unsupported value type: 0x%02" PRIx8 ".",
5725
38
       function,
5726
38
       value_type );
5727
5728
38
      return( -1 );
5729
135k
  }
5730
135k
  if( ( value_data_size > binary_data_size )
5731
135k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
5732
111
  {
5733
111
    libcerror_error_set(
5734
111
     error,
5735
111
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5736
111
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5737
111
     "%s: invalid value data size value out of bounds.",
5738
111
     function );
5739
5740
111
    return( -1 );
5741
111
  }
5742
#if defined( HAVE_DEBUG_OUTPUT )
5743
  if( libcnotify_verbose != 0 )
5744
  {
5745
    libcnotify_printf(
5746
     "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
5747
     function,
5748
     binary_data_offset );
5749
5750
    libcnotify_printf(
5751
     "%s: value data:\n",
5752
     function );
5753
    libcnotify_print_data(
5754
     &( binary_data[ binary_data_offset ] ),
5755
     value_data_size,
5756
     0 );
5757
  }
5758
#endif
5759
135k
  if( libfwevt_xml_tag_set_value_type(
5760
135k
       xml_tag,
5761
135k
       value_type,
5762
135k
       error ) != 1 )
5763
3
  {
5764
3
    libcerror_error_set(
5765
3
     error,
5766
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5767
3
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5768
3
     "%s: unable to set value type.",
5769
3
     function );
5770
5771
3
    return( -1 );
5772
3
  }
5773
135k
  if( libfwevt_xml_tag_append_value_data(
5774
135k
       xml_tag,
5775
135k
       &( binary_data[ binary_data_offset ] ),
5776
135k
       value_data_size,
5777
135k
       value_encoding,
5778
135k
       &value_entry_index,
5779
135k
       error ) != 1 )
5780
6
  {
5781
6
    libcerror_error_set(
5782
6
     error,
5783
6
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5784
6
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
5785
6
     "%s: unable to append value data.",
5786
6
     function );
5787
5788
6
    return( -1 );
5789
6
  }
5790
#if defined( HAVE_DEBUG_OUTPUT )
5791
  if( libcnotify_verbose != 0 )
5792
  {
5793
    if( libfwevt_xml_tag_value_debug_print(
5794
         xml_tag,
5795
         value_entry_index,
5796
         error ) != 1 )
5797
    {
5798
      libcerror_error_set(
5799
       error,
5800
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5801
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
5802
       "%s: unable to print value: %d.",
5803
       function,
5804
       value_entry_index );
5805
5806
      return( -1 );
5807
    }
5808
  }
5809
#endif
5810
135k
  xml_token->size += value_data_size;
5811
  
5812
135k
  return( 1 );
5813
135k
}
5814
5815
/* Substitutes a substitution placeholder with a template value
5816
 * Returns 1 if successful, 0 if no substitution or -1 on error
5817
 */
5818
int libfwevt_xml_document_substitute_template_value(
5819
     libfwevt_internal_xml_document_t *internal_xml_document,
5820
     const uint8_t *binary_data,
5821
     size_t binary_data_size,
5822
     int ascii_codepage,
5823
     uint8_t flags,
5824
     libcdata_array_t *template_values_array,
5825
     uint16_t template_value_index,
5826
     uint8_t template_value_type,
5827
     size_t *template_value_offset,
5828
     libfwevt_xml_tag_t *xml_tag,
5829
     int element_recursion_depth,
5830
     int template_instance_recursion_depth,
5831
     libcerror_error_t **error )
5832
509k
{
5833
509k
  libfwevt_xml_template_value_t *template_value = NULL;
5834
509k
  libfwevt_xml_token_t *xml_sub_token           = NULL;
5835
509k
  const uint8_t *template_value_data            = NULL;
5836
509k
  static char *function                         = "libfwevt_xml_document_substitute_template_value";
5837
509k
  size_t binary_data_offset                     = 0;
5838
509k
  size_t safe_template_value_offset             = 0;
5839
509k
  size_t template_value_data_size               = 0;
5840
509k
  size_t template_value_size                    = 0;
5841
509k
  ssize_t read_count                            = 0;
5842
509k
  uint32_t value_format_flags                   = 0;
5843
509k
  uint16_t substitution_value_data_size         = 0;
5844
509k
  uint8_t substitution_value_type               = 0;
5845
509k
  uint8_t template_value_flags                  = 0;
5846
509k
  int value_encoding                            = 0;
5847
509k
  int value_type                                = 0;
5848
5849
509k
  if( internal_xml_document == NULL )
5850
0
  {
5851
0
    libcerror_error_set(
5852
0
     error,
5853
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5854
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5855
0
     "%s: invalid binary XML document.",
5856
0
     function );
5857
5858
0
    return( -1 );
5859
0
  }
5860
509k
  if( template_value_offset == NULL )
5861
0
  {
5862
0
    libcerror_error_set(
5863
0
     error,
5864
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5865
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5866
0
     "%s: invalid template value offset.",
5867
0
     function );
5868
5869
0
    return( -1 );
5870
0
  }
5871
509k
  if( xml_tag == NULL )
5872
0
  {
5873
0
    libcerror_error_set(
5874
0
     error,
5875
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5876
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5877
0
     "%s: invalid XML tag.",
5878
0
     function );
5879
5880
0
    return( -1 );
5881
0
  }
5882
509k
  if( libcdata_array_get_entry_by_index(
5883
509k
       template_values_array,
5884
509k
       (int) template_value_index,
5885
509k
       (intptr_t **) &template_value,
5886
509k
       error ) != 1 )
5887
188
  {
5888
188
    libcerror_error_set(
5889
188
     error,
5890
188
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5891
188
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5892
188
     "%s: unable to retrieve template value: %" PRIu16 " from array.",
5893
188
     function,
5894
188
     template_value_index );
5895
5896
188
    goto on_error;
5897
188
  }
5898
508k
  if( libfwevt_xml_template_value_get_flags(
5899
508k
       template_value,
5900
508k
       &template_value_flags,
5901
508k
       error ) != 1 )
5902
0
  {
5903
0
    libcerror_error_set(
5904
0
     error,
5905
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5906
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5907
0
     "%s: unable to retrieve template value flags.",
5908
0
     function );
5909
5910
0
    goto on_error;
5911
0
  }
5912
508k
  if( ( template_value_flags & LIBFWEVT_XML_TEMPLATE_VALUE_FLAG_IS_DEFINITION ) != 0 )
5913
0
  {
5914
0
    substitution_value_type = LIBFWEVT_VALUE_TYPE_STRING_UTF16;
5915
0
  }
5916
508k
  else
5917
508k
  {
5918
508k
    if( libfwevt_xml_template_value_get_type(
5919
508k
         template_value,
5920
508k
         &substitution_value_type,
5921
508k
         error ) != 1 )
5922
0
    {
5923
0
      libcerror_error_set(
5924
0
       error,
5925
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5926
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5927
0
       "%s: unable to retrieve template value type.",
5928
0
       function );
5929
5930
0
      goto on_error;
5931
0
    }
5932
508k
  }
5933
508k
  if( libfwevt_xml_template_value_get_offset(
5934
508k
       template_value,
5935
508k
       &binary_data_offset,
5936
508k
       error ) != 1 )
5937
0
  {
5938
0
    libcerror_error_set(
5939
0
     error,
5940
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5941
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5942
0
     "%s: unable to retrieve template value data offset.",
5943
0
     function );
5944
5945
0
    goto on_error;
5946
0
  }
5947
508k
  if( libfwevt_xml_template_value_get_size(
5948
508k
       template_value,
5949
508k
       &substitution_value_data_size,
5950
508k
       error ) != 1 )
5951
0
  {
5952
0
    libcerror_error_set(
5953
0
     error,
5954
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5955
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5956
0
     "%s: unable to retrieve template value data size.",
5957
0
     function );
5958
5959
0
    goto on_error;
5960
0
  }
5961
#if defined( HAVE_DEBUG_OUTPUT )
5962
  if( libcnotify_verbose != 0 )
5963
  {
5964
    libcnotify_printf(
5965
     "%s: value: %02" PRIu32 " offset\t: 0x%08" PRIzx "\n",
5966
     function,
5967
     template_value_index,
5968
     binary_data_offset );
5969
5970
    libcnotify_printf(
5971
     "%s: value: %02" PRIu32 " size\t\t: %" PRIu16 "\n",
5972
     function,
5973
     template_value_index,
5974
     substitution_value_data_size );
5975
5976
    libcnotify_printf(
5977
     "%s: value: %02" PRIu32 " type\t\t: 0x%02" PRIx8 " (",
5978
     function,
5979
     template_value_index,
5980
     substitution_value_type );
5981
    libfwevt_debug_print_value_type(
5982
     substitution_value_type );
5983
    libcnotify_printf(
5984
     ")\n" );
5985
5986
    libcnotify_printf(
5987
     "%s: value: %02" PRIu32 " data:\n",
5988
     function,
5989
     template_value_index );
5990
    libcnotify_print_data(
5991
     &( binary_data[ binary_data_offset ] ),
5992
     substitution_value_data_size,
5993
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
5994
5995
    libcnotify_printf(
5996
     "\n" );
5997
  }
5998
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5999
6000
  /* No substitution
6001
   */
6002
508k
  if( substitution_value_type == LIBFWEVT_VALUE_TYPE_NULL )
6003
14.6k
  {
6004
14.6k
    *template_value_offset = 0;
6005
6006
14.6k
    return( 0 );
6007
14.6k
  }
6008
#if defined( HAVE_VERBOSE_OUTPUT )
6009
  if( template_value_type != substitution_value_type )
6010
  {
6011
    /* The size type can be substituded by a 32-bit or 64-bit hexadecimal integer
6012
     * The same applies to it's array type
6013
     */
6014
    if( ( ( template_value_type & 0x7f ) != LIBFWEVT_VALUE_TYPE_SIZE )
6015
     || ( ( ( substitution_value_type & 0x7f ) != LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_32BIT )
6016
      &&  ( ( substitution_value_type & 0x7f ) != LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_64BIT ) ) )
6017
    {
6018
      if( libcnotify_verbose != 0 )
6019
      {
6020
        libcnotify_printf(
6021
         "%s: mismatch in value type ( 0x%02" PRIx8 " != 0x%02" PRIx8 " ).\n",
6022
         function,
6023
         template_value_type,
6024
         substitution_value_type );
6025
      }
6026
    }
6027
  }
6028
#endif /* defined( HAVE_VERBOSE_OUTPUT ) */
6029
6030
494k
  if( substitution_value_type == LIBFWEVT_VALUE_TYPE_BINARY_XML )
6031
34.6k
  {
6032
34.6k
    if( libfwevt_xml_token_initialize(
6033
34.6k
         &xml_sub_token,
6034
34.6k
         error ) != 1 )
6035
0
    {
6036
0
      libcerror_error_set(
6037
0
       error,
6038
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6039
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6040
0
       "%s: unable to create binary XML sub token.",
6041
0
       function );
6042
6043
0
      goto on_error;
6044
0
    }
6045
34.6k
    if( libfwevt_xml_token_read_data(
6046
34.6k
         xml_sub_token,
6047
34.6k
         binary_data,
6048
34.6k
         binary_data_size,
6049
34.6k
         binary_data_offset,
6050
34.6k
         error ) != 1 )
6051
3
    {
6052
3
      libcerror_error_set(
6053
3
       error,
6054
3
       LIBCERROR_ERROR_DOMAIN_IO,
6055
3
       LIBCERROR_IO_ERROR_READ_FAILED,
6056
3
       "%s: unable to read binary XML sub token.",
6057
3
       function );
6058
6059
3
      goto on_error;
6060
3
    }
6061
34.6k
    switch( xml_sub_token->type & 0xbf )
6062
34.6k
    {
6063
27.2k
      case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
6064
27.2k
        if( libfwevt_xml_document_read_element(
6065
27.2k
             internal_xml_document,
6066
27.2k
             xml_sub_token,
6067
27.2k
             binary_data,
6068
27.2k
             binary_data_size,
6069
27.2k
             binary_data_offset,
6070
27.2k
             ascii_codepage,
6071
27.2k
             flags & ~( LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DEPENDENCY_IDENTIFIERS ),
6072
27.2k
             template_values_array,
6073
27.2k
             xml_tag,
6074
27.2k
             element_recursion_depth + 1,
6075
27.2k
             template_instance_recursion_depth,
6076
27.2k
             error ) != 1 )
6077
21.2k
        {
6078
21.2k
          libcerror_error_set(
6079
21.2k
           error,
6080
21.2k
           LIBCERROR_ERROR_DOMAIN_IO,
6081
21.2k
           LIBCERROR_IO_ERROR_READ_FAILED,
6082
21.2k
           "%s: unable to read element.",
6083
21.2k
           function );
6084
6085
21.2k
          goto on_error;
6086
21.2k
        }
6087
6.01k
        break;
6088
6089
6.01k
      case LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER:
6090
5.52k
        if( libfwevt_xml_document_read_fragment(
6091
5.52k
             internal_xml_document,
6092
5.52k
             xml_sub_token,
6093
5.52k
             binary_data,
6094
5.52k
             binary_data_size,
6095
5.52k
             binary_data_offset,
6096
5.52k
             ascii_codepage,
6097
5.52k
             flags,
6098
5.52k
             NULL,
6099
5.52k
             xml_tag,
6100
5.52k
             element_recursion_depth,
6101
5.52k
             template_instance_recursion_depth,
6102
5.52k
             error ) != 1 )
6103
3.24k
        {
6104
3.24k
          libcerror_error_set(
6105
3.24k
           error,
6106
3.24k
           LIBCERROR_ERROR_DOMAIN_IO,
6107
3.24k
           LIBCERROR_IO_ERROR_READ_FAILED,
6108
3.24k
           "%s: unable to read fragment header.",
6109
3.24k
           function );
6110
6111
3.24k
          goto on_error;
6112
3.24k
        }
6113
2.27k
        break;
6114
6115
2.27k
      case LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE:
6116
1.85k
        if( libfwevt_xml_document_read_template_instance(
6117
1.85k
             internal_xml_document,
6118
1.85k
             xml_sub_token,
6119
1.85k
             binary_data,
6120
1.85k
             binary_data_size,
6121
1.85k
             binary_data_offset,
6122
1.85k
             ascii_codepage,
6123
1.85k
             flags,
6124
1.85k
             xml_tag,
6125
1.85k
             element_recursion_depth,
6126
1.85k
             template_instance_recursion_depth + 1,
6127
1.85k
             error ) != 1 )
6128
429
        {
6129
429
          libcerror_error_set(
6130
429
           error,
6131
429
           LIBCERROR_ERROR_DOMAIN_IO,
6132
429
           LIBCERROR_IO_ERROR_READ_FAILED,
6133
429
           "%s: unable to read document template instance.",
6134
429
           function );
6135
6136
429
          goto on_error;
6137
429
        }
6138
1.42k
        break;
6139
6140
1.42k
      default:
6141
9
        libcerror_error_set(
6142
9
         error,
6143
9
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6144
9
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6145
9
         "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
6146
9
         function,
6147
9
         xml_sub_token->type );
6148
6149
9
        goto on_error;
6150
34.6k
    }
6151
9.71k
    if( libfwevt_xml_token_free(
6152
9.71k
         &xml_sub_token,
6153
9.71k
         error ) != 1 )
6154
0
    {
6155
0
      libcerror_error_set(
6156
0
       error,
6157
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6158
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
6159
0
       "%s: unable to free binary XML sub token.",
6160
0
       function );
6161
6162
0
      goto on_error;
6163
0
    }
6164
9.71k
  }
6165
459k
  else
6166
459k
  {
6167
/* TODO for now the array types are kept separate to find undocumented values
6168
 * when done apply ( substitution_value_type & 0x7f ) and remove the array types
6169
 */
6170
459k
    switch( substitution_value_type )
6171
459k
    {
6172
3.24k
      case LIBFWEVT_VALUE_TYPE_STRING_UTF16:
6173
13.4k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_UTF16:
6174
13.4k
        value_encoding = LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN;
6175
13.4k
        value_type     = LIBFVALUE_VALUE_TYPE_STRING_UTF16;
6176
13.4k
        break;
6177
6178
718
      case LIBFWEVT_VALUE_TYPE_STRING_BYTE_STREAM:
6179
17.0k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_BYTE_STREAM:
6180
17.0k
        value_encoding = ascii_codepage;
6181
17.0k
        value_type     = LIBFVALUE_VALUE_TYPE_STRING_BYTE_STREAM;
6182
17.0k
        break;
6183
6184
1.01k
      case LIBFWEVT_VALUE_TYPE_INTEGER_8BIT:
6185
15.2k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_8BIT:
6186
15.2k
        template_value_size = 1;
6187
15.2k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6188
15.2k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_SIGNED;
6189
15.2k
        value_type          = LIBFVALUE_VALUE_TYPE_INTEGER_8BIT;
6190
15.2k
        break;
6191
6192
15.1k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_8BIT:
6193
345k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_8BIT:
6194
345k
        template_value_size = 1;
6195
345k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6196
345k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_UNSIGNED;
6197
345k
        value_type          = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_8BIT;
6198
345k
        break;
6199
6200
957
      case LIBFWEVT_VALUE_TYPE_INTEGER_16BIT:
6201
2.17k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_16BIT:
6202
2.17k
        template_value_size = 2;
6203
2.17k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6204
2.17k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_SIGNED;
6205
2.17k
        value_type          = LIBFVALUE_VALUE_TYPE_INTEGER_16BIT;
6206
2.17k
        break;
6207
6208
11.0k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_16BIT:
6209
11.8k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_16BIT:
6210
11.8k
        template_value_size = 2;
6211
11.8k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6212
11.8k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_UNSIGNED;
6213
11.8k
        value_type          = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_16BIT;
6214
11.8k
        break;
6215
6216
561
      case LIBFWEVT_VALUE_TYPE_INTEGER_32BIT:
6217
1.53k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_32BIT:
6218
1.53k
        template_value_size = 4;
6219
1.53k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6220
1.53k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_SIGNED;
6221
1.53k
        value_type          = LIBFVALUE_VALUE_TYPE_INTEGER_32BIT;
6222
1.53k
        break;
6223
6224
7.71k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_32BIT:
6225
8.55k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_32BIT:
6226
8.55k
        template_value_size = 4;
6227
8.55k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6228
8.55k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_UNSIGNED;
6229
8.55k
        value_type          = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_32BIT;
6230
8.55k
        break;
6231
6232
967
      case LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_32BIT:
6233
1.65k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_HEXADECIMAL_INTEGER_32BIT:
6234
1.65k
        template_value_size = 4;
6235
1.65k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6236
1.65k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL;
6237
1.65k
        value_type          = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_32BIT;
6238
1.65k
        break;
6239
6240
607
      case LIBFWEVT_VALUE_TYPE_INTEGER_64BIT:
6241
1.62k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_64BIT:
6242
1.62k
        template_value_size = 8;
6243
1.62k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6244
1.62k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_SIGNED;
6245
1.62k
        value_type          = LIBFVALUE_VALUE_TYPE_INTEGER_64BIT;
6246
1.62k
        break;
6247
6248
3.93k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_64BIT:
6249
4.78k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_64BIT:
6250
4.78k
        template_value_size = 8;
6251
4.78k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6252
4.78k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_UNSIGNED;
6253
4.78k
        value_type          = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_64BIT;
6254
4.78k
        break;
6255
6256
4.36k
      case LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_64BIT:
6257
4.94k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_HEXADECIMAL_INTEGER_64BIT:
6258
4.94k
        template_value_size = 8;
6259
4.94k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6260
4.94k
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL;
6261
4.94k
        value_type          = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_64BIT;
6262
4.94k
        break;
6263
6264
644
      case LIBFWEVT_VALUE_TYPE_FLOATING_POINT_32BIT:
6265
1.26k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FLOATING_POINT_32BIT:
6266
1.26k
        template_value_size = 4;
6267
1.26k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6268
1.26k
        value_format_flags  = LIBFVALUE_FLOATING_POINT_FORMAT_TYPE_DECIMAL;
6269
1.26k
        value_type          = LIBFVALUE_VALUE_TYPE_FLOATING_POINT_32BIT;
6270
1.26k
        break;
6271
6272
704
      case LIBFWEVT_VALUE_TYPE_FLOATING_POINT_64BIT:
6273
1.42k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FLOATING_POINT_64BIT:
6274
1.42k
        template_value_size = 8;
6275
1.42k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6276
1.42k
        value_format_flags  = LIBFVALUE_FLOATING_POINT_FORMAT_TYPE_DECIMAL;
6277
1.42k
        value_type          = LIBFVALUE_VALUE_TYPE_FLOATING_POINT_64BIT;
6278
1.42k
        break;
6279
6280
685
      case LIBFWEVT_VALUE_TYPE_BOOLEAN:
6281
685
        template_value_size = 4;
6282
685
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6283
685
        value_format_flags  = LIBFVALUE_INTEGER_FORMAT_TYPE_BOOLEAN;
6284
685
        value_type          = LIBFVALUE_VALUE_TYPE_BOOLEAN;
6285
685
        break;
6286
6287
18.8k
      case LIBFWEVT_VALUE_TYPE_BINARY_DATA:
6288
18.8k
        value_format_flags = LIBFVALUE_BINARY_DATA_FORMAT_TYPE_BASE16
6289
18.8k
                           | LIBFVALUE_BINARY_DATA_FORMAT_FLAG_CASE_UPPER;
6290
18.8k
        value_type         = LIBFVALUE_VALUE_TYPE_BINARY_DATA;
6291
18.8k
        break;
6292
6293
578
      case LIBFWEVT_VALUE_TYPE_GUID:
6294
1.18k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_GUID:
6295
1.18k
        template_value_size = 16;
6296
1.18k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6297
1.18k
        value_format_flags  = LIBFVALUE_GUID_FORMAT_FLAG_USE_UPPER_CASE | LIBFVALUE_GUID_FORMAT_FLAG_USE_SURROUNDING_BRACES;
6298
1.18k
        value_type          = LIBFVALUE_VALUE_TYPE_GUID;
6299
1.18k
        break;
6300
6301
/* TODO how to deal with array types ? */
6302
2.02k
      case LIBFWEVT_VALUE_TYPE_SIZE:
6303
2.02k
        value_encoding     = LIBFVALUE_ENDIAN_LITTLE;
6304
2.02k
        value_format_flags = LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_UNSIGNED;
6305
6306
2.02k
        if( substitution_value_data_size == 4 )
6307
603
        {
6308
603
          value_type = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_32BIT;
6309
603
        }
6310
1.42k
        else if( substitution_value_data_size == 8 )
6311
1.38k
        {
6312
1.38k
          value_type = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_64BIT;
6313
1.38k
        }
6314
41
        else
6315
41
        {
6316
41
          libcerror_error_set(
6317
41
           error,
6318
41
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6319
41
           LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6320
41
           "%s: unsupported value data size: %" PRIu16 ".",
6321
41
           function,
6322
41
           substitution_value_data_size );
6323
6324
41
          goto on_error;
6325
41
        }
6326
1.98k
        break;
6327
6328
4.02k
      case LIBFWEVT_VALUE_TYPE_FILETIME:
6329
4.63k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FILETIME:
6330
4.63k
        template_value_size = 8;
6331
4.63k
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6332
4.63k
        value_format_flags  = (uint32_t) ( LIBFVALUE_DATE_TIME_FORMAT_TYPE_ISO8601 | LIBFVALUE_DATE_TIME_FORMAT_FLAG_DATE_TIME_NANO_SECONDS | LIBFVALUE_DATE_TIME_FORMAT_FLAG_TIMEZONE_INDICATOR );
6333
4.63k
        value_type          = LIBFVALUE_VALUE_TYPE_FILETIME;
6334
4.63k
        break;
6335
6336
346
      case LIBFWEVT_VALUE_TYPE_SYSTEMTIME:
6337
945
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_SYSTEMTIME:
6338
945
        template_value_size = 16;
6339
945
        value_encoding      = LIBFVALUE_ENDIAN_LITTLE;
6340
945
        value_format_flags  = (uint32_t) ( LIBFVALUE_DATE_TIME_FORMAT_TYPE_ISO8601 | LIBFVALUE_DATE_TIME_FORMAT_FLAG_DATE_TIME_MILLI_SECONDS | LIBFVALUE_DATE_TIME_FORMAT_FLAG_TIMEZONE_INDICATOR );
6341
945
        value_type          = LIBFVALUE_VALUE_TYPE_SYSTEMTIME;
6342
945
        break;
6343
6344
508
      case LIBFWEVT_VALUE_TYPE_NT_SECURITY_IDENTIFIER:
6345
508
        value_encoding = LIBFVALUE_ENDIAN_LITTLE;
6346
508
        value_type     = LIBFVALUE_VALUE_TYPE_NT_SECURITY_IDENTIFIER;
6347
508
        break;
6348
6349
8
      default:
6350
8
        libcerror_error_set(
6351
8
         error,
6352
8
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6353
8
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6354
8
         "%s: unsupported value type: 0x%02" PRIx8 ".",
6355
8
         function,
6356
8
         substitution_value_type );
6357
6358
8
        goto on_error;
6359
459k
    }
6360
459k
    if( libfwevt_xml_tag_set_value_type(
6361
459k
         xml_tag,
6362
459k
         value_type,
6363
459k
         error ) != 1 )
6364
8
    {
6365
8
      libcerror_error_set(
6366
8
       error,
6367
8
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6368
8
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6369
8
       "%s: unable to set value type.",
6370
8
       function );
6371
6372
8
      goto on_error;
6373
8
    }
6374
459k
    if( value_format_flags != 0 )
6375
428k
    {
6376
428k
      if( libfwevt_xml_tag_set_value_format_flags(
6377
428k
           xml_tag,
6378
428k
           value_format_flags,
6379
428k
           error ) != 1 )
6380
0
      {
6381
0
        libcerror_error_set(
6382
0
         error,
6383
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6384
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6385
0
         "%s: unable to set value format flags.",
6386
0
         function );
6387
6388
0
        goto on_error;
6389
0
      }
6390
428k
    }
6391
459k
    if( ( substitution_value_type & LIBFWEVT_VALUE_TYPE_ARRAY ) != 0 )
6392
381k
    {
6393
381k
      safe_template_value_offset = *template_value_offset;
6394
6395
381k
      if( substitution_value_data_size > 0 )
6396
375k
      {
6397
375k
        if( safe_template_value_offset >= (size_t) substitution_value_data_size )
6398
19
        {
6399
19
          libcerror_error_set(
6400
19
           error,
6401
19
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6402
19
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6403
19
           "%s: invalid template value offset value out of bounds.",
6404
19
           function );
6405
6406
19
          goto on_error;
6407
19
        }
6408
375k
        template_value_data      = &( binary_data[ binary_data_offset + safe_template_value_offset ] );
6409
375k
        template_value_data_size = substitution_value_data_size - (uint16_t) safe_template_value_offset;
6410
375k
      }
6411
      /* An empty XML tag should be created if template_value_data_size == 0
6412
       */
6413
381k
      if( template_value_data_size > 0 )
6414
375k
      {
6415
375k
        if( ( substitution_value_type == LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_BYTE_STREAM )
6416
375k
         || ( substitution_value_type == LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_UTF16 ) )
6417
26.0k
        {
6418
26.0k
          if( ( value_type == LIBFVALUE_VALUE_TYPE_STRING_UTF16 )
6419
26.0k
           && ( ( template_value_data_size % 2 ) != 0 ) )
6420
3
          {
6421
3
            libcerror_error_set(
6422
3
             error,
6423
3
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6424
3
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6425
3
             "%s: invalid UTF-16 template value data size value out of bounds.",
6426
3
             function );
6427
6428
3
            goto on_error;
6429
3
          }
6430
26.0k
          read_count = libfwevt_xml_tag_set_value_strings_array(
6431
26.0k
                  xml_tag,
6432
26.0k
                  template_value_data,
6433
26.0k
                  template_value_data_size,
6434
26.0k
                  value_encoding,
6435
26.0k
                  error );
6436
6437
26.0k
          if( read_count == -1 )
6438
0
          {
6439
0
            libcerror_error_set(
6440
0
             error,
6441
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
6442
0
             LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6443
0
             "%s: unable to set value data.",
6444
0
             function );
6445
6446
0
            goto on_error;
6447
0
          }
6448
26.0k
          safe_template_value_offset += read_count;
6449
26.0k
        }
6450
348k
        else
6451
348k
        {
6452
348k
          if( template_value_size > template_value_data_size )
6453
63
          {
6454
63
            libcerror_error_set(
6455
63
             error,
6456
63
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6457
63
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6458
63
             "%s: invalid template value size value out of bounds.",
6459
63
             function );
6460
6461
63
            goto on_error;
6462
63
          }
6463
348k
          if( libfwevt_xml_tag_set_value_data(
6464
348k
               xml_tag,
6465
348k
               template_value_data,
6466
348k
               template_value_size,
6467
348k
               value_encoding,
6468
348k
               error ) != 1 )
6469
0
          {
6470
0
            libcerror_error_set(
6471
0
             error,
6472
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
6473
0
             LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6474
0
             "%s: unable to set value data.",
6475
0
             function );
6476
6477
0
            goto on_error;
6478
0
          }
6479
348k
          safe_template_value_offset += template_value_size;
6480
348k
        }
6481
375k
      }
6482
380k
      if( safe_template_value_offset == substitution_value_data_size )
6483
17.5k
      {
6484
17.5k
        safe_template_value_offset = 0;
6485
17.5k
      }
6486
380k
    }
6487
78.6k
    else
6488
78.6k
    {
6489
78.6k
      if( ( template_value_size != 0 )
6490
78.6k
       && ( template_value_size != substitution_value_data_size ) )
6491
51
      {
6492
51
        libcerror_error_set(
6493
51
         error,
6494
51
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6495
51
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6496
51
         "%s: invalid substitution value data size value out of bounds.",
6497
51
         function );
6498
6499
51
        goto on_error;
6500
51
      }
6501
78.5k
      else if( ( value_type == LIBFVALUE_VALUE_TYPE_STRING_UTF16 )
6502
78.5k
            && ( ( substitution_value_data_size % 2 ) != 0 ) )
6503
3
      {
6504
3
        libcerror_error_set(
6505
3
         error,
6506
3
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6507
3
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6508
3
         "%s: invalid UTF-16 substitution value data size value out of bounds.",
6509
3
         function );
6510
6511
3
        goto on_error;
6512
3
      }
6513
78.5k
      if( libfwevt_xml_tag_set_value_data(
6514
78.5k
           xml_tag,
6515
78.5k
           &( binary_data[ binary_data_offset ] ),
6516
78.5k
           (size_t) substitution_value_data_size,
6517
78.5k
           value_encoding,
6518
78.5k
           error ) != 1 )
6519
0
      {
6520
0
        libcerror_error_set(
6521
0
         error,
6522
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6523
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6524
0
         "%s: unable to set value data.",
6525
0
         function );
6526
6527
0
        goto on_error;
6528
0
      }
6529
78.5k
    }
6530
459k
    if( libfwevt_xml_tag_set_flags(
6531
459k
         xml_tag,
6532
459k
         LIBFWEVT_XML_TAG_FLAG_IS_TEMPLATE_DEFINITION,
6533
459k
         error ) != 1 )
6534
0
    {
6535
0
      libcerror_error_set(
6536
0
       error,
6537
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6538
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6539
0
       "%s: unable to set flags.",
6540
0
       function );
6541
6542
0
      goto on_error;
6543
0
    }
6544
#if defined( HAVE_DEBUG_OUTPUT )
6545
    if( libcnotify_verbose != 0 )
6546
    {
6547
      if( libfwevt_xml_tag_value_debug_print(
6548
           xml_tag,
6549
           0,
6550
           error ) != 1 )
6551
      {
6552
        libcerror_error_set(
6553
         error,
6554
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6555
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
6556
         "%s: unable to print value.",
6557
         function );
6558
6559
        goto on_error;
6560
      }
6561
    }
6562
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
6563
459k
  }
6564
469k
  *template_value_offset = safe_template_value_offset;
6565
6566
469k
  return( 1 );
6567
6568
25.2k
on_error:
6569
25.2k
  if( xml_sub_token != NULL )
6570
24.8k
  {
6571
24.8k
    libfwevt_xml_token_free(
6572
24.8k
     &xml_sub_token,
6573
24.8k
     NULL );
6574
24.8k
  }
6575
25.2k
  return( -1 );
6576
494k
}
6577
6578
/* Retrieves the size of the UTF-8 formatted string of the XML document
6579
 * Returns 1 if successful or -1 on error
6580
 */
6581
int libfwevt_xml_document_get_utf8_xml_string_size(
6582
     libfwevt_xml_document_t *xml_document,
6583
     size_t *utf8_string_size,
6584
     libcerror_error_t **error )
6585
0
{
6586
0
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
6587
0
  static char *function                                   = "libfwevt_xml_document_get_utf8_xml_string_size";
6588
6589
0
  if( xml_document == NULL )
6590
0
  {
6591
0
    libcerror_error_set(
6592
0
     error,
6593
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6594
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6595
0
     "%s: invalid XML document.",
6596
0
     function );
6597
6598
0
    return( -1 );
6599
0
  }
6600
0
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
6601
6602
0
  if( libfwevt_xml_tag_get_utf8_xml_string_size(
6603
0
       internal_xml_document->root_xml_tag,
6604
0
       0,
6605
0
       utf8_string_size,
6606
0
       error ) != 1 )
6607
0
  {
6608
0
    libcerror_error_set(
6609
0
     error,
6610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6611
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6612
0
     "%s: unable to retrieve size of UTF-8 string of root XML tag.",
6613
0
     function );
6614
6615
0
    return( -1 );
6616
0
  }
6617
0
  return( 1 );
6618
0
}
6619
6620
/* Retrieves the UTF-8 formatted string of the XML document
6621
 * Returns 1 if successful or -1 on error
6622
 */
6623
int libfwevt_xml_document_get_utf8_xml_string(
6624
     libfwevt_xml_document_t *xml_document,
6625
     uint8_t *utf8_string,
6626
     size_t utf8_string_size,
6627
     libcerror_error_t **error )
6628
0
{
6629
0
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
6630
0
  static char *function                                   = "libfwevt_xml_document_get_utf8_xml_string";
6631
0
  size_t utf8_string_index                                = 0;
6632
6633
0
  if( xml_document == NULL )
6634
0
  {
6635
0
    libcerror_error_set(
6636
0
     error,
6637
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6638
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6639
0
     "%s: invalid XML document.",
6640
0
     function );
6641
6642
0
    return( -1 );
6643
0
  }
6644
0
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
6645
6646
0
  if( libfwevt_xml_tag_get_utf8_xml_string_with_index(
6647
0
       internal_xml_document->root_xml_tag,
6648
0
       0,
6649
0
       utf8_string,
6650
0
       utf8_string_size,
6651
0
       &utf8_string_index,
6652
0
       error ) != 1 )
6653
0
  {
6654
0
    libcerror_error_set(
6655
0
     error,
6656
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6657
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6658
0
     "%s: unable to retrieve UTF-8 string of root XML tag.",
6659
0
     function );
6660
6661
0
    return( -1 );
6662
0
  }
6663
0
  return( 1 );
6664
0
}
6665
6666
/* Retrieves the size of the UTF-16 formatted string of the XML document
6667
 * Returns 1 if successful or -1 on error
6668
 */
6669
int libfwevt_xml_document_get_utf16_xml_string_size(
6670
     libfwevt_xml_document_t *xml_document,
6671
     size_t *utf16_string_size,
6672
     libcerror_error_t **error )
6673
0
{
6674
0
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
6675
0
  static char *function                                   = "libfwevt_xml_document_get_utf16_xml_string_size";
6676
6677
0
  if( xml_document == NULL )
6678
0
  {
6679
0
    libcerror_error_set(
6680
0
     error,
6681
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6682
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6683
0
     "%s: invalid XML document.",
6684
0
     function );
6685
6686
0
    return( -1 );
6687
0
  }
6688
0
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
6689
6690
0
  if( libfwevt_xml_tag_get_utf16_xml_string_size(
6691
0
       internal_xml_document->root_xml_tag,
6692
0
       0,
6693
0
       utf16_string_size,
6694
0
       error ) != 1 )
6695
0
  {
6696
0
    libcerror_error_set(
6697
0
     error,
6698
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6699
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6700
0
     "%s: unable to retrieve size of UTF-16 string of root XML tag.",
6701
0
     function );
6702
6703
0
    return( -1 );
6704
0
  }
6705
0
  return( 1 );
6706
0
}
6707
6708
/* Retrieves the UTF-16 formatted string of the XML document
6709
 * Returns 1 if successful or -1 on error
6710
 */
6711
int libfwevt_xml_document_get_utf16_xml_string(
6712
     libfwevt_xml_document_t *xml_document,
6713
     uint16_t *utf16_string,
6714
     size_t utf16_string_size,
6715
     libcerror_error_t **error )
6716
0
{
6717
0
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
6718
0
  static char *function                                   = "libfwevt_xml_document_get_utf16_xml_string";
6719
0
  size_t utf16_string_index                               = 0;
6720
6721
0
  if( xml_document == NULL )
6722
0
  {
6723
0
    libcerror_error_set(
6724
0
     error,
6725
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6726
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6727
0
     "%s: invalid XML document.",
6728
0
     function );
6729
6730
0
    return( -1 );
6731
0
  }
6732
0
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
6733
6734
0
  if( libfwevt_xml_tag_get_utf16_xml_string_with_index(
6735
0
       internal_xml_document->root_xml_tag,
6736
0
       0,
6737
0
       utf16_string,
6738
0
       utf16_string_size,
6739
0
       &utf16_string_index,
6740
0
       error ) != 1 )
6741
0
  {
6742
0
    libcerror_error_set(
6743
0
     error,
6744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6745
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6746
0
     "%s: unable to retrieve UTF-16 string of root XML tag.",
6747
0
     function );
6748
6749
0
    return( -1 );
6750
0
  }
6751
0
  return( 1 );
6752
0
}
6753
6754
#if defined( HAVE_DEBUG_OUTPUT )
6755
6756
/* Debug prints the XML document
6757
 * Returns 1 if successful or -1 on error
6758
 */
6759
int libfwevt_xml_document_debug_print(
6760
     libfwevt_xml_document_t *xml_document,
6761
     libcerror_error_t **error )
6762
{
6763
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
6764
  static char *function                                   = "libfwevt_xml_document_print";
6765
6766
  if( xml_document == NULL )
6767
  {
6768
    libcerror_error_set(
6769
     error,
6770
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6771
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6772
     "%s: invalid binary XML document.",
6773
     function );
6774
6775
    return( -1 );
6776
  }
6777
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
6778
6779
  if( libfwevt_xml_tag_debug_print(
6780
       internal_xml_document->root_xml_tag,
6781
       0,
6782
       error ) != 1 )
6783
  {
6784
    libcerror_error_set(
6785
     error,
6786
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6787
     LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
6788
     "%s: unable to print root XML tag.",
6789
     function );
6790
6791
    return( -1 );
6792
  }
6793
  return( 1 );
6794
}
6795
6796
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
6797