Coverage Report

Created: 2025-08-28 07:10

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