Coverage Report

Created: 2024-06-12 07:07

/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.85k
{
49
4.85k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
50
4.85k
  static char *function                                   = "libfwevt_xml_document_initialize";
51
52
4.85k
  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.85k
  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.85k
  internal_xml_document = memory_allocate_structure(
75
4.85k
                           libfwevt_internal_xml_document_t );
76
77
4.85k
  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.85k
  if( memory_set(
89
4.85k
       internal_xml_document,
90
4.85k
       0,
91
4.85k
       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.85k
  *xml_document = (libfwevt_xml_document_t *) internal_xml_document;
103
104
4.85k
  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.85k
}
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.85k
{
122
4.85k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
123
4.85k
  static char *function                                   = "libfwevt_xml_document_free";
124
4.85k
  int result                                              = 1;
125
126
4.85k
  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.85k
  if( *xml_document != NULL )
138
4.85k
  {
139
4.85k
    internal_xml_document = (libfwevt_internal_xml_document_t *) *xml_document;
140
4.85k
    *xml_document         = NULL;
141
142
4.85k
    if( internal_xml_document->root_xml_tag != NULL )
143
571
    {
144
571
      if( libfwevt_internal_xml_tag_free(
145
571
           (libfwevt_internal_xml_tag_t **) &( internal_xml_document->root_xml_tag ),
146
571
           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
571
    }
158
4.85k
    memory_free(
159
4.85k
     internal_xml_document );
160
4.85k
  }
161
4.85k
  return( result );
162
4.85k
}
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.85k
{
216
4.85k
  static char *function = "libfwevt_xml_document_read";
217
218
4.85k
  if( libfwevt_xml_document_read_with_template_values(
219
4.85k
       xml_document,
220
4.85k
       binary_data,
221
4.85k
       binary_data_size,
222
4.85k
       binary_data_offset,
223
4.85k
       ascii_codepage,
224
4.85k
       flags,
225
4.85k
       NULL,
226
4.85k
       error ) != 1 )
227
4.74k
  {
228
4.74k
    libcerror_error_set(
229
4.74k
     error,
230
4.74k
     LIBCERROR_ERROR_DOMAIN_IO,
231
4.74k
     LIBCERROR_IO_ERROR_READ_FAILED,
232
4.74k
     "%s: unable to read XML document.",
233
4.74k
     function );
234
235
4.74k
    return( -1 );
236
4.74k
  }
237
115
  return( 1 );
238
4.85k
}
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.85k
{
253
4.85k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
254
4.85k
  libfwevt_xml_token_t *xml_token                         = NULL;
255
4.85k
  static char *function                                   = "libfwevt_xml_document_read_with_template_values";
256
4.85k
  uint8_t supported_flags                                 = 0;
257
258
4.85k
  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.85k
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
270
271
4.85k
  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.85k
  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.85k
  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.85k
  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.85k
  supported_flags = LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS
316
4.85k
                  | LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DEPENDENCY_IDENTIFIERS;
317
318
4.85k
  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.85k
  if( libfwevt_xml_token_initialize(
331
4.85k
       &xml_token,
332
4.85k
       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
18.3k
  while( binary_data_offset < binary_data_size )
344
18.3k
  {
345
18.3k
    if( libfwevt_xml_token_read_data(
346
18.3k
         xml_token,
347
18.3k
         binary_data,
348
18.3k
         binary_data_size,
349
18.3k
         binary_data_offset,
350
18.3k
         error ) != 1 )
351
37
    {
352
37
      libcerror_error_set(
353
37
       error,
354
37
       LIBCERROR_ERROR_DOMAIN_IO,
355
37
       LIBCERROR_IO_ERROR_READ_FAILED,
356
37
       "%s: unable to read binary XML token.",
357
37
       function );
358
359
37
      goto on_error;
360
37
    }
361
/* TODO check for prologue */
362
/* TODO validate the order */
363
/* TODO check for Miscellaneous before end of file token */
364
18.3k
    switch( xml_token->type & 0xbf )
365
18.3k
    {
366
128
      case LIBFWEVT_XML_TOKEN_END_OF_FILE:
367
128
        if( ( binary_data_size < 1 )
368
128
         || ( binary_data_offset >= ( binary_data_size - 1 ) ) )
369
15
        {
370
15
          libcerror_error_set(
371
15
           error,
372
15
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
373
15
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
374
15
           "%s: invalid binary XML document data size value too small.",
375
15
           function );
376
377
15
          goto on_error;
378
15
        }
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
113
        xml_token->size = 1;
409
410
113
        break;
411
412
18.1k
      case LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER:
413
18.1k
        if( libfwevt_xml_document_read_fragment(
414
18.1k
             internal_xml_document,
415
18.1k
             xml_token,
416
18.1k
             binary_data,
417
18.1k
             binary_data_size,
418
18.1k
             binary_data_offset,
419
18.1k
             ascii_codepage,
420
18.1k
             flags,
421
18.1k
             template_values_array,
422
18.1k
             internal_xml_document->root_xml_tag,
423
18.1k
             0,
424
18.1k
             0,
425
18.1k
             error ) != 1 )
426
4.62k
        {
427
4.62k
          libcerror_error_set(
428
4.62k
           error,
429
4.62k
           LIBCERROR_ERROR_DOMAIN_IO,
430
4.62k
           LIBCERROR_IO_ERROR_READ_FAILED,
431
4.62k
           "%s: unable to read fragment header.",
432
4.62k
           function );
433
434
4.62k
          goto on_error;
435
4.62k
        }
436
13.5k
        break;
437
438
13.5k
      default:
439
62
        libcerror_error_set(
440
62
         error,
441
62
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
442
62
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
443
62
         "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
444
62
         function,
445
62
         xml_token->type );
446
447
62
        goto on_error;
448
18.3k
    }
449
13.6k
    internal_xml_document->size += xml_token->size;
450
13.6k
    binary_data_offset          += xml_token->size;
451
452
13.6k
    if( xml_token->type == LIBFWEVT_XML_TOKEN_END_OF_FILE )
453
113
    {
454
113
      break;
455
113
    }
456
13.6k
  }
457
115
  if( libfwevt_xml_token_free(
458
115
       &xml_token,
459
115
       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
115
  return( 1 );
471
472
4.74k
on_error:
473
4.74k
  if( xml_token != NULL )
474
4.74k
  {
475
4.74k
    libfwevt_xml_token_free(
476
4.74k
     &xml_token,
477
4.74k
     NULL );
478
4.74k
  }
479
4.74k
  return( -1 );
480
115
}
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
802k
{
499
802k
  libfwevt_xml_tag_t *attribute_xml_tag    = NULL;
500
802k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
501
802k
  const uint8_t *xml_document_data         = NULL;
502
802k
  static char *function                    = "libfwevt_xml_document_read_attribute";
503
802k
  size_t additional_value_size             = 0;
504
802k
  size_t template_value_offset             = 0;
505
802k
  size_t trailing_data_size                = 0;
506
802k
  size_t xml_document_data_offset          = 0;
507
802k
  size_t xml_document_data_size            = 0;
508
802k
  uint32_t attribute_name_offset           = 0;
509
802k
  uint32_t attribute_name_size             = 0;
510
802k
  int result                               = 0;
511
802k
  int template_value_array_recursion_depth = 0;
512
513
802k
  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
802k
  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
802k
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_ATTRIBUTE )
536
37
  {
537
37
    libcerror_error_set(
538
37
     error,
539
37
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
540
37
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
541
37
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
542
37
     function,
543
37
     xml_token->type );
544
545
37
    return( -1 );
546
37
  }
547
802k
  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
802k
  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
802k
  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
802k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
581
802k
  {
582
802k
    additional_value_size = 4;
583
584
802k
    if( ( binary_data_size < 4 )
585
802k
     || ( binary_data_offset > ( binary_data_size - 4 ) ) )
586
6
    {
587
6
      libcerror_error_set(
588
6
       error,
589
6
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
590
6
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
591
6
       "%s: invalid binary data offset value out of bounds.",
592
6
       function );
593
594
6
      return( -1 );
595
6
    }
596
802k
  }
597
802k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
598
802k
  xml_document_data_size = binary_data_size - binary_data_offset;
599
600
802k
  if( libfwevt_xml_token_initialize(
601
802k
       &xml_sub_token,
602
802k
       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
802k
  do
614
803k
  {
615
803k
    if( ( template_value_array_recursion_depth < 0 )
616
803k
     || ( template_value_array_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_VALUE_ARRAY_RECURSION_DEPTH ) )
617
1
    {
618
1
      libcerror_error_set(
619
1
       error,
620
1
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
621
1
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
622
1
       "%s: invalid template value array recursion depth value out of bounds.",
623
1
       function );
624
625
1
      goto on_error;
626
1
    }
627
803k
    if( ( xml_document_data_size < ( additional_value_size + 1 ) )
628
803k
     || ( xml_document_data_offset > ( xml_document_data_size - ( additional_value_size + 1 ) ) ) )
629
18
    {
630
18
      libcerror_error_set(
631
18
       error,
632
18
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
633
18
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
634
18
       "%s: invalid binary XML document data size value too small.",
635
18
       function );
636
637
18
      goto on_error;
638
18
    }
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
803k
    xml_document_data_offset += 1;
666
667
803k
    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
803k
    else
672
803k
    {
673
803k
      if( ( xml_document_data_size < 4 )
674
803k
       || ( 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
803k
      byte_stream_copy_to_uint32_little_endian(
686
803k
       &( xml_document_data[ xml_document_data_offset ] ),
687
803k
       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
803k
      xml_document_data_offset += 4;
699
803k
    }
700
#if defined( HAVE_DEBUG_OUTPUT )
701
    if( libcnotify_verbose != 0 )
702
    {
703
      libcnotify_printf(
704
       "\n" );
705
    }
706
#endif
707
803k
    if( attribute_name_offset > ( binary_data_offset + xml_document_data_offset ) )
708
184
    {
709
184
      libcerror_error_set(
710
184
       error,
711
184
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
712
184
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
713
184
       "%s: invalid attribute data offset value out of bounds.",
714
184
       function );
715
716
184
      goto on_error;
717
184
    }
718
803k
    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
803k
    if( libfwevt_xml_tag_initialize(
742
803k
         &attribute_xml_tag,
743
803k
         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
803k
    if( libfwevt_xml_document_read_name(
755
803k
         internal_xml_document,
756
803k
         binary_data,
757
803k
         binary_data_size,
758
803k
         attribute_name_offset,
759
803k
         flags,
760
803k
         &attribute_name_size,
761
803k
         attribute_xml_tag,
762
803k
         error ) != 1 )
763
9
    {
764
9
      libcerror_error_set(
765
9
       error,
766
9
       LIBCERROR_ERROR_DOMAIN_IO,
767
9
       LIBCERROR_IO_ERROR_READ_FAILED,
768
9
       "%s: unable to read attribute name.",
769
9
       function );
770
771
9
      goto on_error;
772
9
    }
773
803k
    if( ( binary_data_offset + xml_document_data_offset ) == attribute_name_offset )
774
75.9k
    {
775
75.9k
      xml_document_data_offset += attribute_name_size;
776
75.9k
    }
777
803k
    if( libfwevt_xml_token_read_data(
778
803k
         xml_sub_token,
779
803k
         binary_data,
780
803k
         binary_data_size,
781
803k
         binary_data_offset + xml_document_data_offset,
782
803k
         error ) != 1 )
783
17
    {
784
17
      libcerror_error_set(
785
17
       error,
786
17
       LIBCERROR_ERROR_DOMAIN_IO,
787
17
       LIBCERROR_IO_ERROR_READ_FAILED,
788
17
       "%s: unable to read binary XML sub token.",
789
17
       function );
790
791
17
      goto on_error;
792
17
    }
793
803k
    result = 1;
794
795
803k
    switch( xml_sub_token->type & 0xbf )
796
803k
    {
797
285k
      case LIBFWEVT_XML_TOKEN_VALUE:
798
285k
        if( template_value_offset != 0 )
799
3
        {
800
3
          libcerror_error_set(
801
3
           error,
802
3
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
803
3
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
804
3
           "%s: invalid template value offset value out of bounds.",
805
3
           function );
806
807
3
          goto on_error;
808
3
        }
809
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
46
        {
818
46
          libcerror_error_set(
819
46
           error,
820
46
           LIBCERROR_ERROR_DOMAIN_IO,
821
46
           LIBCERROR_IO_ERROR_READ_FAILED,
822
46
           "%s: unable to read value.",
823
46
           function );
824
825
46
          goto on_error;
826
46
        }
827
285k
        break;
828
829
285k
      case LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION:
830
72.6k
        result = libfwevt_xml_document_read_normal_substitution(
831
72.6k
                  internal_xml_document,
832
72.6k
                  xml_sub_token,
833
72.6k
                  binary_data,
834
72.6k
                  binary_data_size,
835
72.6k
                  binary_data_offset + xml_document_data_offset,
836
72.6k
                  ascii_codepage,
837
72.6k
                  flags,
838
72.6k
                  template_values_array,
839
72.6k
                  &template_value_offset,
840
72.6k
                  attribute_xml_tag,
841
72.6k
                  element_recursion_depth,
842
72.6k
                  template_instance_recursion_depth,
843
72.6k
                  error );
844
845
72.6k
        if( result == -1 )
846
1.82k
        {
847
1.82k
          libcerror_error_set(
848
1.82k
           error,
849
1.82k
           LIBCERROR_ERROR_DOMAIN_IO,
850
1.82k
           LIBCERROR_IO_ERROR_READ_FAILED,
851
1.82k
           "%s: unable to read normal substitution.",
852
1.82k
           function );
853
854
1.82k
          goto on_error;
855
1.82k
        }
856
70.8k
        break;
857
858
445k
      case LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION:
859
445k
        result = libfwevt_xml_document_read_optional_substitution(
860
445k
            internal_xml_document,
861
445k
            xml_sub_token,
862
445k
            binary_data,
863
445k
            binary_data_size,
864
445k
            binary_data_offset + xml_document_data_offset,
865
445k
            ascii_codepage,
866
445k
            flags,
867
445k
            template_values_array,
868
445k
            &template_value_offset,
869
445k
            attribute_xml_tag,
870
445k
                  element_recursion_depth,
871
445k
                  template_instance_recursion_depth,
872
445k
            error );
873
874
445k
        if( result == -1 )
875
1.44k
        {
876
1.44k
          libcerror_error_set(
877
1.44k
           error,
878
1.44k
           LIBCERROR_ERROR_DOMAIN_IO,
879
1.44k
           LIBCERROR_IO_ERROR_READ_FAILED,
880
1.44k
           "%s: unable to read optional substitution.",
881
1.44k
           function );
882
883
1.44k
          goto on_error;
884
1.44k
        }
885
443k
        break;
886
887
443k
      default:
888
33
        libcerror_error_set(
889
33
         error,
890
33
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
891
33
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
892
33
         "%s: invalid binary XML sub token - unsupported type: 0x%02" PRIx8 ".",
893
33
         function,
894
33
         xml_sub_token->type );
895
896
33
        goto on_error;
897
803k
    }
898
800k
    if( result != 0 )
899
693k
    {
900
693k
      if( libfwevt_xml_tag_append_attribute(
901
693k
           xml_tag,
902
693k
           attribute_xml_tag,
903
693k
           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
693k
      attribute_xml_tag = NULL;
915
693k
    }
916
800k
    xml_document_data_offset += xml_sub_token->size;
917
918
800k
    template_value_array_recursion_depth++;
919
800k
  }
920
802k
  while( template_value_offset > 0 );
921
922
798k
  xml_token->size = xml_document_data_offset;
923
924
798k
  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
798k
  if( libfwevt_xml_token_free(
941
798k
       &xml_sub_token,
942
798k
       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
798k
  return( 1 );
954
955
3.59k
on_error:
956
3.59k
  if( attribute_xml_tag != NULL )
957
3.38k
  {
958
3.38k
    libfwevt_internal_xml_tag_free(
959
3.38k
     (libfwevt_internal_xml_tag_t **) &attribute_xml_tag,
960
3.38k
     NULL );
961
3.38k
  }
962
3.59k
  if( xml_sub_token != NULL )
963
3.59k
  {
964
3.59k
    libfwevt_xml_token_free(
965
3.59k
     &xml_sub_token,
966
3.59k
     NULL );
967
3.59k
  }
968
3.59k
  return( -1 );
969
798k
}
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
5.12k
{
983
5.12k
  const uint8_t *xml_document_data = NULL;
984
5.12k
  static char *function            = "libfwevt_xml_document_read_cdata_section";
985
5.12k
  size_t value_data_size           = 0;
986
5.12k
  size_t xml_document_data_size    = 0;
987
988
5.12k
  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
5.12k
  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
5.12k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_CDATA_SECTION )
1011
2
  {
1012
2
    libcerror_error_set(
1013
2
     error,
1014
2
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1015
2
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1016
2
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1017
2
     function,
1018
2
     xml_token->type );
1019
1020
2
    return( -1 );
1021
2
  }
1022
5.12k
  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
5.12k
  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
5.12k
  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
5.12k
  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
5.12k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1067
5.12k
  xml_document_data_size = binary_data_size - binary_data_offset;
1068
1069
5.12k
  if( xml_document_data_size < 3 )
1070
10
  {
1071
10
    libcerror_error_set(
1072
10
     error,
1073
10
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1074
10
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1075
10
     "%s: invalid binary XML document data size value too small.",
1076
10
     function );
1077
1078
10
    return( -1 );
1079
10
  }
1080
5.11k
  if( libfwevt_xml_tag_set_type(
1081
5.11k
       xml_tag,
1082
5.11k
       LIBFWEVT_XML_TAG_TYPE_CDATA,
1083
5.11k
       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
5.11k
  byte_stream_copy_to_uint16_little_endian(
1112
5.11k
   &( xml_document_data[ 1 ] ),
1113
5.11k
   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
5.11k
  xml_token->size     = 3;
1130
5.11k
  binary_data_offset += 3;
1131
1132
5.11k
  value_data_size *= 2;
1133
1134
5.11k
  if( ( value_data_size > binary_data_size )
1135
5.11k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
1136
97
  {
1137
97
    libcerror_error_set(
1138
97
     error,
1139
97
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1140
97
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1141
97
     "%s: invalid value data size value out of bounds.",
1142
97
     function );
1143
1144
97
    return( -1 );
1145
97
  }
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
5.01k
  if( libfwevt_xml_tag_set_value_type(
1164
5.01k
       xml_tag,
1165
5.01k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
1166
5.01k
       error ) != 1 )
1167
6
  {
1168
6
    libcerror_error_set(
1169
6
     error,
1170
6
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1171
6
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1172
6
     "%s: unable to set value type.",
1173
6
     function );
1174
1175
6
    return( -1 );
1176
6
  }
1177
5.01k
  if( libfwevt_xml_tag_set_value_data(
1178
5.01k
       xml_tag,
1179
5.01k
       &( binary_data[ binary_data_offset ] ),
1180
5.01k
       value_data_size,
1181
5.01k
       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
5.01k
  xml_token->size += value_data_size;
1213
1214
5.01k
  return( 1 );
1215
5.01k
}
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
2
{
1229
2
  libfwevt_xml_tag_t *character_xml_tag     = NULL;
1230
2
  uint16_t *character_value_string          = NULL;
1231
2
  uint8_t *character_value_utf16_stream     = NULL;
1232
2
  const uint8_t *xml_document_data          = NULL;
1233
2
  static char *function                     = "libfwevt_xml_document_read_character_reference";
1234
2
  size_t character_value_string_index       = 0;
1235
2
  size_t character_value_string_size        = 0;
1236
2
  size_t character_value_utf16_stream_index = 0;
1237
2
  size_t character_value_utf16_stream_size  = 0;
1238
2
  size_t xml_document_data_size             = 0;
1239
2
  uint16_t character_value                  = 0;
1240
2
  int data_segment_index                    = 0;
1241
1242
2
  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
2
  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
2
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_ENTITY_REFERENCE )
1265
2
  {
1266
2
    libcerror_error_set(
1267
2
     error,
1268
2
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1269
2
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1270
2
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1271
2
     function,
1272
2
     xml_token->type );
1273
1274
2
    return( -1 );
1275
2
  }
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.17M
{
1590
1.17M
  libfwevt_xml_tag_t *element_xml_tag      = NULL;
1591
1.17M
  libfwevt_xml_token_t *xml_sub_token      = NULL;
1592
1.17M
  const uint8_t *xml_document_data         = NULL;
1593
1.17M
  static char *function                    = "libfwevt_xml_document_read_element";
1594
1.17M
  size_t additional_value_size             = 0;
1595
1.17M
  size_t element_size_offset               = 0;
1596
1.17M
  size_t template_value_offset             = 0;
1597
1.17M
  size_t trailing_data_size                = 0;
1598
1.17M
  size_t xml_document_data_offset          = 0;
1599
1.17M
  size_t xml_document_data_size            = 0;
1600
1.17M
  uint32_t attribute_list_size             = 0;
1601
1.17M
  uint32_t element_name_offset             = 0;
1602
1.17M
  uint32_t element_name_size               = 0;
1603
1.17M
  uint32_t element_size                    = 0;
1604
1.17M
  int result                               = 0;
1605
1.17M
  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.17M
  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.17M
  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.17M
  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.17M
  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.17M
  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.17M
  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.17M
  if( ( element_recursion_depth < 0 )
1679
1.17M
   || ( element_recursion_depth > LIBFWEVT_XML_DOCUMENT_ELEMENT_RECURSION_DEPTH ) )
1680
43
  {
1681
43
    libcerror_error_set(
1682
43
     error,
1683
43
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1684
43
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1685
43
     "%s: invalid element recursion depth value out of bounds.",
1686
43
     function );
1687
1688
43
    return( -1 );
1689
43
  }
1690
1.17M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
1691
1.17M
  {
1692
1.17M
    additional_value_size = 4;
1693
1.17M
  }
1694
1.17M
  if( ( binary_data_size < ( 5 + additional_value_size ) )
1695
1.17M
   || ( binary_data_offset > ( binary_data_size - 5 - additional_value_size ) ) )
1696
31
  {
1697
31
    libcerror_error_set(
1698
31
     error,
1699
31
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1700
31
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1701
31
     "%s: invalid binary XML document data size value too small.",
1702
31
     function );
1703
1704
31
    goto on_error;
1705
31
  }
1706
1.17M
  if( libfwevt_xml_token_initialize(
1707
1.17M
       &xml_sub_token,
1708
1.17M
       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.17M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1720
1.17M
  xml_document_data_size = binary_data_size - binary_data_offset;
1721
1722
1.17M
  do
1723
1.26M
  {
1724
1.26M
    if( ( template_value_array_recursion_depth < 0 )
1725
1.26M
     || ( template_value_array_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_VALUE_ARRAY_RECURSION_DEPTH ) )
1726
78
    {
1727
78
      libcerror_error_set(
1728
78
       error,
1729
78
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1730
78
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1731
78
       "%s: invalid template value array recursion depth value out of bounds.",
1732
78
       function );
1733
1734
78
      goto on_error;
1735
78
    }
1736
1.26M
    if( libfwevt_xml_tag_initialize(
1737
1.26M
         &element_xml_tag,
1738
1.26M
         error ) != 1 )
1739
33
    {
1740
33
      libcerror_error_set(
1741
33
       error,
1742
33
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1743
33
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1744
33
       "%s: unable to create element XML tag.",
1745
33
       function );
1746
1747
33
      goto on_error;
1748
33
    }
1749
    /* Note that the dependency identifier is an optional value.
1750
     */
1751
1.26M
    element_size_offset = 1;
1752
1753
1.26M
    byte_stream_copy_to_uint32_little_endian(
1754
1.26M
     &( xml_document_data[ element_size_offset ] ),
1755
1.26M
     element_size );
1756
1757
1.26M
    if( ( xml_document_data_size > 7 )
1758
1.26M
     && ( element_size > ( xml_document_data_size - 7 ) ) )
1759
1.17M
    {
1760
1.17M
      element_size_offset = 3;
1761
1.17M
    }
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.26M
    byte_stream_copy_to_uint32_little_endian(
1780
1.26M
     &( xml_document_data[ element_size_offset ] ),
1781
1.26M
     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.26M
    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.26M
    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.26M
    else
1818
1.26M
    {
1819
1.26M
      if( xml_document_data_offset >= ( xml_document_data_size - 4 ) )
1820
54
      {
1821
54
        libcerror_error_set(
1822
54
         error,
1823
54
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1824
54
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1825
54
         "%s: invalid binary XML document data size value too small.",
1826
54
         function );
1827
1828
54
        goto on_error;
1829
54
      }
1830
1.26M
      byte_stream_copy_to_uint32_little_endian(
1831
1.26M
       &( xml_document_data[ xml_document_data_offset ] ),
1832
1.26M
       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.26M
      xml_document_data_offset += 4;
1844
1.26M
      element_size             -= 4;
1845
1.26M
    }
1846
#if defined( HAVE_DEBUG_OUTPUT )
1847
    if( libcnotify_verbose != 0 )
1848
    {
1849
      libcnotify_printf(
1850
       "\n" );
1851
    }
1852
#endif
1853
1.26M
    if( element_name_offset > ( binary_data_offset + xml_document_data_offset ) )
1854
159
    {
1855
159
      libcerror_error_set(
1856
159
       error,
1857
159
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1858
159
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1859
159
       "%s: invalid element data offset value out of bounds.",
1860
159
       function );
1861
1862
159
      goto on_error;
1863
159
    }
1864
1.26M
    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.26M
    if( libfwevt_xml_document_read_name(
1889
1.26M
         internal_xml_document,
1890
1.26M
         binary_data,
1891
1.26M
         binary_data_size,
1892
1.26M
         element_name_offset,
1893
1.26M
         flags,
1894
1.26M
         &element_name_size,
1895
1.26M
         element_xml_tag,
1896
1.26M
         error ) != 1 )
1897
40
    {
1898
40
      libcerror_error_set(
1899
40
       error,
1900
40
       LIBCERROR_ERROR_DOMAIN_IO,
1901
40
       LIBCERROR_IO_ERROR_READ_FAILED,
1902
40
       "%s: unable to read element name.",
1903
40
       function );
1904
1905
40
      goto on_error;
1906
40
    }
1907
1.26M
    if( ( binary_data_offset + xml_document_data_offset ) == element_name_offset )
1908
11.1k
    {
1909
11.1k
      xml_document_data_offset += element_name_size;
1910
11.1k
      element_size             -= element_name_size;
1911
11.1k
    }
1912
1.26M
    if( ( xml_token->type & LIBFWEVT_XML_TOKEN_FLAG_HAS_MORE_DATA ) != 0 )
1913
520k
    {
1914
520k
      if( xml_document_data_offset >= ( xml_document_data_size - 4 ) )
1915
5
      {
1916
5
        libcerror_error_set(
1917
5
         error,
1918
5
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1919
5
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1920
5
         "%s: invalid binary XML document data size value too small.",
1921
5
         function );
1922
1923
5
        goto on_error;
1924
5
      }
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
519k
      byte_stream_copy_to_uint32_little_endian(
1943
519k
       &( xml_document_data[ xml_document_data_offset ] ),
1944
519k
       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
519k
      xml_document_data_offset += 4;
1960
519k
      element_size             -= 4;
1961
1962
519k
      if( attribute_list_size > ( binary_data_size - ( binary_data_offset + xml_document_data_offset ) ) )
1963
72
      {
1964
72
        libcerror_error_set(
1965
72
         error,
1966
72
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1967
72
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1968
72
         "%s: invalid attribute list size value out of bounds.",
1969
72
         function );
1970
1971
72
        goto on_error;
1972
72
      }
1973
1.31M
      while( attribute_list_size > 0 )
1974
802k
      {
1975
802k
        if( libfwevt_xml_token_read_data(
1976
802k
             xml_sub_token,
1977
802k
             binary_data,
1978
802k
             binary_data_size,
1979
802k
             binary_data_offset + xml_document_data_offset,
1980
802k
             error ) != 1 )
1981
18
        {
1982
18
          libcerror_error_set(
1983
18
           error,
1984
18
           LIBCERROR_ERROR_DOMAIN_IO,
1985
18
           LIBCERROR_IO_ERROR_READ_FAILED,
1986
18
           "%s: unable to read binary XML sub token.",
1987
18
           function );
1988
1989
18
          goto on_error;
1990
18
        }
1991
802k
        if( libfwevt_xml_document_read_attribute(
1992
802k
             internal_xml_document,
1993
802k
             xml_sub_token,
1994
802k
             binary_data,
1995
802k
             binary_data_size,
1996
802k
             binary_data_offset + xml_document_data_offset,
1997
802k
             ascii_codepage,
1998
802k
             flags,
1999
802k
             template_values_array,
2000
802k
             element_xml_tag,
2001
802k
             element_recursion_depth,
2002
802k
             template_instance_recursion_depth,
2003
802k
             error ) != 1 )
2004
3.63k
        {
2005
3.63k
          libcerror_error_set(
2006
3.63k
           error,
2007
3.63k
           LIBCERROR_ERROR_DOMAIN_IO,
2008
3.63k
           LIBCERROR_IO_ERROR_READ_FAILED,
2009
3.63k
           "%s: unable to read attribute.",
2010
3.63k
           function );
2011
2012
3.63k
          goto on_error;
2013
3.63k
        }
2014
798k
        xml_document_data_offset += xml_sub_token->size;
2015
798k
        element_size             -= (uint32_t) xml_sub_token->size;
2016
2017
798k
        if( attribute_list_size < xml_sub_token->size )
2018
74
        {
2019
74
          libcerror_error_set(
2020
74
           error,
2021
74
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2022
74
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2023
74
           "%s: invalid attribute list size value too small.",
2024
74
           function );
2025
2026
74
          goto on_error;
2027
74
        }
2028
798k
        attribute_list_size -= (uint32_t) xml_sub_token->size;
2029
798k
      }
2030
519k
    }
2031
1.25M
    if( libfwevt_xml_token_read_data(
2032
1.25M
         xml_sub_token,
2033
1.25M
         binary_data,
2034
1.25M
         binary_data_size,
2035
1.25M
         binary_data_offset + xml_document_data_offset,
2036
1.25M
         error ) != 1 )
2037
25
    {
2038
25
      libcerror_error_set(
2039
25
       error,
2040
25
       LIBCERROR_ERROR_DOMAIN_IO,
2041
25
       LIBCERROR_IO_ERROR_READ_FAILED,
2042
25
       "%s: unable to read binary XML sub token.",
2043
25
       function );
2044
2045
25
      goto on_error;
2046
25
    }
2047
1.25M
    if( ( xml_sub_token->type != LIBFWEVT_XML_TOKEN_CLOSE_START_ELEMENT_TAG )
2048
1.25M
     && ( xml_sub_token->type != LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG ) )
2049
56
    {
2050
56
      libcerror_error_set(
2051
56
       error,
2052
56
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2053
56
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2054
56
       "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
2055
56
       function,
2056
56
       xml_token->type );
2057
2058
56
      goto on_error;
2059
56
    }
2060
1.25M
    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.25M
    xml_document_data_offset += 1;
2101
1.25M
    element_size             -= 1;
2102
2103
1.25M
    if( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_START_ELEMENT_TAG )
2104
890k
    {
2105
890k
      result = 1;
2106
2107
3.36M
      while( element_size > 0 )
2108
3.30M
      {
2109
3.30M
        if( libfwevt_xml_token_read_data(
2110
3.30M
             xml_sub_token,
2111
3.30M
             binary_data,
2112
3.30M
             binary_data_size,
2113
3.30M
             binary_data_offset + xml_document_data_offset,
2114
3.30M
             error ) != 1 )
2115
238
        {
2116
238
          libcerror_error_set(
2117
238
           error,
2118
238
           LIBCERROR_ERROR_DOMAIN_IO,
2119
238
           LIBCERROR_IO_ERROR_READ_FAILED,
2120
238
           "%s: unable to read binary XML sub token.",
2121
238
           function );
2122
2123
238
          goto on_error;
2124
238
        }
2125
3.30M
        switch( xml_sub_token->type & 0xbf )
2126
3.30M
        {
2127
1.07M
          case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
2128
1.07M
            if( libfwevt_xml_document_read_element(
2129
1.07M
                 internal_xml_document,
2130
1.07M
                 xml_sub_token,
2131
1.07M
                 binary_data,
2132
1.07M
                 binary_data_size,
2133
1.07M
                 binary_data_offset + xml_document_data_offset,
2134
1.07M
                 ascii_codepage,
2135
1.07M
                 flags,
2136
1.07M
                 template_values_array,
2137
1.07M
                 element_xml_tag,
2138
1.07M
                 element_recursion_depth + 1,
2139
1.07M
                 template_instance_recursion_depth,
2140
1.07M
                 error ) != 1 )
2141
9.61k
            {
2142
9.61k
              libcerror_error_set(
2143
9.61k
               error,
2144
9.61k
               LIBCERROR_ERROR_DOMAIN_IO,
2145
9.61k
               LIBCERROR_IO_ERROR_READ_FAILED,
2146
9.61k
               "%s: unable to read element.",
2147
9.61k
               function );
2148
2149
9.61k
              goto on_error;
2150
9.61k
            }
2151
1.06M
            break;
2152
2153
1.06M
          case LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG:
2154
807k
          case LIBFWEVT_XML_TOKEN_END_ELEMENT_TAG:
2155
807k
            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
807k
            xml_sub_token->size = 1;
2196
2197
807k
            break;
2198
2199
5.12k
          case LIBFWEVT_XML_TOKEN_CDATA_SECTION:
2200
5.12k
            if( template_value_offset != 0 )
2201
4
            {
2202
4
              libcerror_error_set(
2203
4
               error,
2204
4
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2205
4
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2206
4
               "%s: invalid template value offset value out of bounds.",
2207
4
               function );
2208
2209
4
              goto on_error;
2210
4
            }
2211
5.12k
            if( libfwevt_xml_document_read_cdata_section(
2212
5.12k
                 internal_xml_document,
2213
5.12k
                 xml_sub_token,
2214
5.12k
                 binary_data,
2215
5.12k
                 binary_data_size,
2216
5.12k
                 binary_data_offset + xml_document_data_offset,
2217
5.12k
                 element_xml_tag,
2218
5.12k
                 error ) != 1 )
2219
115
            {
2220
115
              libcerror_error_set(
2221
115
               error,
2222
115
               LIBCERROR_ERROR_DOMAIN_IO,
2223
115
               LIBCERROR_IO_ERROR_READ_FAILED,
2224
115
               "%s: unable to read CDATA section.",
2225
115
               function );
2226
2227
115
              goto on_error;
2228
115
            }
2229
5.01k
            break;
2230
2231
5.01k
          case LIBFWEVT_XML_TOKEN_PI_TARGET:
2232
2.20k
            if( template_value_offset != 0 )
2233
27
            {
2234
27
              libcerror_error_set(
2235
27
               error,
2236
27
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2237
27
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2238
27
               "%s: invalid template value offset value out of bounds.",
2239
27
               function );
2240
2241
27
              goto on_error;
2242
27
            }
2243
2.17k
            if( libfwevt_xml_document_read_pi_target(
2244
2.17k
                 internal_xml_document,
2245
2.17k
                 xml_sub_token,
2246
2.17k
                 binary_data,
2247
2.17k
                 binary_data_size,
2248
2.17k
                 binary_data_offset + xml_document_data_offset,
2249
2.17k
                 flags,
2250
2.17k
                 element_xml_tag,
2251
2.17k
                 error ) != 1 )
2252
300
            {
2253
300
              libcerror_error_set(
2254
300
               error,
2255
300
               LIBCERROR_ERROR_DOMAIN_IO,
2256
300
               LIBCERROR_IO_ERROR_READ_FAILED,
2257
300
               "%s: unable to read PI target.",
2258
300
               function );
2259
2260
300
              goto on_error;
2261
300
            }
2262
1.87k
            break;
2263
2264
1.87k
          case LIBFWEVT_XML_TOKEN_CHARACTER_REFERENCE:
2265
25
            if( template_value_offset != 0 )
2266
23
            {
2267
23
              libcerror_error_set(
2268
23
               error,
2269
23
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2270
23
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2271
23
               "%s: invalid template value offset value out of bounds.",
2272
23
               function );
2273
2274
23
              goto on_error;
2275
23
            }
2276
2
            if( libfwevt_xml_document_read_character_reference(
2277
2
                 internal_xml_document,
2278
2
                 xml_sub_token,
2279
2
                 binary_data,
2280
2
                 binary_data_size,
2281
2
                 binary_data_offset + xml_document_data_offset,
2282
2
                 element_xml_tag,
2283
2
                 error ) != 1 )
2284
2
            {
2285
2
              libcerror_error_set(
2286
2
               error,
2287
2
               LIBCERROR_ERROR_DOMAIN_IO,
2288
2
               LIBCERROR_IO_ERROR_READ_FAILED,
2289
2
               "%s: unable to read character reference.",
2290
2
               function );
2291
2292
2
              goto on_error;
2293
2
            }
2294
0
            break;
2295
2296
5.85k
          case LIBFWEVT_XML_TOKEN_ENTITY_REFERENCE:
2297
5.85k
            if( template_value_offset != 0 )
2298
4
            {
2299
4
              libcerror_error_set(
2300
4
               error,
2301
4
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2302
4
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2303
4
               "%s: invalid template value offset value out of bounds.",
2304
4
               function );
2305
2306
4
              goto on_error;
2307
4
            }
2308
5.84k
            if( libfwevt_xml_document_read_entity_reference(
2309
5.84k
                 internal_xml_document,
2310
5.84k
                 xml_sub_token,
2311
5.84k
                 binary_data,
2312
5.84k
                 binary_data_size,
2313
5.84k
                 binary_data_offset + xml_document_data_offset,
2314
5.84k
                 flags,
2315
5.84k
                 element_xml_tag,
2316
5.84k
                 error ) != 1 )
2317
884
            {
2318
884
              libcerror_error_set(
2319
884
               error,
2320
884
               LIBCERROR_ERROR_DOMAIN_IO,
2321
884
               LIBCERROR_IO_ERROR_READ_FAILED,
2322
884
               "%s: unable to read entity reference.",
2323
884
               function );
2324
2325
884
              goto on_error;
2326
884
            }
2327
4.96k
            break;
2328
2329
729k
          case LIBFWEVT_XML_TOKEN_VALUE:
2330
729k
            if( template_value_offset != 0 )
2331
4
            {
2332
4
              libcerror_error_set(
2333
4
               error,
2334
4
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2335
4
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2336
4
               "%s: invalid template value offset value out of bounds.",
2337
4
               function );
2338
2339
4
              goto on_error;
2340
4
            }
2341
729k
            if( libfwevt_xml_document_read_value(
2342
729k
                 internal_xml_document,
2343
729k
                 xml_sub_token,
2344
729k
                 binary_data,
2345
729k
                 binary_data_size,
2346
729k
                 binary_data_offset + xml_document_data_offset,
2347
729k
                 element_xml_tag,
2348
729k
                 error ) != 1 )
2349
133
            {
2350
133
              libcerror_error_set(
2351
133
               error,
2352
133
               LIBCERROR_ERROR_DOMAIN_IO,
2353
133
               LIBCERROR_IO_ERROR_READ_FAILED,
2354
133
               "%s: unable to read value.",
2355
133
               function );
2356
2357
133
              goto on_error;
2358
133
            }
2359
729k
            break;
2360
2361
729k
          case LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION:
2362
66.3k
            result = libfwevt_xml_document_read_normal_substitution(
2363
66.3k
                internal_xml_document,
2364
66.3k
                xml_sub_token,
2365
66.3k
                binary_data,
2366
66.3k
                binary_data_size,
2367
66.3k
                binary_data_offset + xml_document_data_offset,
2368
66.3k
                ascii_codepage,
2369
66.3k
                flags,
2370
66.3k
                template_values_array,
2371
66.3k
                &template_value_offset,
2372
66.3k
                element_xml_tag,
2373
66.3k
                element_recursion_depth,
2374
66.3k
                template_instance_recursion_depth,
2375
66.3k
                error );
2376
2377
66.3k
            if( result == -1 )
2378
3.48k
            {
2379
3.48k
              libcerror_error_set(
2380
3.48k
               error,
2381
3.48k
               LIBCERROR_ERROR_DOMAIN_IO,
2382
3.48k
               LIBCERROR_IO_ERROR_READ_FAILED,
2383
3.48k
               "%s: unable to read normal substitution.",
2384
3.48k
               function );
2385
2386
3.48k
              goto on_error;
2387
3.48k
            }
2388
62.8k
            break;
2389
2390
615k
          case LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION:
2391
615k
            result = libfwevt_xml_document_read_optional_substitution(
2392
615k
                internal_xml_document,
2393
615k
                xml_sub_token,
2394
615k
                binary_data,
2395
615k
                binary_data_size,
2396
615k
                binary_data_offset + xml_document_data_offset,
2397
615k
                ascii_codepage,
2398
615k
                flags,
2399
615k
                template_values_array,
2400
615k
                &template_value_offset,
2401
615k
                element_xml_tag,
2402
615k
                      element_recursion_depth,
2403
615k
                template_instance_recursion_depth,
2404
615k
                error );
2405
2406
615k
            if( result == -1 )
2407
5.02k
            {
2408
5.02k
              libcerror_error_set(
2409
5.02k
               error,
2410
5.02k
               LIBCERROR_ERROR_DOMAIN_IO,
2411
5.02k
               LIBCERROR_IO_ERROR_READ_FAILED,
2412
5.02k
               "%s: unable to read optional substitution.",
2413
5.02k
               function );
2414
2415
5.02k
              goto on_error;
2416
5.02k
            }
2417
610k
            break;
2418
2419
610k
          default:
2420
115
            libcerror_error_set(
2421
115
             error,
2422
115
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2423
115
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2424
115
             "%s: invalid binary XML sub token - unsupported type: 0x%02" PRIx8 ".",
2425
115
             function,
2426
115
             xml_sub_token->type );
2427
2428
115
            goto on_error;
2429
3.30M
        }
2430
3.28M
        xml_document_data_offset += xml_sub_token->size;
2431
2432
3.28M
        if( element_size < xml_sub_token->size )
2433
60
        {
2434
60
          libcerror_error_set(
2435
60
           error,
2436
60
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2437
60
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2438
60
           "%s: invalid element size value too small.",
2439
60
           function );
2440
2441
60
          goto on_error;
2442
60
        }
2443
3.28M
        element_size -= (uint32_t) xml_sub_token->size;
2444
2445
3.28M
        if( ( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG )
2446
3.28M
         || ( xml_sub_token->type == LIBFWEVT_XML_TOKEN_END_ELEMENT_TAG ) )
2447
807k
        {
2448
807k
          break;
2449
807k
        }
2450
3.28M
      }
2451
890k
    }
2452
365k
    else if( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG )
2453
365k
    {
2454
365k
      result = 1;
2455
365k
    }
2456
1.23M
    if( element_size > 0 )
2457
190
    {
2458
190
      libcerror_error_set(
2459
190
       error,
2460
190
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2461
190
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2462
190
       "%s: invalid element size value out of bounds.",
2463
190
       function );
2464
2465
190
      goto on_error;
2466
190
    }
2467
1.23M
    if( result != 0 )
2468
1.16M
    {
2469
1.16M
      if( xml_tag != NULL )
2470
1.16M
      {
2471
1.16M
        if( libfwevt_xml_tag_append_element(
2472
1.16M
             xml_tag,
2473
1.16M
             element_xml_tag,
2474
1.16M
             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.16M
        element_xml_tag = NULL;
2486
1.16M
      }
2487
610
      else if( internal_xml_document->root_xml_tag == NULL )
2488
571
      {
2489
571
        internal_xml_document->root_xml_tag = element_xml_tag;
2490
2491
571
        element_xml_tag = NULL;
2492
571
      }
2493
1.16M
    }
2494
1.23M
    template_value_array_recursion_depth++;
2495
1.23M
  }
2496
1.23M
  while( template_value_offset > 0 );
2497
2498
1.14M
  xml_token->size = xml_document_data_offset;
2499
2500
1.14M
  if( element_xml_tag != NULL )
2501
67.8k
  {
2502
67.8k
    if( libfwevt_internal_xml_tag_free(
2503
67.8k
         (libfwevt_internal_xml_tag_t **) &element_xml_tag,
2504
67.8k
         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.8k
  }
2516
1.14M
  if( libfwevt_xml_token_free(
2517
1.14M
       &xml_sub_token,
2518
1.14M
       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.14M
  return( 1 );
2530
2531
24.4k
on_error:
2532
24.4k
  if( ( element_xml_tag != NULL )
2533
24.4k
   && ( element_xml_tag != internal_xml_document->root_xml_tag ) )
2534
24.3k
  {
2535
24.3k
    libfwevt_internal_xml_tag_free(
2536
24.3k
     (libfwevt_internal_xml_tag_t **) &element_xml_tag,
2537
24.3k
     NULL );
2538
24.3k
  }
2539
24.4k
  if( xml_sub_token != NULL )
2540
24.4k
  {
2541
24.4k
    libfwevt_xml_token_free(
2542
24.4k
     &xml_sub_token,
2543
24.4k
     NULL );
2544
24.4k
  }
2545
24.4k
  return( -1 );
2546
1.14M
}
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
5.84k
{
2561
5.84k
  libfwevt_xml_tag_t *entity_xml_tag = NULL;
2562
5.84k
  uint8_t *entity_name               = NULL;
2563
5.84k
  uint8_t *entity_value_utf16_stream = NULL;
2564
5.84k
  const uint8_t *xml_document_data   = NULL;
2565
5.84k
  static char *function              = "libfwevt_xml_document_read_entity_reference";
2566
5.84k
  size_t additional_value_size       = 0;
2567
5.84k
  size_t trailing_data_size          = 0;
2568
5.84k
  size_t utf8_string_size            = 0;
2569
5.84k
  size_t xml_document_data_offset    = 0;
2570
5.84k
  size_t xml_document_data_size      = 0;
2571
5.84k
  uint32_t entity_name_offset        = 0;
2572
5.84k
  uint32_t entity_name_size          = 0;
2573
5.84k
  uint8_t entity_name_match          = 0;
2574
5.84k
  int data_segment_index             = 0;
2575
2576
5.84k
  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
5.84k
  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
5.84k
  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
5.84k
  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
5.84k
  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
5.84k
  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
5.84k
  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
5.84k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
2655
5.84k
  {
2656
5.84k
    additional_value_size = 4;
2657
5.84k
  }
2658
5.84k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
2659
5.84k
  xml_document_data_size = binary_data_size - binary_data_offset;
2660
2661
5.84k
  if( xml_document_data_size < ( 1 + additional_value_size ) )
2662
40
  {
2663
40
    libcerror_error_set(
2664
40
     error,
2665
40
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2666
40
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2667
40
     "%s: invalid binary XML document data size value too small.",
2668
40
     function );
2669
2670
40
    goto on_error;
2671
40
  }
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
5.80k
  xml_token->size          = 1;
2699
5.80k
  xml_document_data_offset = 1;
2700
2701
5.80k
  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
5.80k
  else
2706
5.80k
  {
2707
5.80k
    if( ( xml_document_data_size < 4 )
2708
5.80k
     || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
2709
3
    {
2710
3
      libcerror_error_set(
2711
3
       error,
2712
3
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2713
3
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2714
3
       "%s: invalid binary XML document data size value too small.",
2715
3
       function );
2716
2717
3
      goto on_error;
2718
3
    }
2719
5.80k
    byte_stream_copy_to_uint32_little_endian(
2720
5.80k
     &( xml_document_data[ xml_document_data_offset ] ),
2721
5.80k
     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
5.80k
    xml_token->size          += 4;
2733
5.80k
    xml_document_data_offset += 4;
2734
5.80k
  }
2735
#if defined( HAVE_DEBUG_OUTPUT )
2736
  if( libcnotify_verbose != 0 )
2737
  {
2738
    libcnotify_printf(
2739
     "\n" );
2740
  }
2741
#endif
2742
5.80k
  if( entity_name_offset > ( binary_data_offset + xml_document_data_offset ) )
2743
110
  {
2744
110
    libcerror_error_set(
2745
110
     error,
2746
110
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2747
110
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2748
110
     "%s: invalid entity name offset value out of bounds.",
2749
110
     function );
2750
2751
110
    goto on_error;
2752
110
  }
2753
5.69k
  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
5.69k
  if( libfwevt_xml_tag_initialize(
2778
5.69k
       &entity_xml_tag,
2779
5.69k
       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
5.69k
  if( libfwevt_xml_document_read_name(
2791
5.69k
       internal_xml_document,
2792
5.69k
       binary_data,
2793
5.69k
       binary_data_size,
2794
5.69k
       entity_name_offset,
2795
5.69k
       flags,
2796
5.69k
       &entity_name_size,
2797
5.69k
       entity_xml_tag,
2798
5.69k
       error ) != 1 )
2799
10
  {
2800
10
    libcerror_error_set(
2801
10
     error,
2802
10
     LIBCERROR_ERROR_DOMAIN_IO,
2803
10
     LIBCERROR_IO_ERROR_READ_FAILED,
2804
10
     "%s: unable to read entity name.",
2805
10
     function );
2806
2807
10
    goto on_error;
2808
10
  }
2809
5.68k
  if( ( binary_data_offset + xml_document_data_offset ) == entity_name_offset )
2810
205
  {
2811
205
    xml_token->size += entity_name_size;
2812
205
  }
2813
5.68k
  if( libfwevt_xml_tag_get_utf8_name_size(
2814
5.68k
       entity_xml_tag,
2815
5.68k
       &utf8_string_size,
2816
5.68k
       error ) != 1 )
2817
104
  {
2818
104
    libcerror_error_set(
2819
104
     error,
2820
104
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2821
104
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2822
104
     "%s: unable to retrieve UTF-8 string size of entity name.",
2823
104
     function );
2824
2825
104
    goto on_error;
2826
104
  }
2827
5.58k
  if( ( utf8_string_size == 0 )
2828
5.58k
   || ( 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
5.58k
  entity_name = (uint8_t *) memory_allocate(
2840
5.58k
                             sizeof( uint8_t ) * utf8_string_size );
2841
2842
5.58k
  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
5.58k
  if( libfwevt_xml_tag_get_utf8_name(
2854
5.58k
       entity_xml_tag,
2855
5.58k
       entity_name,
2856
5.58k
       utf8_string_size,
2857
5.58k
       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
5.58k
  if( libfwevt_xml_tag_set_value_type(
2869
5.58k
       xml_tag,
2870
5.58k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
2871
5.58k
       error ) != 1 )
2872
2
  {
2873
2
    libcerror_error_set(
2874
2
     error,
2875
2
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2876
2
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2877
2
     "%s: unable to set value type.",
2878
2
     function );
2879
2880
2
    goto on_error;
2881
2
  }
2882
  /* Make sure the character value data is in UTF-16 litte-endian
2883
   */
2884
5.57k
  entity_value_utf16_stream = (uint8_t *) memory_allocate(
2885
5.57k
                                           sizeof( uint8_t ) * 4 );
2886
2887
5.57k
  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
5.57k
  if( utf8_string_size == 3 )
2899
4.06k
  {
2900
4.06k
    if( ( entity_name[ 0 ] == (uint8_t) 'g' )
2901
4.06k
     && ( entity_name[ 1 ] == (uint8_t) 't' ) )
2902
3.26k
    {
2903
3.26k
      entity_value_utf16_stream[ 0 ] = (uint8_t) '>';
2904
3.26k
      entity_value_utf16_stream[ 1 ] = 0;
2905
2906
3.26k
      entity_name_match = 1;
2907
3.26k
    }
2908
797
    else if( ( entity_name[ 0 ] == (uint8_t) 'l' )
2909
797
          && ( entity_name[ 1 ] == (uint8_t) 't' ) )
2910
734
    {
2911
734
      entity_value_utf16_stream[ 0 ] = (uint8_t) '<';
2912
734
      entity_value_utf16_stream[ 1 ] = 0;
2913
2914
734
      entity_name_match = 1;
2915
734
    }
2916
4.06k
  }
2917
1.51k
  else if( utf8_string_size == 4 )
2918
353
  {
2919
353
    if( ( entity_name[ 0 ] == (uint8_t) 'a' )
2920
353
     && ( entity_name[ 1 ] == (uint8_t) 'm' )
2921
353
     && ( entity_name[ 2 ] == (uint8_t) 'p' ) )
2922
288
    {
2923
288
      entity_value_utf16_stream[ 0 ] = (uint8_t) '&';
2924
288
      entity_value_utf16_stream[ 1 ] = 0;
2925
2926
288
      entity_name_match = 1;
2927
288
    }
2928
353
  }
2929
1.16k
  else if( utf8_string_size == 5 )
2930
849
  {
2931
849
    if( ( entity_name[ 0 ] == (uint8_t) 'a' )
2932
849
     && ( entity_name[ 1 ] == (uint8_t) 'p' )
2933
849
     && ( entity_name[ 2 ] == (uint8_t) 'o' )
2934
849
     && ( entity_name[ 3 ] == (uint8_t) 's' ) )
2935
214
    {
2936
214
      entity_value_utf16_stream[ 0 ] = (uint8_t) '\'';
2937
214
      entity_value_utf16_stream[ 1 ] = 0;
2938
2939
214
      entity_name_match = 1;
2940
214
    }
2941
635
    else if( ( entity_name[ 0 ] == (uint8_t) 'q' )
2942
635
          && ( entity_name[ 1 ] == (uint8_t) 'u' )
2943
635
          && ( entity_name[ 2 ] == (uint8_t) 'o' )
2944
635
          && ( entity_name[ 3 ] == (uint8_t) 't' ) )
2945
462
    {
2946
462
      entity_value_utf16_stream[ 0 ] = (uint8_t) '"';
2947
462
      entity_value_utf16_stream[ 1 ] = 0;
2948
2949
462
      entity_name_match = 1;
2950
462
    }
2951
849
  }
2952
5.57k
  if( entity_name_match == 0 )
2953
615
  {
2954
615
    libcerror_error_set(
2955
615
     error,
2956
615
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2957
615
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2958
615
     "%s: unsupported entity name: %s\n",
2959
615
     function,
2960
615
     entity_name );
2961
2962
615
    goto on_error;
2963
615
  }
2964
4.96k
  entity_value_utf16_stream[ 2 ] = 0;
2965
4.96k
  entity_value_utf16_stream[ 3 ] = 0;
2966
2967
4.96k
  memory_free(
2968
4.96k
   entity_name );
2969
2970
4.96k
  entity_name = NULL;
2971
2972
4.96k
  if( libfwevt_xml_tag_append_value_data(
2973
4.96k
       xml_tag,
2974
4.96k
       entity_value_utf16_stream,
2975
4.96k
       4,
2976
4.96k
       &data_segment_index,
2977
4.96k
       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
4.96k
  memory_free(
2989
4.96k
   entity_value_utf16_stream );
2990
2991
4.96k
  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
4.96k
  if( libfwevt_internal_xml_tag_free(
3016
4.96k
       (libfwevt_internal_xml_tag_t **) &entity_xml_tag,
3017
4.96k
       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
4.96k
  return( 1 );
3029
3030
884
on_error:
3031
884
  if( entity_value_utf16_stream != NULL )
3032
615
  {
3033
615
    memory_free(
3034
615
     entity_value_utf16_stream );
3035
615
  }
3036
884
  if( entity_name != NULL )
3037
617
  {
3038
617
    memory_free(
3039
617
     entity_name );
3040
617
  }
3041
884
  if( entity_xml_tag != NULL )
3042
731
  {
3043
731
    libfwevt_internal_xml_tag_free(
3044
731
     (libfwevt_internal_xml_tag_t **) &entity_xml_tag,
3045
731
     NULL );
3046
731
  }
3047
884
  return( -1 );
3048
4.96k
}
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
45.3k
{
3067
45.3k
  libfwevt_xml_token_t *xml_sub_token = NULL;
3068
45.3k
  static char *function               = "libfwevt_xml_document_read_fragment";
3069
3070
45.3k
  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
45.3k
  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
45.3k
  if( libfwevt_xml_document_read_fragment_header(
3093
45.3k
       internal_xml_document,
3094
45.3k
       xml_token,
3095
45.3k
       binary_data,
3096
45.3k
       binary_data_size,
3097
45.3k
       binary_data_offset,
3098
45.3k
       error ) != 1 )
3099
14
  {
3100
14
    libcerror_error_set(
3101
14
     error,
3102
14
     LIBCERROR_ERROR_DOMAIN_IO,
3103
14
     LIBCERROR_IO_ERROR_READ_FAILED,
3104
14
     "%s: unable to read fragment header.",
3105
14
     function );
3106
3107
14
    goto on_error;
3108
14
  }
3109
45.3k
  binary_data_offset += xml_token->size;
3110
3111
45.3k
  if( libfwevt_xml_token_initialize(
3112
45.3k
       &xml_sub_token,
3113
45.3k
       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
45.3k
  if( libfwevt_xml_token_read_data(
3125
45.3k
       xml_sub_token,
3126
45.3k
       binary_data,
3127
45.3k
       binary_data_size,
3128
45.3k
       binary_data_offset,
3129
45.3k
       error ) != 1 )
3130
9
  {
3131
9
    libcerror_error_set(
3132
9
     error,
3133
9
     LIBCERROR_ERROR_DOMAIN_IO,
3134
9
     LIBCERROR_IO_ERROR_READ_FAILED,
3135
9
     "%s: unable to read binary XML sub token.",
3136
9
     function );
3137
3138
9
    goto on_error;
3139
9
  }
3140
45.3k
  switch( xml_sub_token->type & 0xbf )
3141
45.3k
  {
3142
2.50k
    case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
3143
2.50k
      if( libfwevt_xml_document_read_element(
3144
2.50k
           internal_xml_document,
3145
2.50k
           xml_sub_token,
3146
2.50k
           binary_data,
3147
2.50k
           binary_data_size,
3148
2.50k
           binary_data_offset,
3149
2.50k
           ascii_codepage,
3150
2.50k
           flags,
3151
2.50k
           template_values_array,
3152
2.50k
           xml_tag,
3153
2.50k
           element_recursion_depth + 1,
3154
2.50k
           template_instance_recursion_depth,
3155
2.50k
           error ) != 1 )
3156
1.83k
      {
3157
1.83k
        libcerror_error_set(
3158
1.83k
         error,
3159
1.83k
         LIBCERROR_ERROR_DOMAIN_IO,
3160
1.83k
         LIBCERROR_IO_ERROR_READ_FAILED,
3161
1.83k
         "%s: unable to read element.",
3162
1.83k
         function );
3163
3164
1.83k
        goto on_error;
3165
1.83k
      }
3166
668
      break;
3167
3168
42.7k
    case LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE:
3169
42.7k
      if( libfwevt_xml_document_read_template_instance(
3170
42.7k
           internal_xml_document,
3171
42.7k
           xml_sub_token,
3172
42.7k
           binary_data,
3173
42.7k
           binary_data_size,
3174
42.7k
           binary_data_offset,
3175
42.7k
           ascii_codepage,
3176
42.7k
           flags,
3177
42.7k
           xml_tag,
3178
42.7k
           element_recursion_depth,
3179
42.7k
           template_instance_recursion_depth + 1,
3180
42.7k
           error ) != 1 )
3181
5.77k
      {
3182
5.77k
        libcerror_error_set(
3183
5.77k
         error,
3184
5.77k
         LIBCERROR_ERROR_DOMAIN_IO,
3185
5.77k
         LIBCERROR_IO_ERROR_READ_FAILED,
3186
5.77k
         "%s: unable to read document template instance.",
3187
5.77k
         function );
3188
3189
5.77k
        goto on_error;
3190
5.77k
      }
3191
37.0k
      break;
3192
3193
37.0k
    default:
3194
14
      libcerror_error_set(
3195
14
       error,
3196
14
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3197
14
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3198
14
       "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3199
14
       function,
3200
14
       xml_sub_token->type );
3201
3202
14
      goto on_error;
3203
45.3k
  }
3204
37.6k
  xml_token->size += xml_sub_token->size;
3205
3206
37.6k
  if( libfwevt_xml_token_free(
3207
37.6k
       &xml_sub_token,
3208
37.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
37.6k
  return( 1 );
3220
3221
7.64k
on_error:
3222
7.64k
  if( xml_sub_token != NULL )
3223
7.63k
  {
3224
7.63k
    libfwevt_xml_token_free(
3225
7.63k
     &xml_sub_token,
3226
7.63k
     NULL );
3227
7.63k
  }
3228
7.64k
  return( -1 );
3229
37.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
132k
{
3242
132k
  static char *function            = "libfwevt_xml_document_read_fragment_header";
3243
132k
  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
132k
  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
132k
  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
132k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER )
3272
102
  {
3273
102
    libcerror_error_set(
3274
102
     error,
3275
102
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3276
102
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3277
102
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3278
102
     function,
3279
102
     xml_token->type );
3280
3281
102
    return( -1 );
3282
102
  }
3283
132k
  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
132k
  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
132k
  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
132k
  xml_document_data_size = binary_data_size - binary_data_offset;
3321
3322
132k
  if( xml_document_data_size < 4 )
3323
14
  {
3324
14
    libcerror_error_set(
3325
14
     error,
3326
14
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3327
14
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3328
14
     "%s: invalid binary XML document data size value too small.",
3329
14
     function );
3330
3331
14
    return( -1 );
3332
14
  }
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
132k
  xml_token->size = 4;
3380
  
3381
132k
  return( 1 );
3382
132k
}
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.07M
{
3397
2.07M
  const uint8_t *xml_document_data = NULL;
3398
2.07M
  static char *function            = "libfwevt_xml_document_read_name";
3399
2.07M
  size_t additional_value_size     = 0;
3400
2.07M
  size_t xml_document_data_offset  = 0;
3401
2.07M
  size_t xml_document_data_size    = 0;
3402
2.07M
  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.07M
  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.07M
  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.07M
  if( ( binary_data_size < 4 )
3432
2.07M
   || ( 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.07M
  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.07M
  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.07M
  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.07M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3477
2.07M
  xml_document_data_size = binary_data_size - binary_data_offset;
3478
3479
2.07M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
3480
2.07M
  {
3481
2.07M
    additional_value_size += 4;
3482
2.07M
  }
3483
2.07M
  if( ( additional_value_size + 4 ) > xml_document_data_size )
3484
10
  {
3485
10
    libcerror_error_set(
3486
10
     error,
3487
10
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3488
10
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3489
10
     "%s: invalid binary XML document data size value too small.",
3490
10
     function );
3491
3492
10
    return( -1 );
3493
10
  }
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.07M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
3512
2.07M
  {
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.07M
    xml_document_data_offset += 4;
3527
2.07M
  }
3528
2.07M
  byte_stream_copy_to_uint16_little_endian(
3529
2.07M
   &( xml_document_data[ xml_document_data_offset + 2 ] ),
3530
2.07M
   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.07M
  xml_document_data_offset += 4;
3551
3552
2.07M
  if( ( name_size == 0 )
3553
2.07M
   || ( (size_t) name_size > ( ( MEMORY_MAXIMUM_ALLOCATION_SIZE - 1 ) / 2 ) ) )
3554
23
  {
3555
23
    libcerror_error_set(
3556
23
     error,
3557
23
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3558
23
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3559
23
     "%s: invalid name size value out of bounds.",
3560
23
     function );
3561
3562
23
    return( -1 );
3563
23
  }
3564
2.07M
  name_size = ( name_size + 1 ) * 2;
3565
3566
2.07M
  if( (size_t) name_size > ( xml_document_data_size - xml_document_data_offset ) )
3567
34
  {
3568
34
    libcerror_error_set(
3569
34
     error,
3570
34
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3571
34
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3572
34
     "%s: invalid binary XML document data size value too small.",
3573
34
     function );
3574
3575
34
    return( -1 );
3576
34
  }
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.07M
  if( libfwevt_xml_tag_set_name_data(
3590
2.07M
       xml_tag,
3591
2.07M
       &( xml_document_data[ xml_document_data_offset ] ),
3592
2.07M
       name_size,
3593
2.07M
       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.07M
  *name_data_size = (uint32_t) ( xml_document_data_offset + name_size );
3624
3625
2.07M
  return( 1 );
3626
2.07M
}
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
138k
{
3646
138k
  const uint8_t *xml_document_data = NULL;
3647
138k
  static char *function            = "libfwevt_xml_document_read_normal_substitution";
3648
138k
  size_t xml_document_data_size    = 0;
3649
138k
  uint16_t template_value_index    = 0;
3650
138k
  uint8_t template_value_type      = 0;
3651
138k
  int result                       = 0;
3652
3653
138k
  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
138k
  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
138k
  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
138k
  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
138k
  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
138k
  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
138k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3721
138k
  xml_document_data_size = binary_data_size - binary_data_offset;
3722
3723
138k
  if( xml_document_data_size < 4 )
3724
9
  {
3725
9
    libcerror_error_set(
3726
9
     error,
3727
9
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3728
9
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3729
9
     "%s: invalid binary XML document data size value too small.",
3730
9
     function );
3731
3732
9
    return( -1 );
3733
9
  }
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
138k
  byte_stream_copy_to_uint16_little_endian(
3752
138k
   &( xml_document_data[ 1 ] ),
3753
138k
   template_value_index );
3754
3755
138k
  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
138k
  xml_token->size = 4;
3785
3786
138k
  result = libfwevt_xml_document_substitute_template_value(
3787
138k
            internal_xml_document,
3788
138k
            binary_data,
3789
138k
            binary_data_size,
3790
138k
            ascii_codepage,
3791
138k
            flags,
3792
138k
            template_values_array,
3793
138k
            template_value_index,
3794
138k
            template_value_type,
3795
138k
            template_value_offset,
3796
138k
            xml_tag,
3797
138k
            element_recursion_depth,
3798
138k
            template_instance_recursion_depth,
3799
138k
            error );
3800
3801
138k
  if( result != 1 )
3802
5.29k
  {
3803
5.29k
    libcerror_error_set(
3804
5.29k
     error,
3805
5.29k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3806
5.29k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3807
5.29k
     "%s: unable to substitute template value.",
3808
5.29k
     function );
3809
3810
5.29k
    return( -1 );
3811
5.29k
  }
3812
133k
  return( 1 );
3813
138k
}
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.06M
{
3833
1.06M
  const uint8_t *xml_document_data = NULL;
3834
1.06M
  static char *function            = "libfwevt_xml_document_read_optional_substitution";
3835
1.06M
  size_t xml_document_data_size    = 0;
3836
1.06M
  uint16_t template_value_index    = 0;
3837
1.06M
  uint8_t template_value_type      = 0;
3838
1.06M
  int result                       = 0;
3839
3840
1.06M
  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.06M
  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.06M
  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.06M
  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.06M
  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.06M
  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.06M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3908
1.06M
  xml_document_data_size = binary_data_size - binary_data_offset;
3909
3910
1.06M
  if( xml_document_data_size < 4 )
3911
12
  {
3912
12
    libcerror_error_set(
3913
12
     error,
3914
12
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3915
12
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3916
12
     "%s: invalid binary XML document data size value too small.",
3917
12
     function );
3918
3919
12
    return( -1 );
3920
12
  }
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.06M
  byte_stream_copy_to_uint16_little_endian(
3939
1.06M
   &( xml_document_data[ 1 ] ),
3940
1.06M
   template_value_index );
3941
3942
1.06M
  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.06M
  xml_token->size = 4;
3972
3973
1.06M
  result = libfwevt_xml_document_substitute_template_value(
3974
1.06M
            internal_xml_document,
3975
1.06M
            binary_data,
3976
1.06M
            binary_data_size,
3977
1.06M
            ascii_codepage,
3978
1.06M
            flags,
3979
1.06M
            template_values_array,
3980
1.06M
            template_value_index,
3981
1.06M
            template_value_type,
3982
1.06M
            template_value_offset,
3983
1.06M
            xml_tag,
3984
1.06M
            element_recursion_depth,
3985
1.06M
            template_instance_recursion_depth,
3986
1.06M
            error );
3987
3988
1.06M
  if( result == -1 )
3989
6.45k
  {
3990
6.45k
    libcerror_error_set(
3991
6.45k
     error,
3992
6.45k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3993
6.45k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3994
6.45k
     "%s: unable to substitute template value.",
3995
6.45k
     function );
3996
3997
6.45k
    return( -1 );
3998
6.45k
  }
3999
1.05M
  return( result );
4000
1.06M
}
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.00k
{
4014
2.00k
  const uint8_t *xml_document_data = NULL;
4015
2.00k
  static char *function            = "libfwevt_xml_document_read_pi_data";
4016
2.00k
  size_t value_data_size           = 0;
4017
2.00k
  size_t xml_document_data_size    = 0;
4018
4019
2.00k
  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.00k
  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.00k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_PI_DATA )
4042
40
  {
4043
40
    libcerror_error_set(
4044
40
     error,
4045
40
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4046
40
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4047
40
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
4048
40
     function,
4049
40
     xml_token->type );
4050
4051
40
    return( -1 );
4052
40
  }
4053
1.96k
  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
1.96k
  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
1.96k
  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
1.96k
  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
1.96k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4098
1.96k
  xml_document_data_size = binary_data_size - binary_data_offset;
4099
4100
1.96k
  if( xml_document_data_size < 3 )
4101
10
  {
4102
10
    libcerror_error_set(
4103
10
     error,
4104
10
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4105
10
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4106
10
     "%s: invalid binary XML document data size value too small.",
4107
10
     function );
4108
4109
10
    return( -1 );
4110
10
  }
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
1.95k
  byte_stream_copy_to_uint16_little_endian(
4129
1.95k
   &( xml_document_data[ 1 ] ),
4130
1.95k
   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
1.95k
  xml_token->size     = 3;
4147
1.95k
  binary_data_offset += 3;
4148
4149
1.95k
  value_data_size *= 2;
4150
4151
1.95k
  if( ( value_data_size > binary_data_size )
4152
1.95k
   || ( 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
1.87k
  if( libfwevt_xml_tag_set_value_type(
4181
1.87k
       xml_tag,
4182
1.87k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
4183
1.87k
       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
1.87k
  if( libfwevt_xml_tag_set_value_data(
4195
1.87k
       xml_tag,
4196
1.87k
       &( binary_data[ binary_data_offset ] ),
4197
1.87k
       value_data_size,
4198
1.87k
       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
1.87k
  xml_token->size += value_data_size;
4230
4231
1.87k
  return( 1 );
4232
1.87k
}
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.17k
{
4247
2.17k
  libfwevt_xml_tag_t *pi_xml_tag      = NULL;
4248
2.17k
  libfwevt_xml_token_t *xml_sub_token = NULL;
4249
2.17k
  const uint8_t *xml_document_data    = NULL;
4250
2.17k
  static char *function               = "libfwevt_xml_document_read_pi_target";
4251
2.17k
  size_t additional_value_size        = 0;
4252
2.17k
  size_t trailing_data_size           = 0;
4253
2.17k
  size_t xml_document_data_offset     = 0;
4254
2.17k
  size_t xml_document_data_size       = 0;
4255
2.17k
  uint32_t pi_name_offset             = 0;
4256
2.17k
  uint32_t pi_name_size               = 0;
4257
4258
2.17k
  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.17k
  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.17k
  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.17k
  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.17k
  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.17k
  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.17k
  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.17k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
4337
2.17k
  {
4338
2.17k
    additional_value_size = 4;
4339
2.17k
  }
4340
2.17k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4341
2.17k
  xml_document_data_size = binary_data_size - binary_data_offset;
4342
4343
2.17k
  if( xml_document_data_size < ( 1 + additional_value_size ) )
4344
12
  {
4345
12
    libcerror_error_set(
4346
12
     error,
4347
12
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4348
12
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4349
12
     "%s: invalid binary XML document data size value too small.",
4350
12
     function );
4351
4352
12
    return( -1 );
4353
12
  }
4354
2.16k
  if( libfwevt_xml_tag_initialize(
4355
2.16k
       &pi_xml_tag,
4356
2.16k
       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.16k
  if( libfwevt_xml_tag_set_type(
4368
2.16k
       pi_xml_tag,
4369
2.16k
       LIBFWEVT_XML_TAG_TYPE_PI,
4370
2.16k
       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.16k
  xml_token->size          = 1;
4408
2.16k
  xml_document_data_offset = 1;
4409
4410
2.16k
  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.16k
  else
4417
2.16k
  {
4418
2.16k
    if( ( xml_document_data_size < 4 )
4419
2.16k
     || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
4420
3
    {
4421
3
      libcerror_error_set(
4422
3
       error,
4423
3
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4424
3
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4425
3
       "%s: invalid binary XML document data size value too small.",
4426
3
       function );
4427
4428
3
      goto on_error;
4429
3
    }
4430
2.16k
    byte_stream_copy_to_uint32_little_endian(
4431
2.16k
     &( xml_document_data[ xml_document_data_offset ] ),
4432
2.16k
     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.16k
    xml_token->size           = 4;
4444
2.16k
    xml_document_data_offset += 4;
4445
2.16k
  }
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.16k
  xml_token->size          = 5;
4458
2.16k
  xml_document_data_offset = 5;
4459
4460
2.16k
  if( pi_name_offset > ( binary_data_offset + xml_document_data_offset ) )
4461
129
  {
4462
129
    libcerror_error_set(
4463
129
     error,
4464
129
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4465
129
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4466
129
     "%s: invalid PI name offset value out of bounds.",
4467
129
     function );
4468
4469
129
    goto on_error;
4470
129
  }
4471
2.03k
  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.03k
  if( libfwevt_xml_document_read_name(
4496
2.03k
       internal_xml_document,
4497
2.03k
       binary_data,
4498
2.03k
       binary_data_size,
4499
2.03k
       pi_name_offset,
4500
2.03k
       flags,
4501
2.03k
       &pi_name_size,
4502
2.03k
       pi_xml_tag,
4503
2.03k
       error ) != 1 )
4504
8
  {
4505
8
    libcerror_error_set(
4506
8
     error,
4507
8
     LIBCERROR_ERROR_DOMAIN_IO,
4508
8
     LIBCERROR_IO_ERROR_READ_FAILED,
4509
8
     "%s: unable to read PI name.",
4510
8
     function );
4511
4512
8
    goto on_error;
4513
8
  }
4514
2.02k
  if( ( binary_data_offset + xml_document_data_offset ) == pi_name_offset )
4515
39
  {
4516
39
    xml_token->size          += pi_name_size;
4517
39
    xml_document_data_offset += pi_name_size;
4518
39
  }
4519
2.02k
  if( libfwevt_xml_token_initialize(
4520
2.02k
       &xml_sub_token,
4521
2.02k
       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.02k
  if( libfwevt_xml_token_read_data(
4533
2.02k
       xml_sub_token,
4534
2.02k
       binary_data,
4535
2.02k
       binary_data_size,
4536
2.02k
       binary_data_offset + xml_document_data_offset,
4537
2.02k
       error ) != 1 )
4538
15
  {
4539
15
    libcerror_error_set(
4540
15
     error,
4541
15
     LIBCERROR_ERROR_DOMAIN_IO,
4542
15
     LIBCERROR_IO_ERROR_READ_FAILED,
4543
15
     "%s: unable to read binary XML sub token.",
4544
15
     function );
4545
4546
15
    goto on_error;
4547
15
  }
4548
2.00k
  if( libfwevt_xml_document_read_pi_data(
4549
2.00k
       internal_xml_document,
4550
2.00k
       xml_sub_token,
4551
2.00k
       binary_data,
4552
2.00k
       binary_data_size,
4553
2.00k
       binary_data_offset + xml_document_data_offset,
4554
2.00k
       pi_xml_tag,
4555
2.00k
       error ) != 1 )
4556
133
  {
4557
133
    libcerror_error_set(
4558
133
     error,
4559
133
     LIBCERROR_ERROR_DOMAIN_IO,
4560
133
     LIBCERROR_IO_ERROR_READ_FAILED,
4561
133
     "%s: unable to read PI target.",
4562
133
     function );
4563
4564
133
    goto on_error;
4565
133
  }
4566
1.87k
  xml_token->size += xml_sub_token->size;
4567
4568
1.87k
  if( libfwevt_xml_token_free(
4569
1.87k
       &xml_sub_token,
4570
1.87k
       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
1.87k
  if( libfwevt_xml_tag_append_element(
4582
1.87k
       xml_tag,
4583
1.87k
       pi_xml_tag,
4584
1.87k
       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
1.87k
  pi_xml_tag = NULL;
4596
4597
1.87k
  return( 1 );
4598
4599
288
on_error:
4600
288
  if( xml_sub_token != NULL )
4601
148
  {
4602
148
    libfwevt_xml_token_free(
4603
148
     &xml_sub_token,
4604
148
     NULL );
4605
148
  }
4606
288
  if( pi_xml_tag != NULL )
4607
288
  {
4608
288
    libfwevt_internal_xml_tag_free(
4609
288
     (libfwevt_internal_xml_tag_t **) &pi_xml_tag,
4610
288
     NULL );
4611
288
  }
4612
288
  return( -1 );
4613
1.87k
}
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
88.4k
{
4631
88.4k
  libcdata_array_t *template_values_array  = NULL;
4632
88.4k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
4633
88.4k
  const uint8_t *xml_document_data         = NULL;
4634
88.4k
  static char *function                    = "libfwevt_xml_document_read_template_instance";
4635
88.4k
  size_t template_data_offset              = 0;
4636
88.4k
  size_t template_data_size                = 0;
4637
88.4k
  size_t template_values_data_offset       = 0;
4638
88.4k
  size_t template_values_data_size         = 0;
4639
88.4k
  size_t trailing_data_size                = 0;
4640
88.4k
  size_t xml_document_data_size            = 0;
4641
88.4k
  uint32_t template_definition_data_offset = 0;
4642
88.4k
  uint32_t template_definition_data_size   = 0;
4643
4644
#if defined( HAVE_DEBUG_OUTPUT )
4645
  uint32_t value_32bit                     = 0;
4646
#endif
4647
4648
88.4k
  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
88.4k
  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
88.4k
  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
88.4k
  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
88.4k
  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
88.4k
  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
88.4k
  if( ( template_instance_recursion_depth < 0 )
4716
88.4k
   || ( template_instance_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_INSTANCE_RECURSION_DEPTH ) )
4717
180
  {
4718
180
    libcerror_error_set(
4719
180
     error,
4720
180
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4721
180
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4722
180
     "%s: invalid template instance recursion depth value out of bounds.",
4723
180
     function );
4724
4725
180
    return( -1 );
4726
180
  }
4727
88.3k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4728
88.3k
  xml_document_data_size = binary_data_size - binary_data_offset;
4729
4730
88.3k
  if( ( binary_data_size < 10 )
4731
88.3k
   || ( binary_data_offset >= ( binary_data_size - 10 ) ) )
4732
22
  {
4733
22
    libcerror_error_set(
4734
22
     error,
4735
22
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4736
22
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4737
22
     "%s: invalid binary XML document data size value too small.",
4738
22
     function );
4739
4740
22
    goto on_error;
4741
22
  }
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
88.2k
  byte_stream_copy_to_uint32_little_endian(
4760
88.2k
   &( xml_document_data[ 6 ] ),
4761
88.2k
   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
88.2k
  xml_token->size     = 10;
4795
88.2k
  binary_data_offset += 10;
4796
4797
88.2k
  if( template_definition_data_offset >= binary_data_size )
4798
110
  {
4799
110
    libcerror_error_set(
4800
110
     error,
4801
110
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4802
110
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4803
110
     "%s: invalid template definition data offset value out of bounds.",
4804
110
     function );
4805
4806
110
    goto on_error;
4807
110
  }
4808
88.1k
  if( template_definition_data_offset > binary_data_offset )
4809
1.01k
  {
4810
1.01k
    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.01k
    xml_token->size    += trailing_data_size;
4830
1.01k
    binary_data_offset += trailing_data_size;
4831
1.01k
  }
4832
88.1k
  template_data_offset = template_definition_data_offset;
4833
4834
88.1k
  if( ( binary_data_size < 24 )
4835
88.1k
   || ( template_data_offset >= ( binary_data_size - 24 ) ) )
4836
67
  {
4837
67
    libcerror_error_set(
4838
67
     error,
4839
67
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4840
67
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4841
67
     "%s: invalid binary XML document data size value too small.",
4842
67
     function );
4843
4844
67
    goto on_error;
4845
67
  }
4846
88.1k
  byte_stream_copy_to_uint32_little_endian(
4847
88.1k
   &( binary_data[ template_data_offset + 20 ] ),
4848
88.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
88.1k
  if( template_definition_data_size > binary_data_size )
4890
179
  {
4891
179
    libcerror_error_set(
4892
179
     error,
4893
179
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4894
179
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4895
179
     "%s: invalid template definition data size value out of bounds.",
4896
179
     function );
4897
4898
179
    goto on_error;
4899
179
  }
4900
87.9k
  if( template_data_offset == binary_data_offset )
4901
1.73k
  {
4902
1.73k
    template_values_data_offset = 24 + template_definition_data_size;
4903
1.73k
  }
4904
86.2k
  else
4905
86.2k
  {
4906
86.2k
    template_values_data_offset = 0;
4907
86.2k
  }
4908
87.9k
  template_data_offset += 24;
4909
4910
87.9k
  if( template_values_data_offset >= xml_document_data_size )
4911
40
  {
4912
40
    libcerror_error_set(
4913
40
     error,
4914
40
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4915
40
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4916
40
     "%s: invalid template values data offset value out of bounds.",
4917
40
     function );
4918
4919
40
    goto on_error;
4920
40
  }
4921
87.9k
  if( libfwevt_xml_document_read_template_instance_values(
4922
87.9k
       internal_xml_document,
4923
87.9k
       binary_data,
4924
87.9k
       binary_data_size,
4925
87.9k
       binary_data_offset + template_values_data_offset,
4926
87.9k
       &template_values_array,
4927
87.9k
       &template_values_data_size,
4928
87.9k
       error ) != 1 )
4929
376
  {
4930
376
    libcerror_error_set(
4931
376
     error,
4932
376
     LIBCERROR_ERROR_DOMAIN_IO,
4933
376
     LIBCERROR_IO_ERROR_READ_FAILED,
4934
376
     "%s: unable to read document template instance values.",
4935
376
     function );
4936
4937
376
    goto on_error;
4938
376
  }
4939
87.5k
  xml_token->size += template_values_data_size;
4940
4941
87.5k
  if( libfwevt_xml_token_initialize(
4942
87.5k
       &xml_sub_token,
4943
87.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
87.5k
  if( libfwevt_xml_token_read_data(
4955
87.5k
       xml_sub_token,
4956
87.5k
       binary_data,
4957
87.5k
       binary_data_size,
4958
87.5k
       template_data_offset,
4959
87.5k
       error ) != 1 )
4960
17
  {
4961
17
    libcerror_error_set(
4962
17
     error,
4963
17
     LIBCERROR_ERROR_DOMAIN_IO,
4964
17
     LIBCERROR_IO_ERROR_READ_FAILED,
4965
17
     "%s: unable to read binary XML sub token.",
4966
17
     function );
4967
4968
17
    goto on_error;
4969
17
  }
4970
87.5k
  if( libfwevt_xml_document_read_fragment_header(
4971
87.5k
       internal_xml_document,
4972
87.5k
       xml_sub_token,
4973
87.5k
       binary_data,
4974
87.5k
       binary_data_size,
4975
87.5k
       template_data_offset,
4976
87.5k
       error ) != 1 )
4977
102
  {
4978
102
    libcerror_error_set(
4979
102
     error,
4980
102
     LIBCERROR_ERROR_DOMAIN_IO,
4981
102
     LIBCERROR_IO_ERROR_READ_FAILED,
4982
102
     "%s: unable to read fragment header.",
4983
102
     function );
4984
4985
102
    goto on_error;
4986
102
  }
4987
87.4k
  template_data_offset += xml_sub_token->size;
4988
4989
87.4k
  if( libfwevt_xml_token_read_data(
4990
87.4k
       xml_sub_token,
4991
87.4k
       binary_data,
4992
87.4k
       binary_data_size,
4993
87.4k
       template_data_offset,
4994
87.4k
       error ) != 1 )
4995
5
  {
4996
5
    libcerror_error_set(
4997
5
     error,
4998
5
     LIBCERROR_ERROR_DOMAIN_IO,
4999
5
     LIBCERROR_IO_ERROR_READ_FAILED,
5000
5
     "%s: unable to read binary XML sub token.",
5001
5
     function );
5002
5003
5
    goto on_error;
5004
5
  }
5005
87.4k
  if( libfwevt_xml_document_read_element(
5006
87.4k
       internal_xml_document,
5007
87.4k
       xml_sub_token,
5008
87.4k
       binary_data,
5009
87.4k
       binary_data_size,
5010
87.4k
       template_data_offset,
5011
87.4k
       ascii_codepage,
5012
87.4k
       flags,
5013
87.4k
       template_values_array,
5014
87.4k
       xml_tag,
5015
87.4k
       element_recursion_depth + 1,
5016
87.4k
       template_instance_recursion_depth,
5017
87.4k
       error ) != 1 )
5018
5.03k
  {
5019
5.03k
    libcerror_error_set(
5020
5.03k
     error,
5021
5.03k
     LIBCERROR_ERROR_DOMAIN_IO,
5022
5.03k
     LIBCERROR_IO_ERROR_READ_FAILED,
5023
5.03k
     "%s: unable to read element.",
5024
5.03k
     function );
5025
5026
5.03k
    goto on_error;
5027
5.03k
  }
5028
82.3k
  template_data_offset += xml_sub_token->size;
5029
5030
82.3k
  if( libfwevt_xml_token_read_data(
5031
82.3k
       xml_sub_token,
5032
82.3k
       binary_data,
5033
82.3k
       binary_data_size,
5034
82.3k
       template_data_offset,
5035
82.3k
       error ) != 1 )
5036
8
  {
5037
8
    libcerror_error_set(
5038
8
     error,
5039
8
     LIBCERROR_ERROR_DOMAIN_IO,
5040
8
     LIBCERROR_IO_ERROR_READ_FAILED,
5041
8
     "%s: unable to read binary XML sub token.",
5042
8
     function );
5043
5044
8
    goto on_error;
5045
8
  }
5046
82.3k
  if( xml_sub_token->type != LIBFWEVT_XML_TOKEN_END_OF_FILE )
5047
13
  {
5048
13
    libcerror_error_set(
5049
13
     error,
5050
13
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5051
13
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5052
13
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
5053
13
     function,
5054
13
     xml_token->type );
5055
5056
13
    goto on_error;
5057
13
  }
5058
82.3k
  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
82.3k
  template_data_offset += 1;
5099
5100
82.3k
  if( libfwevt_xml_token_free(
5101
82.3k
       &xml_sub_token,
5102
82.3k
       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
82.3k
  if( template_definition_data_offset == binary_data_offset )
5114
459
  {
5115
459
    template_data_size = template_data_offset
5116
459
                       - template_definition_data_offset;
5117
5118
459
    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
459
    if( template_definition_data_size < ( template_data_size - 24 ) )
5125
6
    {
5126
6
      libcerror_error_set(
5127
6
       error,
5128
6
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5129
6
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5130
6
       "%s: invalid template definition data size value too small.",
5131
6
       function );
5132
5133
6
      goto on_error;
5134
6
    }
5135
453
    template_definition_data_size -= (uint32_t) ( template_data_size - 24 );
5136
453
  }
5137
/* TODO check if template_definition_data_size is 0 */
5138
5139
82.3k
  if( libcdata_array_free(
5140
82.3k
       &template_values_array,
5141
82.3k
       (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5142
82.3k
       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
82.3k
  return( 1 );
5154
5155
5.98k
on_error:
5156
5.98k
  if( template_values_array != NULL )
5157
5.18k
  {
5158
5.18k
    libcdata_array_free(
5159
5.18k
     &template_values_array,
5160
5.18k
     (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5161
5.18k
     NULL );
5162
5.18k
  }
5163
5.98k
  if( xml_sub_token != NULL )
5164
5.18k
  {
5165
5.18k
    libfwevt_xml_token_free(
5166
5.18k
     &xml_sub_token,
5167
5.18k
     NULL );
5168
5.18k
  }
5169
5.98k
  return( -1 );
5170
82.3k
}
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
87.9k
{
5184
87.9k
  libfwevt_xml_template_value_t *template_value = NULL;
5185
87.9k
  static char *function                         = "libfwevt_xml_document_read_template_instance_values";
5186
87.9k
  size_t safe_template_values_size              = 0;
5187
87.9k
  size_t template_value_definitions_data_size   = 0;
5188
87.9k
  size_t template_values_data_size              = 0;
5189
87.9k
  uint32_t number_of_template_values            = 0;
5190
87.9k
  uint32_t template_value_index                 = 0;
5191
87.9k
  uint16_t template_value_data_size             = 0;
5192
87.9k
  uint8_t template_value_type                   = 0;
5193
5194
87.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
87.9k
  if( ( binary_data_size < 4 )
5206
87.9k
   || ( binary_data_offset >= ( binary_data_size - 4 ) ) )
5207
28
  {
5208
28
    libcerror_error_set(
5209
28
     error,
5210
28
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5211
28
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5212
28
     "%s: invalid binary data size value out of bounds.",
5213
28
     function );
5214
5215
28
    return( -1 );
5216
28
  }
5217
87.8k
  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
87.8k
  byte_stream_copy_to_uint32_little_endian(
5246
87.8k
   &( binary_data[ binary_data_offset ] ),
5247
87.8k
   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
87.8k
  safe_template_values_size = 4;
5262
87.8k
  binary_data_offset       += 4;
5263
5264
87.8k
  template_value_definitions_data_size = number_of_template_values * 4;
5265
5266
87.8k
  if( ( template_value_definitions_data_size > binary_data_size )
5267
87.8k
   || ( binary_data_offset >= ( binary_data_size - template_value_definitions_data_size ) ) )
5268
157
  {
5269
157
    libcerror_error_set(
5270
157
     error,
5271
157
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5272
157
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5273
157
     "%s: invalid template value definitions data size value out of bounds.",
5274
157
     function );
5275
5276
157
    goto on_error;
5277
157
  }
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
87.7k
  if( libcdata_array_initialize(
5296
87.7k
       template_values_array,
5297
87.7k
       number_of_template_values,
5298
87.7k
       error ) != 1 )
5299
31
  {
5300
31
    libcerror_error_set(
5301
31
     error,
5302
31
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5303
31
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5304
31
     "%s: unable to create template values array.",
5305
31
     function );
5306
5307
31
    goto on_error;
5308
31
  }
5309
87.6k
  for( template_value_index = 0;
5310
3.80M
       template_value_index < number_of_template_values;
5311
3.71M
       template_value_index++ )
5312
3.71M
  {
5313
3.71M
    byte_stream_copy_to_uint16_little_endian(
5314
3.71M
     &( binary_data[ binary_data_offset ] ),
5315
3.71M
     template_value_data_size );
5316
5317
3.71M
    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.71M
    safe_template_values_size += 4;
5350
3.71M
    binary_data_offset        += 4;
5351
5352
3.71M
    template_values_data_size += template_value_data_size;
5353
5354
3.71M
    if( libfwevt_xml_template_value_initialize(
5355
3.71M
         &template_value,
5356
3.71M
         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.71M
    if( libfwevt_xml_template_value_set_type(
5368
3.71M
         template_value,
5369
3.71M
         template_value_type,
5370
3.71M
         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.71M
    if( libfwevt_xml_template_value_set_size(
5386
3.71M
         template_value,
5387
3.71M
         template_value_data_size,
5388
3.71M
         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.71M
    if( libcdata_array_set_entry_by_index(
5404
3.71M
         *template_values_array,
5405
3.71M
         (int) template_value_index,
5406
3.71M
         (intptr_t *) template_value,
5407
3.71M
         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.71M
    template_value = NULL;
5424
3.71M
  }
5425
87.6k
  if( ( template_values_data_size > binary_data_size )
5426
87.6k
   || ( binary_data_offset >= ( binary_data_size - template_values_data_size ) ) )
5427
160
  {
5428
160
    libcerror_error_set(
5429
160
     error,
5430
160
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5431
160
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5432
160
     "%s: invalid template values data size value out of bounds.",
5433
160
     function );
5434
5435
160
    goto on_error;
5436
160
  }
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
87.5k
  for( template_value_index = 0;
5455
2.13M
       template_value_index < number_of_template_values;
5456
2.05M
       template_value_index++ )
5457
2.05M
  {
5458
2.05M
    if( libcdata_array_get_entry_by_index(
5459
2.05M
         *template_values_array,
5460
2.05M
         (int) template_value_index,
5461
2.05M
         (intptr_t **) &template_value,
5462
2.05M
         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.05M
    if( libfwevt_xml_template_value_get_size(
5475
2.05M
         template_value,
5476
2.05M
         &template_value_data_size,
5477
2.05M
         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.05M
    if( template_value_data_size == 0 )
5510
1.27M
    {
5511
1.27M
      continue;
5512
1.27M
    }
5513
775k
    if( libfwevt_xml_template_value_set_offset(
5514
775k
         template_value,
5515
775k
         binary_data_offset,
5516
775k
         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
775k
    binary_data_offset += template_value_data_size;
5528
775k
  }
5529
87.5k
  *template_values_size = safe_template_values_size + template_values_data_size;
5530
5531
87.5k
  return( 1 );
5532
5533
348
on_error:
5534
348
  if( template_values_array != NULL )
5535
348
  {
5536
348
    libcdata_array_free(
5537
348
     template_values_array,
5538
348
     (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5539
348
     NULL );
5540
348
  }
5541
348
  return( -1 );
5542
87.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.01M
{
5556
1.01M
  const uint8_t *xml_document_data = NULL;
5557
1.01M
  static char *function            = "libfwevt_xml_document_read_value";
5558
1.01M
  size_t value_data_size           = 0;
5559
1.01M
  size_t xml_document_data_size    = 0;
5560
1.01M
  uint8_t value_type               = 0;
5561
1.01M
  int data_segment_index           = 0;
5562
5563
1.01M
  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.01M
  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.01M
  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.01M
  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.01M
  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.01M
  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.01M
  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.01M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
5642
1.01M
  xml_document_data_size = binary_data_size - binary_data_offset;
5643
5644
1.01M
  if( xml_document_data_size < 4 )
5645
38
  {
5646
38
    libcerror_error_set(
5647
38
     error,
5648
38
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5649
38
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5650
38
     "%s: invalid binary XML document data size value too small.",
5651
38
     function );
5652
5653
38
    return( -1 );
5654
38
  }
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.01M
  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.01M
  xml_token->size     = 4;
5693
1.01M
  binary_data_offset += 4;
5694
5695
1.01M
  switch( value_type )
5696
1.01M
  {
5697
1.01M
    case LIBFWEVT_VALUE_TYPE_STRING_UTF16:
5698
1.01M
      byte_stream_copy_to_uint16_little_endian(
5699
1.01M
       &( xml_document_data[ 2 ] ),
5700
1.01M
       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.01M
      value_data_size *= 2;
5712
5713
1.01M
      break;
5714
5715
33
    default:
5716
33
      libcerror_error_set(
5717
33
       error,
5718
33
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5719
33
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5720
33
       "%s: unsupported value type: 0x%02" PRIx8 ".",
5721
33
       function,
5722
33
       value_type );
5723
5724
33
      return( -1 );
5725
1.01M
  }
5726
1.01M
  if( ( value_data_size > binary_data_size )
5727
1.01M
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
5728
104
  {
5729
104
    libcerror_error_set(
5730
104
     error,
5731
104
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5732
104
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5733
104
     "%s: invalid value data size value out of bounds.",
5734
104
     function );
5735
5736
104
    return( -1 );
5737
104
  }
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.01M
  if( libfwevt_xml_tag_set_value_type(
5756
1.01M
       xml_tag,
5757
1.01M
       value_type,
5758
1.01M
       error ) != 1 )
5759
4
  {
5760
4
    libcerror_error_set(
5761
4
     error,
5762
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5763
4
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5764
4
     "%s: unable to set value type.",
5765
4
     function );
5766
5767
4
    return( -1 );
5768
4
  }
5769
1.01M
  if( libfwevt_xml_tag_append_value_data(
5770
1.01M
       xml_tag,
5771
1.01M
       &( binary_data[ binary_data_offset ] ),
5772
1.01M
       value_data_size,
5773
1.01M
       &data_segment_index,
5774
1.01M
       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.01M
  xml_token->size += value_data_size;
5807
  
5808
1.01M
  return( 1 );
5809
1.01M
}
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.19M
{
5829
1.19M
  libfwevt_xml_template_value_t *template_value = NULL;
5830
1.19M
  libfwevt_xml_token_t *xml_sub_token           = NULL;
5831
1.19M
  const uint8_t *template_value_data            = NULL;
5832
1.19M
  static char *function                         = "libfwevt_xml_document_substitute_template_value";
5833
1.19M
  size_t binary_data_offset                     = 0;
5834
1.19M
  size_t safe_template_value_offset             = 0;
5835
1.19M
  size_t template_value_data_offset             = 0;
5836
1.19M
  size_t template_value_data_size               = 0;
5837
1.19M
  size_t template_value_size                    = 0;
5838
1.19M
  uint16_t substitution_value_data_size         = 0;
5839
1.19M
  uint8_t substitution_value_type               = 0;
5840
1.19M
  uint8_t template_value_flags                  = 0;
5841
5842
1.19M
  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.19M
  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.19M
  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.19M
  if( libcdata_array_get_entry_by_index(
5876
1.19M
       template_values_array,
5877
1.19M
       (int) template_value_index,
5878
1.19M
       (intptr_t **) &template_value,
5879
1.19M
       error ) != 1 )
5880
124
  {
5881
124
    libcerror_error_set(
5882
124
     error,
5883
124
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5884
124
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5885
124
     "%s: unable to retrieve template value: %" PRIu16 " from array.",
5886
124
     function,
5887
124
     template_value_index );
5888
5889
124
    goto on_error;
5890
124
  }
5891
1.19M
  if( libfwevt_xml_template_value_get_flags(
5892
1.19M
       template_value,
5893
1.19M
       &template_value_flags,
5894
1.19M
       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.19M
  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.19M
  else
5910
1.19M
  {
5911
1.19M
    if( libfwevt_xml_template_value_get_type(
5912
1.19M
         template_value,
5913
1.19M
         &substitution_value_type,
5914
1.19M
         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.19M
  }
5926
1.19M
  if( libfwevt_xml_template_value_get_offset(
5927
1.19M
       template_value,
5928
1.19M
       &binary_data_offset,
5929
1.19M
       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.19M
  if( libfwevt_xml_template_value_get_size(
5941
1.19M
       template_value,
5942
1.19M
       &substitution_value_data_size,
5943
1.19M
       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.19M
  if( substitution_value_type == LIBFWEVT_VALUE_TYPE_NULL )
5996
177k
  {
5997
177k
    *template_value_offset = 0;
5998
5999
177k
    return( 0 );
6000
177k
  }
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
1.02M
  if( substitution_value_type == LIBFWEVT_VALUE_TYPE_BINARY_XML )
6024
81.2k
  {
6025
81.2k
    if( libfwevt_xml_token_initialize(
6026
81.2k
         &xml_sub_token,
6027
81.2k
         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
81.2k
    if( libfwevt_xml_token_read_data(
6039
81.2k
         xml_sub_token,
6040
81.2k
         binary_data,
6041
81.2k
         binary_data_size,
6042
81.2k
         binary_data_offset,
6043
81.2k
         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
81.2k
    switch( xml_sub_token->type & 0xbf )
6055
81.2k
    {
6056
8.35k
      case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
6057
8.35k
        if( libfwevt_xml_document_read_element(
6058
8.35k
             internal_xml_document,
6059
8.35k
             xml_sub_token,
6060
8.35k
             binary_data,
6061
8.35k
             binary_data_size,
6062
8.35k
             binary_data_offset,
6063
8.35k
             ascii_codepage,
6064
8.35k
             flags,
6065
8.35k
             template_values_array,
6066
8.35k
             xml_tag,
6067
8.35k
             element_recursion_depth + 1,
6068
8.35k
             template_instance_recursion_depth,
6069
8.35k
             error ) != 1 )
6070
8.06k
        {
6071
8.06k
          libcerror_error_set(
6072
8.06k
           error,
6073
8.06k
           LIBCERROR_ERROR_DOMAIN_IO,
6074
8.06k
           LIBCERROR_IO_ERROR_READ_FAILED,
6075
8.06k
           "%s: unable to read element.",
6076
8.06k
           function );
6077
6078
8.06k
          goto on_error;
6079
8.06k
        }
6080
298
        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.01k
        {
6097
3.01k
          libcerror_error_set(
6098
3.01k
           error,
6099
3.01k
           LIBCERROR_ERROR_DOMAIN_IO,
6100
3.01k
           LIBCERROR_IO_ERROR_READ_FAILED,
6101
3.01k
           "%s: unable to read fragment header.",
6102
3.01k
           function );
6103
6104
3.01k
          goto on_error;
6105
3.01k
        }
6106
24.1k
        break;
6107
6108
45.7k
      case LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE:
6109
45.7k
        if( libfwevt_xml_document_read_template_instance(
6110
45.7k
             internal_xml_document,
6111
45.7k
             xml_sub_token,
6112
45.7k
             binary_data,
6113
45.7k
             binary_data_size,
6114
45.7k
             binary_data_offset,
6115
45.7k
             ascii_codepage,
6116
45.7k
             flags,
6117
45.7k
             xml_tag,
6118
45.7k
             element_recursion_depth,
6119
45.7k
             template_instance_recursion_depth + 1,
6120
45.7k
             error ) != 1 )
6121
386
        {
6122
386
          libcerror_error_set(
6123
386
           error,
6124
386
           LIBCERROR_ERROR_DOMAIN_IO,
6125
386
           LIBCERROR_IO_ERROR_READ_FAILED,
6126
386
           "%s: unable to read document template instance.",
6127
386
           function );
6128
6129
386
          goto on_error;
6130
386
        }
6131
45.3k
        break;
6132
6133
45.3k
      default:
6134
11
        libcerror_error_set(
6135
11
         error,
6136
11
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6137
11
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6138
11
         "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
6139
11
         function,
6140
11
         xml_sub_token->type );
6141
6142
11
        goto on_error;
6143
81.2k
    }
6144
69.7k
    if( libfwevt_xml_token_free(
6145
69.7k
         &xml_sub_token,
6146
69.7k
         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.7k
  }
6158
940k
  else
6159
940k
  {
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
940k
    switch( substitution_value_type )
6164
940k
    {
6165
69.4k
      case LIBFWEVT_VALUE_TYPE_STRING_UTF16:
6166
81.8k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_UTF16:
6167
81.8k
        break;
6168
6169
494
      case LIBFWEVT_VALUE_TYPE_STRING_BYTE_STREAM:
6170
68.4k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_BYTE_STREAM:
6171
68.4k
        break;
6172
6173
9.06k
      case LIBFWEVT_VALUE_TYPE_INTEGER_8BIT:
6174
15.1k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_8BIT:
6175
15.1k
        template_value_size = 1;
6176
15.1k
        break;
6177
6178
236k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_8BIT:
6179
245k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_8BIT:
6180
245k
        template_value_size = 1;
6181
245k
        break;
6182
6183
9.03k
      case LIBFWEVT_VALUE_TYPE_INTEGER_16BIT:
6184
9.80k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_16BIT:
6185
9.80k
        template_value_size = 2;
6186
9.80k
        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
471
      case LIBFWEVT_VALUE_TYPE_INTEGER_32BIT:
6194
1.07k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_32BIT:
6195
1.07k
        template_value_size = 4;
6196
1.07k
        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
857
      case LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_32BIT:
6204
1.35k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_HEXADECIMAL_INTEGER_32BIT:
6205
1.35k
        template_value_size = 4;
6206
1.35k
        break;
6207
6208
563
      case LIBFWEVT_VALUE_TYPE_INTEGER_64BIT:
6209
1.31k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_64BIT:
6210
1.31k
        template_value_size = 8;
6211
1.31k
        break;
6212
6213
36.4k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_64BIT:
6214
37.2k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_64BIT:
6215
37.2k
        template_value_size = 8;
6216
37.2k
        break;
6217
6218
69.7k
      case LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_64BIT:
6219
70.2k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_HEXADECIMAL_INTEGER_64BIT:
6220
70.2k
        template_value_size = 8;
6221
70.2k
        break;
6222
6223
503
      case LIBFWEVT_VALUE_TYPE_FLOATING_POINT_32BIT:
6224
952
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FLOATING_POINT_32BIT:
6225
952
        template_value_size = 4;
6226
952
        break;
6227
6228
566
      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
536
      case LIBFWEVT_VALUE_TYPE_BOOLEAN:
6234
536
        template_value_size = 4;
6235
536
        break;
6236
6237
20.9k
      case LIBFWEVT_VALUE_TYPE_BINARY_DATA:
6238
20.9k
        break;
6239
6240
422
      case LIBFWEVT_VALUE_TYPE_GUID:
6241
843
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_GUID:
6242
843
        template_value_size = 16;
6243
843
        break;
6244
6245
/* TODO how to deal with array types ? */
6246
1.84k
      case LIBFWEVT_VALUE_TYPE_SIZE:
6247
1.84k
        if( ( substitution_value_data_size != 4 )
6248
1.84k
         && ( substitution_value_data_size != 8 ) )
6249
33
        {
6250
33
          libcerror_error_set(
6251
33
           error,
6252
33
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6253
33
           LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6254
33
           "%s: unsupported value data size: %" PRIu16 ".",
6255
33
           function,
6256
33
           substitution_value_data_size );
6257
6258
33
          goto on_error;
6259
33
        }
6260
1.81k
        break;
6261
6262
69.4k
      case LIBFWEVT_VALUE_TYPE_FILETIME:
6263
69.9k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FILETIME:
6264
69.9k
        template_value_size = 8;
6265
69.9k
        break;
6266
6267
209
      case LIBFWEVT_VALUE_TYPE_SYSTEMTIME:
6268
1.51k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_SYSTEMTIME:
6269
1.51k
        template_value_size = 16;
6270
1.51k
        break;
6271
6272
3.40k
      case LIBFWEVT_VALUE_TYPE_NT_SECURITY_IDENTIFIER:
6273
3.40k
        break;
6274
6275
13
      default:
6276
13
        libcerror_error_set(
6277
13
         error,
6278
13
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6279
13
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6280
13
         "%s: unsupported value type: 0x%02" PRIx8 ".",
6281
13
         function,
6282
13
         substitution_value_type );
6283
6284
13
        goto on_error;
6285
940k
    }
6286
940k
    if( libfwevt_xml_tag_set_value_type(
6287
940k
         xml_tag,
6288
940k
         substitution_value_type,
6289
940k
         error ) != 1 )
6290
4
    {
6291
4
      libcerror_error_set(
6292
4
       error,
6293
4
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6294
4
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6295
4
       "%s: unable to set value type.",
6296
4
       function );
6297
6298
4
      goto on_error;
6299
4
    }
6300
940k
    if( ( substitution_value_type & LIBFWEVT_VALUE_TYPE_ARRAY ) != 0 )
6301
104k
    {
6302
104k
      safe_template_value_offset = *template_value_offset;
6303
6304
104k
      if( substitution_value_data_size > 0 )
6305
100k
      {
6306
100k
        if( safe_template_value_offset >= (size_t) substitution_value_data_size )
6307
24
        {
6308
24
          libcerror_error_set(
6309
24
           error,
6310
24
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6311
24
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6312
24
           "%s: invalid template value offset value out of bounds.",
6313
24
           function );
6314
6315
24
          goto on_error;
6316
24
        }
6317
100k
        template_value_data      = &( binary_data[ binary_data_offset + safe_template_value_offset ] );
6318
100k
        template_value_data_size = substitution_value_data_size - (uint16_t) safe_template_value_offset;
6319
100k
      }
6320
104k
      if( template_value_data_size > 0 )
6321
100k
      {
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
100k
        if( substitution_value_type == LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_BYTE_STREAM )
6335
67.5k
        {
6336
67.5k
          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
870k
          while( template_value_data_offset < template_value_data_size ) 
6348
868k
          {
6349
868k
            if( template_value_data[ template_value_data_offset ] == 0 )
6350
65.6k
            {
6351
65.6k
              template_value_data_offset += 1;
6352
6353
65.6k
              break;
6354
65.6k
            }
6355
802k
            template_value_data_offset += 1;
6356
802k
          }
6357
67.5k
          template_value_data_size = template_value_data_offset;
6358
67.5k
        }
6359
33.0k
        else if( substitution_value_type == LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_UTF16 )
6360
12.0k
        {
6361
12.0k
          if( ( template_value_data_size < 2 )
6362
12.0k
           && ( ( template_value_data_size % 2 ) != 0 ) )
6363
2
          {
6364
2
            libcerror_error_set(
6365
2
             error,
6366
2
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6367
2
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6368
2
             "%s: invalid UTF-16 template value data size value out of bounds.",
6369
2
             function );
6370
6371
2
            goto on_error;
6372
2
          }
6373
1.00M
          while( template_value_data_offset < template_value_data_size ) 
6374
1.00M
          {
6375
1.00M
            if( ( template_value_data[ template_value_data_offset ] == 0 )
6376
1.00M
             && ( template_value_data[ template_value_data_offset + 1 ] == 0 ) )
6377
11.3k
            {
6378
11.3k
              template_value_data_offset += 2;
6379
6380
11.3k
              break;
6381
11.3k
            }
6382
996k
            template_value_data_offset += 2;
6383
996k
          }
6384
12.0k
          template_value_data_size = template_value_data_offset;
6385
12.0k
        }
6386
21.0k
        else
6387
21.0k
        {
6388
21.0k
          if( template_value_size > template_value_data_size )
6389
29
          {
6390
29
            libcerror_error_set(
6391
29
             error,
6392
29
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6393
29
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6394
29
             "%s: invalid template value size value out of bounds.",
6395
29
             function );
6396
6397
29
            goto on_error;
6398
29
          }
6399
21.0k
          template_value_data_size = template_value_size;
6400
21.0k
        }
6401
100k
      }
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
104k
      if( template_value_data_size > 0 )
6406
100k
      {
6407
100k
        if( libfwevt_xml_tag_set_value_data(
6408
100k
             xml_tag,
6409
100k
             template_value_data,
6410
100k
             template_value_data_size,
6411
100k
             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
100k
        safe_template_value_offset += template_value_data_size;
6423
100k
      }
6424
104k
      if( safe_template_value_offset == substitution_value_data_size )
6425
7.96k
      {
6426
7.96k
        safe_template_value_offset = 0;
6427
7.96k
      }
6428
104k
    }
6429
836k
    else
6430
836k
    {
6431
836k
      if( ( template_value_size != 0 )
6432
836k
       && ( template_value_size != substitution_value_data_size ) )
6433
34
      {
6434
34
        libcerror_error_set(
6435
34
         error,
6436
34
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6437
34
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6438
34
         "%s: invalid substitution value data size value out of bounds.",
6439
34
         function );
6440
6441
34
        goto on_error;
6442
34
      }
6443
836k
      else if( ( substitution_value_type == LIBFWEVT_VALUE_TYPE_STRING_UTF16 )
6444
836k
            && ( ( 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
836k
      if( libfwevt_xml_tag_set_value_data(
6456
836k
           xml_tag,
6457
836k
           &( binary_data[ binary_data_offset ] ),
6458
836k
           (size_t) substitution_value_data_size,
6459
836k
           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
836k
    }
6471
940k
    if( libfwevt_xml_tag_set_flags(
6472
940k
         xml_tag,
6473
940k
         LIBFWEVT_XML_TAG_FLAG_IS_TEMPLATE_DEFINITION,
6474
940k
         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
940k
  }
6506
1.01M
  *template_value_offset = safe_template_value_offset;
6507
6508
1.01M
  return( 1 );
6509
6510
11.7k
on_error:
6511
11.7k
  if( xml_sub_token != NULL )
6512
11.4k
  {
6513
11.4k
    libfwevt_xml_token_free(
6514
11.4k
     &xml_sub_token,
6515
11.4k
     NULL );
6516
11.4k
  }
6517
11.7k
  return( -1 );
6518
1.02M
}
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