Coverage Report

Created: 2025-06-13 07:22

/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.95k
{
49
4.95k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
50
4.95k
  static char *function                                   = "libfwevt_xml_document_initialize";
51
52
4.95k
  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.95k
  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.95k
  internal_xml_document = memory_allocate_structure(
75
4.95k
                           libfwevt_internal_xml_document_t );
76
77
4.95k
  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.95k
  if( memory_set(
89
4.95k
       internal_xml_document,
90
4.95k
       0,
91
4.95k
       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.95k
  *xml_document = (libfwevt_xml_document_t *) internal_xml_document;
103
104
4.95k
  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.95k
}
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.95k
{
122
4.95k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
123
4.95k
  static char *function                                   = "libfwevt_xml_document_free";
124
4.95k
  int result                                              = 1;
125
126
4.95k
  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.95k
  if( *xml_document != NULL )
138
4.95k
  {
139
4.95k
    internal_xml_document = (libfwevt_internal_xml_document_t *) *xml_document;
140
4.95k
    *xml_document         = NULL;
141
142
4.95k
    if( internal_xml_document->root_xml_tag != NULL )
143
428
    {
144
428
      if( libfwevt_internal_xml_tag_free(
145
428
           (libfwevt_internal_xml_tag_t **) &( internal_xml_document->root_xml_tag ),
146
428
           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
428
    }
158
4.95k
    memory_free(
159
4.95k
     internal_xml_document );
160
4.95k
  }
161
4.95k
  return( result );
162
4.95k
}
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.95k
{
216
4.95k
  static char *function = "libfwevt_xml_document_read";
217
218
4.95k
  if( libfwevt_xml_document_read_with_template_values(
219
4.95k
       xml_document,
220
4.95k
       binary_data,
221
4.95k
       binary_data_size,
222
4.95k
       binary_data_offset,
223
4.95k
       ascii_codepage,
224
4.95k
       flags,
225
4.95k
       NULL,
226
4.95k
       error ) != 1 )
227
4.87k
  {
228
4.87k
    libcerror_error_set(
229
4.87k
     error,
230
4.87k
     LIBCERROR_ERROR_DOMAIN_IO,
231
4.87k
     LIBCERROR_IO_ERROR_READ_FAILED,
232
4.87k
     "%s: unable to read XML document.",
233
4.87k
     function );
234
235
4.87k
    return( -1 );
236
4.87k
  }
237
80
  return( 1 );
238
4.95k
}
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.95k
{
253
4.95k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
254
4.95k
  libfwevt_xml_token_t *xml_token                         = NULL;
255
4.95k
  static char *function                                   = "libfwevt_xml_document_read_with_template_values";
256
4.95k
  uint8_t supported_flags                                 = 0;
257
258
4.95k
  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.95k
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
270
271
4.95k
  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.95k
  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.95k
  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.95k
  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.95k
  supported_flags = LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS
316
4.95k
                  | LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DEPENDENCY_IDENTIFIERS;
317
318
4.95k
  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.95k
  if( libfwevt_xml_token_initialize(
331
4.95k
       &xml_token,
332
4.95k
       error ) != 1 )
333
0
  {
334
0
    libcerror_error_set(
335
0
     error,
336
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
337
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
338
0
     "%s: unable to create binary XML token.",
339
0
     function );
340
341
0
    goto on_error;
342
0
  }
343
16.5k
  while( binary_data_offset < binary_data_size )
344
16.5k
  {
345
16.5k
    if( libfwevt_xml_token_read_data(
346
16.5k
         xml_token,
347
16.5k
         binary_data,
348
16.5k
         binary_data_size,
349
16.5k
         binary_data_offset,
350
16.5k
         error ) != 1 )
351
18
    {
352
18
      libcerror_error_set(
353
18
       error,
354
18
       LIBCERROR_ERROR_DOMAIN_IO,
355
18
       LIBCERROR_IO_ERROR_READ_FAILED,
356
18
       "%s: unable to read binary XML token.",
357
18
       function );
358
359
18
      goto on_error;
360
18
    }
361
/* TODO check for prologue */
362
/* TODO validate the order */
363
/* TODO check for Miscellaneous before end of file token */
364
16.5k
    switch( xml_token->type & 0xbf )
365
16.5k
    {
366
91
      case LIBFWEVT_XML_TOKEN_END_OF_FILE:
367
91
        if( ( binary_data_size < 1 )
368
91
         || ( binary_data_offset >= ( binary_data_size - 1 ) ) )
369
13
        {
370
13
          libcerror_error_set(
371
13
           error,
372
13
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
373
13
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
374
13
           "%s: invalid binary XML document data size value too small.",
375
13
           function );
376
377
13
          goto on_error;
378
13
        }
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
78
        xml_token->size = 1;
409
410
78
        break;
411
412
16.3k
      case LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER:
413
16.3k
        if( libfwevt_xml_document_read_fragment(
414
16.3k
             internal_xml_document,
415
16.3k
             xml_token,
416
16.3k
             binary_data,
417
16.3k
             binary_data_size,
418
16.3k
             binary_data_offset,
419
16.3k
             ascii_codepage,
420
16.3k
             flags,
421
16.3k
             template_values_array,
422
16.3k
             internal_xml_document->root_xml_tag,
423
16.3k
             0,
424
16.3k
             0,
425
16.3k
             error ) != 1 )
426
4.79k
        {
427
4.79k
          libcerror_error_set(
428
4.79k
           error,
429
4.79k
           LIBCERROR_ERROR_DOMAIN_IO,
430
4.79k
           LIBCERROR_IO_ERROR_READ_FAILED,
431
4.79k
           "%s: unable to read fragment header.",
432
4.79k
           function );
433
434
4.79k
          goto on_error;
435
4.79k
        }
436
11.5k
        break;
437
438
11.5k
      default:
439
50
        libcerror_error_set(
440
50
         error,
441
50
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
442
50
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
443
50
         "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
444
50
         function,
445
50
         xml_token->type );
446
447
50
        goto on_error;
448
16.5k
    }
449
11.6k
    internal_xml_document->size += xml_token->size;
450
11.6k
    binary_data_offset          += xml_token->size;
451
452
11.6k
    if( xml_token->type == LIBFWEVT_XML_TOKEN_END_OF_FILE )
453
78
    {
454
78
      break;
455
78
    }
456
11.6k
  }
457
80
  if( libfwevt_xml_token_free(
458
80
       &xml_token,
459
80
       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
80
  return( 1 );
471
472
4.87k
on_error:
473
4.87k
  if( xml_token != NULL )
474
4.87k
  {
475
4.87k
    libfwevt_xml_token_free(
476
4.87k
     &xml_token,
477
4.87k
     NULL );
478
4.87k
  }
479
4.87k
  return( -1 );
480
80
}
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
792k
{
499
792k
  libfwevt_xml_tag_t *attribute_xml_tag    = NULL;
500
792k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
501
792k
  const uint8_t *xml_document_data         = NULL;
502
792k
  static char *function                    = "libfwevt_xml_document_read_attribute";
503
792k
  size_t additional_value_size             = 0;
504
792k
  size_t template_value_offset             = 0;
505
792k
  size_t trailing_data_size                = 0;
506
792k
  size_t xml_document_data_offset          = 0;
507
792k
  size_t xml_document_data_size            = 0;
508
792k
  uint32_t attribute_name_offset           = 0;
509
792k
  uint32_t attribute_name_size             = 0;
510
792k
  int result                               = 0;
511
792k
  int template_value_array_recursion_depth = 0;
512
513
792k
  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
792k
  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
792k
  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
792k
  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
792k
  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
792k
  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
792k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
581
792k
  {
582
792k
    additional_value_size = 4;
583
584
792k
    if( ( binary_data_size < 4 )
585
792k
     || ( binary_data_offset > ( binary_data_size - 4 ) ) )
586
8
    {
587
8
      libcerror_error_set(
588
8
       error,
589
8
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
590
8
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
591
8
       "%s: invalid binary data offset value out of bounds.",
592
8
       function );
593
594
8
      return( -1 );
595
8
    }
596
792k
  }
597
792k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
598
792k
  xml_document_data_size = binary_data_size - binary_data_offset;
599
600
792k
  if( libfwevt_xml_token_initialize(
601
792k
       &xml_sub_token,
602
792k
       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
792k
  do
614
794k
  {
615
794k
    if( ( template_value_array_recursion_depth < 0 )
616
794k
     || ( template_value_array_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_VALUE_ARRAY_RECURSION_DEPTH ) )
617
2
    {
618
2
      libcerror_error_set(
619
2
       error,
620
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
621
2
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
622
2
       "%s: invalid template value array recursion depth value out of bounds.",
623
2
       function );
624
625
2
      goto on_error;
626
2
    }
627
794k
    if( ( xml_document_data_size < ( additional_value_size + 1 ) )
628
794k
     || ( xml_document_data_offset > ( xml_document_data_size - ( additional_value_size + 1 ) ) ) )
629
22
    {
630
22
      libcerror_error_set(
631
22
       error,
632
22
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
633
22
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
634
22
       "%s: invalid binary XML document data size value too small.",
635
22
       function );
636
637
22
      goto on_error;
638
22
    }
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
794k
    xml_document_data_offset += 1;
666
667
794k
    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
794k
    else
672
794k
    {
673
794k
      if( ( xml_document_data_size < 4 )
674
794k
       || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
675
4
      {
676
4
        libcerror_error_set(
677
4
         error,
678
4
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
679
4
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
680
4
         "%s: invalid binary XML document data size value too small.",
681
4
         function );
682
683
4
        goto on_error;
684
4
      }
685
794k
      byte_stream_copy_to_uint32_little_endian(
686
794k
       &( xml_document_data[ xml_document_data_offset ] ),
687
794k
       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
794k
      xml_document_data_offset += 4;
699
794k
    }
700
#if defined( HAVE_DEBUG_OUTPUT )
701
    if( libcnotify_verbose != 0 )
702
    {
703
      libcnotify_printf(
704
       "\n" );
705
    }
706
#endif
707
794k
    if( attribute_name_offset > ( binary_data_offset + xml_document_data_offset ) )
708
148
    {
709
148
      libcerror_error_set(
710
148
       error,
711
148
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
712
148
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
713
148
       "%s: invalid attribute data offset value out of bounds.",
714
148
       function );
715
716
148
      goto on_error;
717
148
    }
718
794k
    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
794k
    if( libfwevt_xml_tag_initialize(
742
794k
         &attribute_xml_tag,
743
794k
         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
794k
    if( libfwevt_xml_document_read_name(
755
794k
         internal_xml_document,
756
794k
         binary_data,
757
794k
         binary_data_size,
758
794k
         attribute_name_offset,
759
794k
         flags,
760
794k
         &attribute_name_size,
761
794k
         attribute_xml_tag,
762
794k
         error ) != 1 )
763
13
    {
764
13
      libcerror_error_set(
765
13
       error,
766
13
       LIBCERROR_ERROR_DOMAIN_IO,
767
13
       LIBCERROR_IO_ERROR_READ_FAILED,
768
13
       "%s: unable to read attribute name.",
769
13
       function );
770
771
13
      goto on_error;
772
13
    }
773
794k
    if( ( binary_data_offset + xml_document_data_offset ) == attribute_name_offset )
774
75.4k
    {
775
75.4k
      xml_document_data_offset += attribute_name_size;
776
75.4k
    }
777
794k
    if( libfwevt_xml_token_read_data(
778
794k
         xml_sub_token,
779
794k
         binary_data,
780
794k
         binary_data_size,
781
794k
         binary_data_offset + xml_document_data_offset,
782
794k
         error ) != 1 )
783
23
    {
784
23
      libcerror_error_set(
785
23
       error,
786
23
       LIBCERROR_ERROR_DOMAIN_IO,
787
23
       LIBCERROR_IO_ERROR_READ_FAILED,
788
23
       "%s: unable to read binary XML sub token.",
789
23
       function );
790
791
23
      goto on_error;
792
23
    }
793
794k
    result = 1;
794
795
794k
    switch( xml_sub_token->type & 0xbf )
796
794k
    {
797
284k
      case LIBFWEVT_XML_TOKEN_VALUE:
798
284k
        if( template_value_offset != 0 )
799
16
        {
800
16
          libcerror_error_set(
801
16
           error,
802
16
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
803
16
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
804
16
           "%s: invalid template value offset value out of bounds.",
805
16
           function );
806
807
16
          goto on_error;
808
16
        }
809
284k
        if( libfwevt_xml_document_read_value(
810
284k
             internal_xml_document,
811
284k
             xml_sub_token,
812
284k
             binary_data,
813
284k
             binary_data_size,
814
284k
             binary_data_offset + xml_document_data_offset,
815
284k
             attribute_xml_tag,
816
284k
             error ) != 1 )
817
47
        {
818
47
          libcerror_error_set(
819
47
           error,
820
47
           LIBCERROR_ERROR_DOMAIN_IO,
821
47
           LIBCERROR_IO_ERROR_READ_FAILED,
822
47
           "%s: unable to read value.",
823
47
           function );
824
825
47
          goto on_error;
826
47
        }
827
284k
        break;
828
829
284k
      case LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION:
830
71.6k
        result = libfwevt_xml_document_read_normal_substitution(
831
71.6k
                  internal_xml_document,
832
71.6k
                  xml_sub_token,
833
71.6k
                  binary_data,
834
71.6k
                  binary_data_size,
835
71.6k
                  binary_data_offset + xml_document_data_offset,
836
71.6k
                  ascii_codepage,
837
71.6k
                  flags,
838
71.6k
                  template_values_array,
839
71.6k
                  &template_value_offset,
840
71.6k
                  attribute_xml_tag,
841
71.6k
                  element_recursion_depth,
842
71.6k
                  template_instance_recursion_depth,
843
71.6k
                  error );
844
845
71.6k
        if( result == -1 )
846
1.65k
        {
847
1.65k
          libcerror_error_set(
848
1.65k
           error,
849
1.65k
           LIBCERROR_ERROR_DOMAIN_IO,
850
1.65k
           LIBCERROR_IO_ERROR_READ_FAILED,
851
1.65k
           "%s: unable to read normal substitution.",
852
1.65k
           function );
853
854
1.65k
          goto on_error;
855
1.65k
        }
856
69.9k
        break;
857
858
438k
      case LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION:
859
438k
        result = libfwevt_xml_document_read_optional_substitution(
860
438k
            internal_xml_document,
861
438k
            xml_sub_token,
862
438k
            binary_data,
863
438k
            binary_data_size,
864
438k
            binary_data_offset + xml_document_data_offset,
865
438k
            ascii_codepage,
866
438k
            flags,
867
438k
            template_values_array,
868
438k
            &template_value_offset,
869
438k
            attribute_xml_tag,
870
438k
                  element_recursion_depth,
871
438k
                  template_instance_recursion_depth,
872
438k
            error );
873
874
438k
        if( result == -1 )
875
1.46k
        {
876
1.46k
          libcerror_error_set(
877
1.46k
           error,
878
1.46k
           LIBCERROR_ERROR_DOMAIN_IO,
879
1.46k
           LIBCERROR_IO_ERROR_READ_FAILED,
880
1.46k
           "%s: unable to read optional substitution.",
881
1.46k
           function );
882
883
1.46k
          goto on_error;
884
1.46k
        }
885
436k
        break;
886
887
436k
      default:
888
27
        libcerror_error_set(
889
27
         error,
890
27
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
891
27
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
892
27
         "%s: invalid binary XML sub token - unsupported type: 0x%02" PRIx8 ".",
893
27
         function,
894
27
         xml_sub_token->type );
895
896
27
        goto on_error;
897
794k
    }
898
791k
    if( result != 0 )
899
685k
    {
900
685k
      if( libfwevt_xml_tag_append_attribute(
901
685k
           xml_tag,
902
685k
           attribute_xml_tag,
903
685k
           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
685k
      attribute_xml_tag = NULL;
915
685k
    }
916
791k
    xml_document_data_offset += xml_sub_token->size;
917
918
791k
    template_value_array_recursion_depth++;
919
791k
  }
920
792k
  while( template_value_offset > 0 );
921
922
789k
  xml_token->size = xml_document_data_offset;
923
924
789k
  if( attribute_xml_tag != NULL )
925
105k
  {
926
105k
    if( libfwevt_internal_xml_tag_free(
927
105k
         (libfwevt_internal_xml_tag_t **) &attribute_xml_tag,
928
105k
         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
105k
  }
940
789k
  if( libfwevt_xml_token_free(
941
789k
       &xml_sub_token,
942
789k
       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
789k
  return( 1 );
954
955
3.41k
on_error:
956
3.41k
  if( attribute_xml_tag != NULL )
957
3.23k
  {
958
3.23k
    libfwevt_internal_xml_tag_free(
959
3.23k
     (libfwevt_internal_xml_tag_t **) &attribute_xml_tag,
960
3.23k
     NULL );
961
3.23k
  }
962
3.41k
  if( xml_sub_token != NULL )
963
3.41k
  {
964
3.41k
    libfwevt_xml_token_free(
965
3.41k
     &xml_sub_token,
966
3.41k
     NULL );
967
3.41k
  }
968
3.41k
  return( -1 );
969
789k
}
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
25.2k
{
983
25.2k
  const uint8_t *xml_document_data = NULL;
984
25.2k
  static char *function            = "libfwevt_xml_document_read_cdata_section";
985
25.2k
  size_t value_data_size           = 0;
986
25.2k
  size_t xml_document_data_size    = 0;
987
988
25.2k
  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
25.2k
  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
25.2k
  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
25.2k
  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
25.2k
  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
25.2k
  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
25.2k
  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
25.2k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1067
25.2k
  xml_document_data_size = binary_data_size - binary_data_offset;
1068
1069
25.2k
  if( xml_document_data_size < 3 )
1070
19
  {
1071
19
    libcerror_error_set(
1072
19
     error,
1073
19
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1074
19
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1075
19
     "%s: invalid binary XML document data size value too small.",
1076
19
     function );
1077
1078
19
    return( -1 );
1079
19
  }
1080
25.2k
  if( libfwevt_xml_tag_set_type(
1081
25.2k
       xml_tag,
1082
25.2k
       LIBFWEVT_XML_TAG_TYPE_CDATA,
1083
25.2k
       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
25.2k
  byte_stream_copy_to_uint16_little_endian(
1112
25.2k
   &( xml_document_data[ 1 ] ),
1113
25.2k
   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
25.2k
  xml_token->size     = 3;
1130
25.2k
  binary_data_offset += 3;
1131
1132
25.2k
  value_data_size *= 2;
1133
1134
25.2k
  if( ( value_data_size > binary_data_size )
1135
25.2k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
1136
101
  {
1137
101
    libcerror_error_set(
1138
101
     error,
1139
101
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1140
101
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1141
101
     "%s: invalid value data size value out of bounds.",
1142
101
     function );
1143
1144
101
    return( -1 );
1145
101
  }
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
25.1k
  if( libfwevt_xml_tag_set_value_type(
1164
25.1k
       xml_tag,
1165
25.1k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
1166
25.1k
       error ) != 1 )
1167
5
  {
1168
5
    libcerror_error_set(
1169
5
     error,
1170
5
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1171
5
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1172
5
     "%s: unable to set value type.",
1173
5
     function );
1174
1175
5
    return( -1 );
1176
5
  }
1177
25.1k
  if( libfwevt_xml_tag_set_value_data(
1178
25.1k
       xml_tag,
1179
25.1k
       &( binary_data[ binary_data_offset ] ),
1180
25.1k
       value_data_size,
1181
25.1k
       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
25.1k
  xml_token->size += value_data_size;
1213
1214
25.1k
  return( 1 );
1215
25.1k
}
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
3
{
1229
3
  libfwevt_xml_tag_t *character_xml_tag     = NULL;
1230
3
  uint16_t *character_value_string          = NULL;
1231
3
  uint8_t *character_value_utf16_stream     = NULL;
1232
3
  const uint8_t *xml_document_data          = NULL;
1233
3
  static char *function                     = "libfwevt_xml_document_read_character_reference";
1234
3
  size_t character_value_string_index       = 0;
1235
3
  size_t character_value_string_size        = 0;
1236
3
  size_t character_value_utf16_stream_index = 0;
1237
3
  size_t character_value_utf16_stream_size  = 0;
1238
3
  size_t xml_document_data_size             = 0;
1239
3
  uint16_t character_value                  = 0;
1240
3
  int data_segment_index                    = 0;
1241
1242
3
  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
3
  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
3
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_ENTITY_REFERENCE )
1265
3
  {
1266
3
    libcerror_error_set(
1267
3
     error,
1268
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1269
3
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1270
3
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1271
3
     function,
1272
3
     xml_token->type );
1273
1274
3
    return( -1 );
1275
3
  }
1276
0
  if( binary_data == NULL )
1277
0
  {
1278
0
    libcerror_error_set(
1279
0
     error,
1280
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1281
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1282
0
     "%s: invalid binary data.",
1283
0
     function );
1284
1285
0
    return( -1 );
1286
0
  }
1287
0
  if( binary_data_size > (size_t) SSIZE_MAX )
1288
0
  {
1289
0
    libcerror_error_set(
1290
0
     error,
1291
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1292
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1293
0
     "%s: invalid binary XML document data size value exceeds maximum.",
1294
0
     function );
1295
1296
0
    return( -1 );
1297
0
  }
1298
0
  if( binary_data_offset >= binary_data_size )
1299
0
  {
1300
0
    libcerror_error_set(
1301
0
     error,
1302
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1303
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1304
0
     "%s: invalid binary data offset value out of bounds.",
1305
0
     function );
1306
1307
0
    return( -1 );
1308
0
  }
1309
0
  if( xml_tag == NULL )
1310
0
  {
1311
0
    libcerror_error_set(
1312
0
     error,
1313
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1314
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1315
0
     "%s: invalid XML tag.",
1316
0
     function );
1317
1318
0
    return( -1 );
1319
0
  }
1320
0
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1321
0
  xml_document_data_size = binary_data_size - binary_data_offset;
1322
1323
0
  if( xml_document_data_size < 3 )
1324
0
  {
1325
0
    libcerror_error_set(
1326
0
     error,
1327
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1328
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1329
0
     "%s: invalid binary XML document data size value too small.",
1330
0
     function );
1331
1332
0
    return( -1 );
1333
0
  }
1334
#if defined( HAVE_DEBUG_OUTPUT )
1335
  if( libcnotify_verbose != 0 )
1336
  {
1337
    libcnotify_printf(
1338
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
1339
     function,
1340
     binary_data_offset );
1341
1342
    libcnotify_printf(
1343
     "%s: character reference data:\n",
1344
     function );
1345
    libcnotify_print_data(
1346
     xml_document_data,
1347
     3,
1348
     0 );
1349
  }
1350
#endif
1351
0
  byte_stream_copy_to_uint16_little_endian(
1352
0
   &( xml_document_data[ 1 ] ),
1353
0
   character_value );
1354
1355
#if defined( HAVE_DEBUG_OUTPUT )
1356
  if( libcnotify_verbose != 0 )
1357
  {
1358
    libcnotify_printf(
1359
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
1360
     function,
1361
     xml_document_data[ 0 ] );
1362
1363
    libcnotify_printf(
1364
     "%s: character value\t\t: 0x%04" PRIx16 "\n",
1365
     function,
1366
     character_value );
1367
1368
    libcnotify_printf(
1369
     "\n" );
1370
  }
1371
#endif
1372
0
  xml_token->size = 3;
1373
1374
0
  if( libfwevt_integer_as_unsigned_decimal_get_string_size(
1375
0
       (uint64_t) character_value,
1376
0
       &character_value_string_size,
1377
0
       error ) != 1 )
1378
0
  {
1379
0
    libcerror_error_set(
1380
0
     error,
1381
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1382
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1383
0
     "%s: unable to determine size of character value string.",
1384
0
     function );
1385
1386
0
    goto on_error;
1387
0
  }
1388
0
  character_value_string_size += 3;
1389
1390
0
  if( character_value_string_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( uint16_t ) ) )
1391
0
  {
1392
0
    libcerror_error_set(
1393
0
     error,
1394
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1395
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1396
0
     "%s: invalid character value string size value out of bounds.",
1397
0
     function );
1398
1399
0
    goto on_error;
1400
0
  }
1401
0
  character_value_string = (uint16_t *) memory_allocate(
1402
0
                                         sizeof( uint16_t ) * character_value_string_size );
1403
1404
0
  if( character_value_string == NULL )
1405
0
  {
1406
0
    libcerror_error_set(
1407
0
     error,
1408
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1409
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1410
0
     "%s: unable to create character value string.",
1411
0
     function );
1412
1413
0
    goto on_error;
1414
0
  }
1415
0
  character_value_string[ character_value_string_index++ ] = (uint16_t) '&';
1416
0
  character_value_string[ character_value_string_index++ ] = (uint16_t) '#';
1417
1418
0
  if( libfwevt_integer_as_unsigned_decimal_copy_to_utf16_string_with_index(
1419
0
       (uint64_t) character_value,
1420
0
       character_value_string,
1421
0
       character_value_string_size,
1422
0
       &character_value_string_index,
1423
0
       error ) != 1 )
1424
0
  {
1425
0
    libcerror_error_set(
1426
0
     error,
1427
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1428
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1429
0
     "%s: unable to copy character value to UTF-16 string.",
1430
0
     function );
1431
1432
0
    goto on_error;
1433
0
  }
1434
0
  character_value_string[ character_value_string_size - 2 ] = (uint16_t) ';';
1435
0
  character_value_string[ character_value_string_size - 1 ] = 0;
1436
1437
0
  if( libfwevt_xml_tag_set_value_type(
1438
0
       xml_tag,
1439
0
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
1440
0
       error ) != 1 )
1441
0
  {
1442
0
    libcerror_error_set(
1443
0
     error,
1444
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1445
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1446
0
     "%s: unable to set value type.",
1447
0
     function );
1448
1449
0
    goto on_error;
1450
0
  }
1451
  /* Make sure the character value data is in UTF-16 litte-endian
1452
   */
1453
0
  if( ( character_value_utf16_stream_size == 0 )
1454
0
   || ( character_value_utf16_stream_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / 2 ) ) )
1455
0
  {
1456
0
    libcerror_error_set(
1457
0
     error,
1458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1459
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1460
0
     "%s: invalid character value UTF-16 stream size value out of bounds.",
1461
0
     function );
1462
1463
0
    goto on_error;
1464
0
  }
1465
0
  character_value_utf16_stream_size = character_value_string_size * 2;
1466
1467
0
  character_value_utf16_stream = (uint8_t *) memory_allocate(
1468
0
                                              sizeof( uint8_t ) * character_value_utf16_stream_size );
1469
1470
0
  if( character_value_utf16_stream == NULL )
1471
0
  {
1472
0
    libcerror_error_set(
1473
0
     error,
1474
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1475
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1476
0
     "%s: unable to create character value UTF-16 stream.",
1477
0
     function );
1478
1479
0
    goto on_error;
1480
0
  }
1481
0
  for( character_value_string_index = 0;
1482
0
       character_value_string_index < character_value_string_size;
1483
0
       character_value_string_index++ )
1484
0
  {
1485
0
    byte_stream_copy_from_uint16_little_endian(
1486
0
     &( character_value_utf16_stream[ character_value_utf16_stream_index ] ),
1487
0
     character_value_string[ character_value_string_index ] );
1488
1489
0
    character_value_utf16_stream_index += 2;
1490
0
  }
1491
0
  memory_free(
1492
0
   character_value_string );
1493
1494
0
  character_value_string = NULL;
1495
1496
0
  if( libfwevt_xml_tag_append_value_data(
1497
0
       xml_tag,
1498
0
       character_value_utf16_stream,
1499
0
       character_value_utf16_stream_size,
1500
0
       &data_segment_index,
1501
0
       error ) != 1 )
1502
0
  {
1503
0
    libcerror_error_set(
1504
0
     error,
1505
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1506
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1507
0
     "%s: unable to append value data.",
1508
0
     function );
1509
1510
0
    goto on_error;
1511
0
  }
1512
0
  memory_free(
1513
0
   character_value_utf16_stream );
1514
1515
0
  character_value_utf16_stream = NULL;
1516
1517
#if defined( HAVE_DEBUG_OUTPUT )
1518
  if( libcnotify_verbose != 0 )
1519
  {
1520
    if( libfwevt_xml_tag_debug_print_value_data_segment(
1521
         xml_tag,
1522
         data_segment_index,
1523
         0,
1524
         error ) != 1 )
1525
    {
1526
      libcerror_error_set(
1527
       error,
1528
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1529
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1530
       "%s: unable to print value data segment: %d.",
1531
       function,
1532
       data_segment_index );
1533
1534
      goto on_error;
1535
    }
1536
  }
1537
#endif
1538
0
  if( libfwevt_internal_xml_tag_free(
1539
0
       (libfwevt_internal_xml_tag_t **) &character_xml_tag,
1540
0
       error ) != 1 )
1541
0
  {
1542
0
    libcerror_error_set(
1543
0
     error,
1544
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1545
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1546
0
     "%s: unable to free character XML tag.",
1547
0
     function );
1548
1549
0
    goto on_error;
1550
0
  }
1551
0
  return( 1 );
1552
1553
0
on_error:
1554
0
  if( character_value_utf16_stream != NULL )
1555
0
  {
1556
0
    memory_free(
1557
0
     character_value_utf16_stream );
1558
0
  }
1559
0
  if( character_value_string != NULL )
1560
0
  {
1561
0
    memory_free(
1562
0
     character_value_string );
1563
0
  }
1564
0
  if( character_xml_tag != NULL )
1565
0
  {
1566
0
    libfwevt_internal_xml_tag_free(
1567
0
     (libfwevt_internal_xml_tag_t **) &character_xml_tag,
1568
0
     NULL );
1569
0
  }
1570
0
  return( -1 );
1571
0
}
1572
1573
/* Reads an element from a binary XML document
1574
 * Returns 1 if successful or -1 on error
1575
 */
1576
int libfwevt_xml_document_read_element(
1577
     libfwevt_internal_xml_document_t *internal_xml_document,
1578
     libfwevt_xml_token_t *xml_token,
1579
     const uint8_t *binary_data,
1580
     size_t binary_data_size,
1581
     size_t binary_data_offset,
1582
     int ascii_codepage,
1583
     uint8_t flags,
1584
     libcdata_array_t *template_values_array,
1585
     libfwevt_xml_tag_t *xml_tag,
1586
     int element_recursion_depth,
1587
     int template_instance_recursion_depth,
1588
     libcerror_error_t **error )
1589
1.16M
{
1590
1.16M
  libfwevt_xml_tag_t *element_xml_tag      = NULL;
1591
1.16M
  libfwevt_xml_token_t *xml_sub_token      = NULL;
1592
1.16M
  const uint8_t *xml_document_data         = NULL;
1593
1.16M
  static char *function                    = "libfwevt_xml_document_read_element";
1594
1.16M
  size_t additional_value_size             = 0;
1595
1.16M
  size_t element_size_offset               = 0;
1596
1.16M
  size_t template_value_offset             = 0;
1597
1.16M
  size_t trailing_data_size                = 0;
1598
1.16M
  size_t xml_document_data_offset          = 0;
1599
1.16M
  size_t xml_document_data_size            = 0;
1600
1.16M
  uint32_t attribute_list_size             = 0;
1601
1.16M
  uint32_t element_name_offset             = 0;
1602
1.16M
  uint32_t element_name_size               = 0;
1603
1.16M
  uint32_t element_size                    = 0;
1604
1.16M
  int result                               = 0;
1605
1.16M
  int template_value_array_recursion_depth = 0;
1606
1607
#if defined( HAVE_DEBUG_OUTPUT )
1608
  uint16_t value_16bit                     = 0;
1609
#endif
1610
1611
1.16M
  if( internal_xml_document == NULL )
1612
0
  {
1613
0
    libcerror_error_set(
1614
0
     error,
1615
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1616
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1617
0
     "%s: invalid binary XML document.",
1618
0
     function );
1619
1620
0
    return( -1 );
1621
0
  }
1622
1.16M
  if( xml_token == NULL )
1623
0
  {
1624
0
    libcerror_error_set(
1625
0
     error,
1626
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1627
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1628
0
     "%s: invalid binary XML token.",
1629
0
     function );
1630
1631
0
    return( -1 );
1632
0
  }
1633
1.16M
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG )
1634
11
  {
1635
11
    libcerror_error_set(
1636
11
     error,
1637
11
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1638
11
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1639
11
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1640
11
     function,
1641
11
     xml_token->type );
1642
1643
11
    return( -1 );
1644
11
  }
1645
1.16M
  if( binary_data == NULL )
1646
0
  {
1647
0
    libcerror_error_set(
1648
0
     error,
1649
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1650
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1651
0
     "%s: invalid binary data.",
1652
0
     function );
1653
1654
0
    return( -1 );
1655
0
  }
1656
1.16M
  if( binary_data_size > (size_t) SSIZE_MAX )
1657
0
  {
1658
0
    libcerror_error_set(
1659
0
     error,
1660
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1661
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1662
0
     "%s: invalid binary XML document data size value exceeds maximum.",
1663
0
     function );
1664
1665
0
    return( -1 );
1666
0
  }
1667
1.16M
  if( binary_data_offset >= binary_data_size )
1668
0
  {
1669
0
    libcerror_error_set(
1670
0
     error,
1671
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1672
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1673
0
     "%s: invalid binary data offset value out of bounds.",
1674
0
     function );
1675
1676
0
    return( -1 );
1677
0
  }
1678
1.16M
  if( ( element_recursion_depth < 0 )
1679
1.16M
   || ( element_recursion_depth > LIBFWEVT_XML_DOCUMENT_ELEMENT_RECURSION_DEPTH ) )
1680
49
  {
1681
49
    libcerror_error_set(
1682
49
     error,
1683
49
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1684
49
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1685
49
     "%s: invalid element recursion depth value out of bounds.",
1686
49
     function );
1687
1688
49
    return( -1 );
1689
49
  }
1690
1.16M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
1691
1.16M
  {
1692
1.16M
    additional_value_size = 4;
1693
1.16M
  }
1694
1.16M
  if( ( binary_data_size < ( 5 + additional_value_size ) )
1695
1.16M
   || ( binary_data_offset > ( binary_data_size - 5 - additional_value_size ) ) )
1696
36
  {
1697
36
    libcerror_error_set(
1698
36
     error,
1699
36
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1700
36
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1701
36
     "%s: invalid binary XML document data size value too small.",
1702
36
     function );
1703
1704
36
    goto on_error;
1705
36
  }
1706
1.16M
  if( libfwevt_xml_token_initialize(
1707
1.16M
       &xml_sub_token,
1708
1.16M
       error ) != 1 )
1709
0
  {
1710
0
    libcerror_error_set(
1711
0
     error,
1712
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1713
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1714
0
     "%s: unable to create binary XML sub token.",
1715
0
     function );
1716
1717
0
    goto on_error;
1718
0
  }
1719
1.16M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1720
1.16M
  xml_document_data_size = binary_data_size - binary_data_offset;
1721
1722
1.16M
  do
1723
1.22M
  {
1724
1.22M
    if( ( template_value_array_recursion_depth < 0 )
1725
1.22M
     || ( template_value_array_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_VALUE_ARRAY_RECURSION_DEPTH ) )
1726
74
    {
1727
74
      libcerror_error_set(
1728
74
       error,
1729
74
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1730
74
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1731
74
       "%s: invalid template value array recursion depth value out of bounds.",
1732
74
       function );
1733
1734
74
      goto on_error;
1735
74
    }
1736
1.22M
    if( libfwevt_xml_tag_initialize(
1737
1.22M
         &element_xml_tag,
1738
1.22M
         error ) != 1 )
1739
31
    {
1740
31
      libcerror_error_set(
1741
31
       error,
1742
31
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1743
31
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1744
31
       "%s: unable to create element XML tag.",
1745
31
       function );
1746
1747
31
      goto on_error;
1748
31
    }
1749
    /* Note that the dependency identifier is an optional value.
1750
     */
1751
1.22M
    element_size_offset = 1;
1752
1753
1.22M
    byte_stream_copy_to_uint32_little_endian(
1754
1.22M
     &( xml_document_data[ element_size_offset ] ),
1755
1.22M
     element_size );
1756
1757
1.22M
    if( ( xml_document_data_size > 7 )
1758
1.22M
     && ( element_size > ( xml_document_data_size - 7 ) ) )
1759
1.16M
    {
1760
1.16M
      element_size_offset = 3;
1761
1.16M
    }
1762
#if defined( HAVE_DEBUG_OUTPUT )
1763
    if( libcnotify_verbose != 0 )
1764
    {
1765
      libcnotify_printf(
1766
       "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
1767
       function,
1768
       binary_data_offset );
1769
1770
      libcnotify_printf(
1771
       "%s: element data:\n",
1772
       function );
1773
      libcnotify_print_data(
1774
       xml_document_data,
1775
       element_size_offset + 4 + additional_value_size,
1776
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1777
    }
1778
#endif
1779
1.22M
    byte_stream_copy_to_uint32_little_endian(
1780
1.22M
     &( xml_document_data[ element_size_offset ] ),
1781
1.22M
     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.22M
    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.22M
    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.22M
    else
1818
1.22M
    {
1819
1.22M
      if( xml_document_data_offset >= ( xml_document_data_size - 4 ) )
1820
56
      {
1821
56
        libcerror_error_set(
1822
56
         error,
1823
56
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1824
56
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1825
56
         "%s: invalid binary XML document data size value too small.",
1826
56
         function );
1827
1828
56
        goto on_error;
1829
56
      }
1830
1.22M
      byte_stream_copy_to_uint32_little_endian(
1831
1.22M
       &( xml_document_data[ xml_document_data_offset ] ),
1832
1.22M
       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.22M
      xml_document_data_offset += 4;
1844
1.22M
      element_size             -= 4;
1845
1.22M
    }
1846
#if defined( HAVE_DEBUG_OUTPUT )
1847
    if( libcnotify_verbose != 0 )
1848
    {
1849
      libcnotify_printf(
1850
       "\n" );
1851
    }
1852
#endif
1853
1.22M
    if( element_name_offset > ( binary_data_offset + xml_document_data_offset ) )
1854
141
    {
1855
141
      libcerror_error_set(
1856
141
       error,
1857
141
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1858
141
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1859
141
       "%s: invalid element data offset value out of bounds.",
1860
141
       function );
1861
1862
141
      goto on_error;
1863
141
    }
1864
1.22M
    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.22M
    if( libfwevt_xml_document_read_name(
1889
1.22M
         internal_xml_document,
1890
1.22M
         binary_data,
1891
1.22M
         binary_data_size,
1892
1.22M
         element_name_offset,
1893
1.22M
         flags,
1894
1.22M
         &element_name_size,
1895
1.22M
         element_xml_tag,
1896
1.22M
         error ) != 1 )
1897
46
    {
1898
46
      libcerror_error_set(
1899
46
       error,
1900
46
       LIBCERROR_ERROR_DOMAIN_IO,
1901
46
       LIBCERROR_IO_ERROR_READ_FAILED,
1902
46
       "%s: unable to read element name.",
1903
46
       function );
1904
1905
46
      goto on_error;
1906
46
    }
1907
1.22M
    if( ( binary_data_offset + xml_document_data_offset ) == element_name_offset )
1908
10.6k
    {
1909
10.6k
      xml_document_data_offset += element_name_size;
1910
10.6k
      element_size             -= element_name_size;
1911
10.6k
    }
1912
1.22M
    if( ( xml_token->type & LIBFWEVT_XML_TOKEN_FLAG_HAS_MORE_DATA ) != 0 )
1913
512k
    {
1914
512k
      if( xml_document_data_offset >= ( xml_document_data_size - 4 ) )
1915
10
      {
1916
10
        libcerror_error_set(
1917
10
         error,
1918
10
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1919
10
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1920
10
         "%s: invalid binary XML document data size value too small.",
1921
10
         function );
1922
1923
10
        goto on_error;
1924
10
      }
1925
#if defined( HAVE_DEBUG_OUTPUT )
1926
      if( libcnotify_verbose != 0 )
1927
      {
1928
        libcnotify_printf(
1929
         "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
1930
         function,
1931
         binary_data_offset + xml_document_data_offset );
1932
1933
        libcnotify_printf(
1934
         "%s: attribute list data:\n",
1935
         function );
1936
        libcnotify_print_data(
1937
         &( xml_document_data[ xml_document_data_offset ] ),
1938
         4,
1939
         0 );
1940
      }
1941
#endif
1942
512k
      byte_stream_copy_to_uint32_little_endian(
1943
512k
       &( xml_document_data[ xml_document_data_offset ] ),
1944
512k
       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
512k
      xml_document_data_offset += 4;
1960
512k
      element_size             -= 4;
1961
1962
512k
      if( attribute_list_size > ( binary_data_size - ( binary_data_offset + xml_document_data_offset ) ) )
1963
74
      {
1964
74
        libcerror_error_set(
1965
74
         error,
1966
74
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1967
74
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1968
74
         "%s: invalid attribute list size value out of bounds.",
1969
74
         function );
1970
1971
74
        goto on_error;
1972
74
      }
1973
1.30M
      while( attribute_list_size > 0 )
1974
792k
      {
1975
792k
        if( libfwevt_xml_token_read_data(
1976
792k
             xml_sub_token,
1977
792k
             binary_data,
1978
792k
             binary_data_size,
1979
792k
             binary_data_offset + xml_document_data_offset,
1980
792k
             error ) != 1 )
1981
21
        {
1982
21
          libcerror_error_set(
1983
21
           error,
1984
21
           LIBCERROR_ERROR_DOMAIN_IO,
1985
21
           LIBCERROR_IO_ERROR_READ_FAILED,
1986
21
           "%s: unable to read binary XML sub token.",
1987
21
           function );
1988
1989
21
          goto on_error;
1990
21
        }
1991
792k
        if( libfwevt_xml_document_read_attribute(
1992
792k
             internal_xml_document,
1993
792k
             xml_sub_token,
1994
792k
             binary_data,
1995
792k
             binary_data_size,
1996
792k
             binary_data_offset + xml_document_data_offset,
1997
792k
             ascii_codepage,
1998
792k
             flags,
1999
792k
             template_values_array,
2000
792k
             element_xml_tag,
2001
792k
             element_recursion_depth,
2002
792k
             template_instance_recursion_depth,
2003
792k
             error ) != 1 )
2004
3.46k
        {
2005
3.46k
          libcerror_error_set(
2006
3.46k
           error,
2007
3.46k
           LIBCERROR_ERROR_DOMAIN_IO,
2008
3.46k
           LIBCERROR_IO_ERROR_READ_FAILED,
2009
3.46k
           "%s: unable to read attribute.",
2010
3.46k
           function );
2011
2012
3.46k
          goto on_error;
2013
3.46k
        }
2014
789k
        xml_document_data_offset += xml_sub_token->size;
2015
789k
        element_size             -= (uint32_t) xml_sub_token->size;
2016
2017
789k
        if( attribute_list_size < xml_sub_token->size )
2018
85
        {
2019
85
          libcerror_error_set(
2020
85
           error,
2021
85
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2022
85
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2023
85
           "%s: invalid attribute list size value too small.",
2024
85
           function );
2025
2026
85
          goto on_error;
2027
85
        }
2028
789k
        attribute_list_size -= (uint32_t) xml_sub_token->size;
2029
789k
      }
2030
512k
    }
2031
1.22M
    if( libfwevt_xml_token_read_data(
2032
1.22M
         xml_sub_token,
2033
1.22M
         binary_data,
2034
1.22M
         binary_data_size,
2035
1.22M
         binary_data_offset + xml_document_data_offset,
2036
1.22M
         error ) != 1 )
2037
20
    {
2038
20
      libcerror_error_set(
2039
20
       error,
2040
20
       LIBCERROR_ERROR_DOMAIN_IO,
2041
20
       LIBCERROR_IO_ERROR_READ_FAILED,
2042
20
       "%s: unable to read binary XML sub token.",
2043
20
       function );
2044
2045
20
      goto on_error;
2046
20
    }
2047
1.22M
    if( ( xml_sub_token->type != LIBFWEVT_XML_TOKEN_CLOSE_START_ELEMENT_TAG )
2048
1.22M
     && ( xml_sub_token->type != LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG ) )
2049
57
    {
2050
57
      libcerror_error_set(
2051
57
       error,
2052
57
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2053
57
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2054
57
       "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
2055
57
       function,
2056
57
       xml_token->type );
2057
2058
57
      goto on_error;
2059
57
    }
2060
1.22M
    if( xml_document_data_offset >= xml_document_data_size )
2061
0
    {
2062
0
      libcerror_error_set(
2063
0
       error,
2064
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2065
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2066
0
       "%s: invalid binary XML document data size value too small.",
2067
0
       function );
2068
2069
0
      goto on_error;
2070
0
    }
2071
#if defined( HAVE_DEBUG_OUTPUT )
2072
    if( libcnotify_verbose != 0 )
2073
    {
2074
      libcnotify_printf(
2075
       "%s: data offset\t\t\t\t: 0x%08" PRIzx "\n",
2076
       function,
2077
       binary_data_offset + xml_document_data_offset );
2078
2079
      libcnotify_printf(
2080
       "%s: close element tag data:\n",
2081
       function );
2082
      libcnotify_print_data(
2083
       &( xml_document_data[ xml_document_data_offset ] ),
2084
       1,
2085
       0 );
2086
    }
2087
#endif
2088
#if defined( HAVE_DEBUG_OUTPUT )
2089
    if( libcnotify_verbose != 0 )
2090
    {
2091
      libcnotify_printf(
2092
       "%s: type\t\t\t\t: 0x%02" PRIx8 "\n",
2093
       function,
2094
       xml_document_data[ xml_document_data_offset ] );
2095
2096
      libcnotify_printf(
2097
       "\n" );
2098
    }
2099
#endif
2100
1.22M
    xml_document_data_offset += 1;
2101
1.22M
    element_size             -= 1;
2102
2103
1.22M
    if( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_START_ELEMENT_TAG )
2104
861k
    {
2105
861k
      result = 1;
2106
2107
4.13M
      while( element_size > 0 )
2108
4.08M
      {
2109
4.08M
        if( libfwevt_xml_token_read_data(
2110
4.08M
             xml_sub_token,
2111
4.08M
             binary_data,
2112
4.08M
             binary_data_size,
2113
4.08M
             binary_data_offset + xml_document_data_offset,
2114
4.08M
             error ) != 1 )
2115
232
        {
2116
232
          libcerror_error_set(
2117
232
           error,
2118
232
           LIBCERROR_ERROR_DOMAIN_IO,
2119
232
           LIBCERROR_IO_ERROR_READ_FAILED,
2120
232
           "%s: unable to read binary XML sub token.",
2121
232
           function );
2122
2123
232
          goto on_error;
2124
232
        }
2125
4.08M
        switch( xml_sub_token->type & 0xbf )
2126
4.08M
        {
2127
1.06M
          case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
2128
1.06M
            if( libfwevt_xml_document_read_element(
2129
1.06M
                 internal_xml_document,
2130
1.06M
                 xml_sub_token,
2131
1.06M
                 binary_data,
2132
1.06M
                 binary_data_size,
2133
1.06M
                 binary_data_offset + xml_document_data_offset,
2134
1.06M
                 ascii_codepage,
2135
1.06M
                 flags,
2136
1.06M
                 template_values_array,
2137
1.06M
                 element_xml_tag,
2138
1.06M
                 element_recursion_depth + 1,
2139
1.06M
                 template_instance_recursion_depth,
2140
1.06M
                 error ) != 1 )
2141
9.79k
            {
2142
9.79k
              libcerror_error_set(
2143
9.79k
               error,
2144
9.79k
               LIBCERROR_ERROR_DOMAIN_IO,
2145
9.79k
               LIBCERROR_IO_ERROR_READ_FAILED,
2146
9.79k
               "%s: unable to read element.",
2147
9.79k
               function );
2148
2149
9.79k
              goto on_error;
2150
9.79k
            }
2151
1.05M
            break;
2152
2153
1.05M
          case LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG:
2154
793k
          case LIBFWEVT_XML_TOKEN_END_ELEMENT_TAG:
2155
793k
            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
793k
            xml_sub_token->size = 1;
2196
2197
793k
            break;
2198
2199
25.2k
          case LIBFWEVT_XML_TOKEN_CDATA_SECTION:
2200
25.2k
            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
25.2k
            if( libfwevt_xml_document_read_cdata_section(
2212
25.2k
                 internal_xml_document,
2213
25.2k
                 xml_sub_token,
2214
25.2k
                 binary_data,
2215
25.2k
                 binary_data_size,
2216
25.2k
                 binary_data_offset + xml_document_data_offset,
2217
25.2k
                 element_xml_tag,
2218
25.2k
                 error ) != 1 )
2219
127
            {
2220
127
              libcerror_error_set(
2221
127
               error,
2222
127
               LIBCERROR_ERROR_DOMAIN_IO,
2223
127
               LIBCERROR_IO_ERROR_READ_FAILED,
2224
127
               "%s: unable to read CDATA section.",
2225
127
               function );
2226
2227
127
              goto on_error;
2228
127
            }
2229
25.1k
            break;
2230
2231
25.1k
          case LIBFWEVT_XML_TOKEN_PI_TARGET:
2232
2.78k
            if( template_value_offset != 0 )
2233
24
            {
2234
24
              libcerror_error_set(
2235
24
               error,
2236
24
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2237
24
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2238
24
               "%s: invalid template value offset value out of bounds.",
2239
24
               function );
2240
2241
24
              goto on_error;
2242
24
            }
2243
2.75k
            if( libfwevt_xml_document_read_pi_target(
2244
2.75k
                 internal_xml_document,
2245
2.75k
                 xml_sub_token,
2246
2.75k
                 binary_data,
2247
2.75k
                 binary_data_size,
2248
2.75k
                 binary_data_offset + xml_document_data_offset,
2249
2.75k
                 flags,
2250
2.75k
                 element_xml_tag,
2251
2.75k
                 error ) != 1 )
2252
331
            {
2253
331
              libcerror_error_set(
2254
331
               error,
2255
331
               LIBCERROR_ERROR_DOMAIN_IO,
2256
331
               LIBCERROR_IO_ERROR_READ_FAILED,
2257
331
               "%s: unable to read PI target.",
2258
331
               function );
2259
2260
331
              goto on_error;
2261
331
            }
2262
2.42k
            break;
2263
2264
2.42k
          case LIBFWEVT_XML_TOKEN_CHARACTER_REFERENCE:
2265
27
            if( template_value_offset != 0 )
2266
24
            {
2267
24
              libcerror_error_set(
2268
24
               error,
2269
24
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2270
24
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2271
24
               "%s: invalid template value offset value out of bounds.",
2272
24
               function );
2273
2274
24
              goto on_error;
2275
24
            }
2276
3
            if( libfwevt_xml_document_read_character_reference(
2277
3
                 internal_xml_document,
2278
3
                 xml_sub_token,
2279
3
                 binary_data,
2280
3
                 binary_data_size,
2281
3
                 binary_data_offset + xml_document_data_offset,
2282
3
                 element_xml_tag,
2283
3
                 error ) != 1 )
2284
3
            {
2285
3
              libcerror_error_set(
2286
3
               error,
2287
3
               LIBCERROR_ERROR_DOMAIN_IO,
2288
3
               LIBCERROR_IO_ERROR_READ_FAILED,
2289
3
               "%s: unable to read character reference.",
2290
3
               function );
2291
2292
3
              goto on_error;
2293
3
            }
2294
0
            break;
2295
2296
31.0k
          case LIBFWEVT_XML_TOKEN_ENTITY_REFERENCE:
2297
31.0k
            if( template_value_offset != 0 )
2298
26
            {
2299
26
              libcerror_error_set(
2300
26
               error,
2301
26
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2302
26
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2303
26
               "%s: invalid template value offset value out of bounds.",
2304
26
               function );
2305
2306
26
              goto on_error;
2307
26
            }
2308
31.0k
            if( libfwevt_xml_document_read_entity_reference(
2309
31.0k
                 internal_xml_document,
2310
31.0k
                 xml_sub_token,
2311
31.0k
                 binary_data,
2312
31.0k
                 binary_data_size,
2313
31.0k
                 binary_data_offset + xml_document_data_offset,
2314
31.0k
                 flags,
2315
31.0k
                 element_xml_tag,
2316
31.0k
                 error ) != 1 )
2317
859
            {
2318
859
              libcerror_error_set(
2319
859
               error,
2320
859
               LIBCERROR_ERROR_DOMAIN_IO,
2321
859
               LIBCERROR_IO_ERROR_READ_FAILED,
2322
859
               "%s: unable to read entity reference.",
2323
859
               function );
2324
2325
859
              goto on_error;
2326
859
            }
2327
30.1k
            break;
2328
2329
1.50M
          case LIBFWEVT_XML_TOKEN_VALUE:
2330
1.50M
            if( template_value_offset != 0 )
2331
24
            {
2332
24
              libcerror_error_set(
2333
24
               error,
2334
24
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2335
24
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2336
24
               "%s: invalid template value offset value out of bounds.",
2337
24
               function );
2338
2339
24
              goto on_error;
2340
24
            }
2341
1.50M
            if( libfwevt_xml_document_read_value(
2342
1.50M
                 internal_xml_document,
2343
1.50M
                 xml_sub_token,
2344
1.50M
                 binary_data,
2345
1.50M
                 binary_data_size,
2346
1.50M
                 binary_data_offset + xml_document_data_offset,
2347
1.50M
                 element_xml_tag,
2348
1.50M
                 error ) != 1 )
2349
141
            {
2350
141
              libcerror_error_set(
2351
141
               error,
2352
141
               LIBCERROR_ERROR_DOMAIN_IO,
2353
141
               LIBCERROR_IO_ERROR_READ_FAILED,
2354
141
               "%s: unable to read value.",
2355
141
               function );
2356
2357
141
              goto on_error;
2358
141
            }
2359
1.49M
            break;
2360
2361
1.49M
          case LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION:
2362
27.2k
            result = libfwevt_xml_document_read_normal_substitution(
2363
27.2k
                internal_xml_document,
2364
27.2k
                xml_sub_token,
2365
27.2k
                binary_data,
2366
27.2k
                binary_data_size,
2367
27.2k
                binary_data_offset + xml_document_data_offset,
2368
27.2k
                ascii_codepage,
2369
27.2k
                flags,
2370
27.2k
                template_values_array,
2371
27.2k
                &template_value_offset,
2372
27.2k
                element_xml_tag,
2373
27.2k
                element_recursion_depth,
2374
27.2k
                template_instance_recursion_depth,
2375
27.2k
                error );
2376
2377
27.2k
            if( result == -1 )
2378
4.52k
            {
2379
4.52k
              libcerror_error_set(
2380
4.52k
               error,
2381
4.52k
               LIBCERROR_ERROR_DOMAIN_IO,
2382
4.52k
               LIBCERROR_IO_ERROR_READ_FAILED,
2383
4.52k
               "%s: unable to read normal substitution.",
2384
4.52k
               function );
2385
2386
4.52k
              goto on_error;
2387
4.52k
            }
2388
22.7k
            break;
2389
2390
640k
          case LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION:
2391
640k
            result = libfwevt_xml_document_read_optional_substitution(
2392
640k
                internal_xml_document,
2393
640k
                xml_sub_token,
2394
640k
                binary_data,
2395
640k
                binary_data_size,
2396
640k
                binary_data_offset + xml_document_data_offset,
2397
640k
                ascii_codepage,
2398
640k
                flags,
2399
640k
                template_values_array,
2400
640k
                &template_value_offset,
2401
640k
                element_xml_tag,
2402
640k
                      element_recursion_depth,
2403
640k
                template_instance_recursion_depth,
2404
640k
                error );
2405
2406
640k
            if( result == -1 )
2407
5.94k
            {
2408
5.94k
              libcerror_error_set(
2409
5.94k
               error,
2410
5.94k
               LIBCERROR_ERROR_DOMAIN_IO,
2411
5.94k
               LIBCERROR_IO_ERROR_READ_FAILED,
2412
5.94k
               "%s: unable to read optional substitution.",
2413
5.94k
               function );
2414
2415
5.94k
              goto on_error;
2416
5.94k
            }
2417
634k
            break;
2418
2419
634k
          default:
2420
114
            libcerror_error_set(
2421
114
             error,
2422
114
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2423
114
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2424
114
             "%s: invalid binary XML sub token - unsupported type: 0x%02" PRIx8 ".",
2425
114
             function,
2426
114
             xml_sub_token->type );
2427
2428
114
            goto on_error;
2429
4.08M
        }
2430
4.06M
        xml_document_data_offset += xml_sub_token->size;
2431
2432
4.06M
        if( element_size < xml_sub_token->size )
2433
63
        {
2434
63
          libcerror_error_set(
2435
63
           error,
2436
63
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2437
63
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2438
63
           "%s: invalid element size value too small.",
2439
63
           function );
2440
2441
63
          goto on_error;
2442
63
        }
2443
4.06M
        element_size -= (uint32_t) xml_sub_token->size;
2444
2445
4.06M
        if( ( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG )
2446
4.06M
         || ( xml_sub_token->type == LIBFWEVT_XML_TOKEN_END_ELEMENT_TAG ) )
2447
793k
        {
2448
793k
          break;
2449
793k
        }
2450
4.06M
      }
2451
861k
    }
2452
361k
    else if( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG )
2453
361k
    {
2454
361k
      result = 1;
2455
361k
    }
2456
1.20M
    if( element_size > 0 )
2457
192
    {
2458
192
      libcerror_error_set(
2459
192
       error,
2460
192
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2461
192
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2462
192
       "%s: invalid element size value out of bounds.",
2463
192
       function );
2464
2465
192
      goto on_error;
2466
192
    }
2467
1.20M
    if( result != 0 )
2468
1.13M
    {
2469
1.13M
      if( xml_tag != NULL )
2470
1.13M
      {
2471
1.13M
        if( libfwevt_xml_tag_append_element(
2472
1.13M
             xml_tag,
2473
1.13M
             element_xml_tag,
2474
1.13M
             error ) != 1 )
2475
0
        {
2476
0
          libcerror_error_set(
2477
0
           error,
2478
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2479
0
           LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2480
0
           "%s: unable to append element to XML tag.",
2481
0
           function );
2482
2483
0
          goto on_error;
2484
0
        }
2485
1.13M
        element_xml_tag = NULL;
2486
1.13M
      }
2487
468
      else if( internal_xml_document->root_xml_tag == NULL )
2488
428
      {
2489
428
        internal_xml_document->root_xml_tag = element_xml_tag;
2490
2491
428
        element_xml_tag = NULL;
2492
428
      }
2493
1.13M
    }
2494
1.20M
    template_value_array_recursion_depth++;
2495
1.20M
  }
2496
1.20M
  while( template_value_offset > 0 );
2497
2498
1.13M
  xml_token->size = xml_document_data_offset;
2499
2500
1.13M
  if( element_xml_tag != NULL )
2501
67.6k
  {
2502
67.6k
    if( libfwevt_internal_xml_tag_free(
2503
67.6k
         (libfwevt_internal_xml_tag_t **) &element_xml_tag,
2504
67.6k
         error ) != 1 )
2505
0
    {
2506
0
      libcerror_error_set(
2507
0
       error,
2508
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2509
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2510
0
       "%s: unable to free element XML tag.",
2511
0
       function );
2512
2513
0
      goto on_error;
2514
0
    }
2515
67.6k
  }
2516
1.13M
  if( libfwevt_xml_token_free(
2517
1.13M
       &xml_sub_token,
2518
1.13M
       error ) != 1 )
2519
0
  {
2520
0
    libcerror_error_set(
2521
0
     error,
2522
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2523
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2524
0
     "%s: unable to free binary XML sub token.",
2525
0
     function );
2526
2527
0
    goto on_error;
2528
0
  }
2529
1.13M
  return( 1 );
2530
2531
26.5k
on_error:
2532
26.5k
  if( ( element_xml_tag != NULL )
2533
26.5k
   && ( element_xml_tag != internal_xml_document->root_xml_tag ) )
2534
26.4k
  {
2535
26.4k
    libfwevt_internal_xml_tag_free(
2536
26.4k
     (libfwevt_internal_xml_tag_t **) &element_xml_tag,
2537
26.4k
     NULL );
2538
26.4k
  }
2539
26.5k
  if( xml_sub_token != NULL )
2540
26.5k
  {
2541
26.5k
    libfwevt_xml_token_free(
2542
26.5k
     &xml_sub_token,
2543
26.5k
     NULL );
2544
26.5k
  }
2545
26.5k
  return( -1 );
2546
1.13M
}
2547
2548
/* Reads an entity reference from a binary XML document
2549
 * Returns 1 if successful or -1 on error
2550
 */
2551
int libfwevt_xml_document_read_entity_reference(
2552
     libfwevt_internal_xml_document_t *internal_xml_document,
2553
     libfwevt_xml_token_t *xml_token,
2554
     const uint8_t *binary_data,
2555
     size_t binary_data_size,
2556
     size_t binary_data_offset,
2557
     uint8_t flags,
2558
     libfwevt_xml_tag_t *xml_tag,
2559
     libcerror_error_t **error )
2560
31.0k
{
2561
31.0k
  libfwevt_xml_tag_t *entity_xml_tag = NULL;
2562
31.0k
  uint8_t *entity_name               = NULL;
2563
31.0k
  uint8_t *entity_value_utf16_stream = NULL;
2564
31.0k
  const uint8_t *xml_document_data   = NULL;
2565
31.0k
  static char *function              = "libfwevt_xml_document_read_entity_reference";
2566
31.0k
  size_t additional_value_size       = 0;
2567
31.0k
  size_t trailing_data_size          = 0;
2568
31.0k
  size_t utf8_string_size            = 0;
2569
31.0k
  size_t xml_document_data_offset    = 0;
2570
31.0k
  size_t xml_document_data_size      = 0;
2571
31.0k
  uint32_t entity_name_offset        = 0;
2572
31.0k
  uint32_t entity_name_size          = 0;
2573
31.0k
  uint8_t entity_name_match          = 0;
2574
31.0k
  int data_segment_index             = 0;
2575
2576
31.0k
  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
31.0k
  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
31.0k
  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
31.0k
  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
31.0k
  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
31.0k
  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
31.0k
  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
31.0k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
2655
31.0k
  {
2656
31.0k
    additional_value_size = 4;
2657
31.0k
  }
2658
31.0k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
2659
31.0k
  xml_document_data_size = binary_data_size - binary_data_offset;
2660
2661
31.0k
  if( xml_document_data_size < ( 1 + additional_value_size ) )
2662
50
  {
2663
50
    libcerror_error_set(
2664
50
     error,
2665
50
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2666
50
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2667
50
     "%s: invalid binary XML document data size value too small.",
2668
50
     function );
2669
2670
50
    goto on_error;
2671
50
  }
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
30.9k
  xml_token->size          = 1;
2699
30.9k
  xml_document_data_offset = 1;
2700
2701
30.9k
  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
30.9k
  else
2706
30.9k
  {
2707
30.9k
    if( ( xml_document_data_size < 4 )
2708
30.9k
     || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
2709
6
    {
2710
6
      libcerror_error_set(
2711
6
       error,
2712
6
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2713
6
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2714
6
       "%s: invalid binary XML document data size value too small.",
2715
6
       function );
2716
2717
6
      goto on_error;
2718
6
    }
2719
30.9k
    byte_stream_copy_to_uint32_little_endian(
2720
30.9k
     &( xml_document_data[ xml_document_data_offset ] ),
2721
30.9k
     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
30.9k
    xml_token->size          += 4;
2733
30.9k
    xml_document_data_offset += 4;
2734
30.9k
  }
2735
#if defined( HAVE_DEBUG_OUTPUT )
2736
  if( libcnotify_verbose != 0 )
2737
  {
2738
    libcnotify_printf(
2739
     "\n" );
2740
  }
2741
#endif
2742
30.9k
  if( entity_name_offset > ( binary_data_offset + xml_document_data_offset ) )
2743
124
  {
2744
124
    libcerror_error_set(
2745
124
     error,
2746
124
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2747
124
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2748
124
     "%s: invalid entity name offset value out of bounds.",
2749
124
     function );
2750
2751
124
    goto on_error;
2752
124
  }
2753
30.8k
  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
30.8k
  if( libfwevt_xml_tag_initialize(
2778
30.8k
       &entity_xml_tag,
2779
30.8k
       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
30.8k
  if( libfwevt_xml_document_read_name(
2791
30.8k
       internal_xml_document,
2792
30.8k
       binary_data,
2793
30.8k
       binary_data_size,
2794
30.8k
       entity_name_offset,
2795
30.8k
       flags,
2796
30.8k
       &entity_name_size,
2797
30.8k
       entity_xml_tag,
2798
30.8k
       error ) != 1 )
2799
17
  {
2800
17
    libcerror_error_set(
2801
17
     error,
2802
17
     LIBCERROR_ERROR_DOMAIN_IO,
2803
17
     LIBCERROR_IO_ERROR_READ_FAILED,
2804
17
     "%s: unable to read entity name.",
2805
17
     function );
2806
2807
17
    goto on_error;
2808
17
  }
2809
30.8k
  if( ( binary_data_offset + xml_document_data_offset ) == entity_name_offset )
2810
145
  {
2811
145
    xml_token->size += entity_name_size;
2812
145
  }
2813
30.8k
  if( libfwevt_xml_tag_get_utf8_name_size(
2814
30.8k
       entity_xml_tag,
2815
30.8k
       &utf8_string_size,
2816
30.8k
       error ) != 1 )
2817
100
  {
2818
100
    libcerror_error_set(
2819
100
     error,
2820
100
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2821
100
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2822
100
     "%s: unable to retrieve UTF-8 string size of entity name.",
2823
100
     function );
2824
2825
100
    goto on_error;
2826
100
  }
2827
30.7k
  if( ( utf8_string_size == 0 )
2828
30.7k
   || ( 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
30.7k
  entity_name = (uint8_t *) memory_allocate(
2840
30.7k
                             sizeof( uint8_t ) * utf8_string_size );
2841
2842
30.7k
  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
30.7k
  if( libfwevt_xml_tag_get_utf8_name(
2854
30.7k
       entity_xml_tag,
2855
30.7k
       entity_name,
2856
30.7k
       utf8_string_size,
2857
30.7k
       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
30.7k
  if( libfwevt_xml_tag_set_value_type(
2869
30.7k
       xml_tag,
2870
30.7k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
2871
30.7k
       error ) != 1 )
2872
3
  {
2873
3
    libcerror_error_set(
2874
3
     error,
2875
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2876
3
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2877
3
     "%s: unable to set value type.",
2878
3
     function );
2879
2880
3
    goto on_error;
2881
3
  }
2882
  /* Make sure the character value data is in UTF-16 litte-endian
2883
   */
2884
30.7k
  entity_value_utf16_stream = (uint8_t *) memory_allocate(
2885
30.7k
                                           sizeof( uint8_t ) * 4 );
2886
2887
30.7k
  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
30.7k
  if( utf8_string_size == 3 )
2899
29.5k
  {
2900
29.5k
    if( ( entity_name[ 0 ] == (uint8_t) 'g' )
2901
29.5k
     && ( entity_name[ 1 ] == (uint8_t) 't' ) )
2902
931
    {
2903
931
      entity_value_utf16_stream[ 0 ] = (uint8_t) '>';
2904
931
      entity_value_utf16_stream[ 1 ] = 0;
2905
2906
931
      entity_name_match = 1;
2907
931
    }
2908
28.5k
    else if( ( entity_name[ 0 ] == (uint8_t) 'l' )
2909
28.5k
          && ( entity_name[ 1 ] == (uint8_t) 't' ) )
2910
28.5k
    {
2911
28.5k
      entity_value_utf16_stream[ 0 ] = (uint8_t) '<';
2912
28.5k
      entity_value_utf16_stream[ 1 ] = 0;
2913
2914
28.5k
      entity_name_match = 1;
2915
28.5k
    }
2916
29.5k
  }
2917
1.18k
  else if( utf8_string_size == 4 )
2918
326
  {
2919
326
    if( ( entity_name[ 0 ] == (uint8_t) 'a' )
2920
326
     && ( entity_name[ 1 ] == (uint8_t) 'm' )
2921
326
     && ( entity_name[ 2 ] == (uint8_t) 'p' ) )
2922
259
    {
2923
259
      entity_value_utf16_stream[ 0 ] = (uint8_t) '&';
2924
259
      entity_value_utf16_stream[ 1 ] = 0;
2925
2926
259
      entity_name_match = 1;
2927
259
    }
2928
326
  }
2929
861
  else if( utf8_string_size == 5 )
2930
573
  {
2931
573
    if( ( entity_name[ 0 ] == (uint8_t) 'a' )
2932
573
     && ( entity_name[ 1 ] == (uint8_t) 'p' )
2933
573
     && ( entity_name[ 2 ] == (uint8_t) 'o' )
2934
573
     && ( entity_name[ 3 ] == (uint8_t) 's' ) )
2935
233
    {
2936
233
      entity_value_utf16_stream[ 0 ] = (uint8_t) '\'';
2937
233
      entity_value_utf16_stream[ 1 ] = 0;
2938
2939
233
      entity_name_match = 1;
2940
233
    }
2941
340
    else if( ( entity_name[ 0 ] == (uint8_t) 'q' )
2942
340
          && ( entity_name[ 1 ] == (uint8_t) 'u' )
2943
340
          && ( entity_name[ 2 ] == (uint8_t) 'o' )
2944
340
          && ( entity_name[ 3 ] == (uint8_t) 't' ) )
2945
194
    {
2946
194
      entity_value_utf16_stream[ 0 ] = (uint8_t) '"';
2947
194
      entity_value_utf16_stream[ 1 ] = 0;
2948
2949
194
      entity_name_match = 1;
2950
194
    }
2951
573
  }
2952
30.7k
  if( entity_name_match == 0 )
2953
559
  {
2954
559
    libcerror_error_set(
2955
559
     error,
2956
559
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2957
559
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2958
559
     "%s: unsupported entity name: %s\n",
2959
559
     function,
2960
559
     entity_name );
2961
2962
559
    goto on_error;
2963
559
  }
2964
30.1k
  entity_value_utf16_stream[ 2 ] = 0;
2965
30.1k
  entity_value_utf16_stream[ 3 ] = 0;
2966
2967
30.1k
  memory_free(
2968
30.1k
   entity_name );
2969
2970
30.1k
  entity_name = NULL;
2971
2972
30.1k
  if( libfwevt_xml_tag_append_value_data(
2973
30.1k
       xml_tag,
2974
30.1k
       entity_value_utf16_stream,
2975
30.1k
       4,
2976
30.1k
       &data_segment_index,
2977
30.1k
       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
30.1k
  memory_free(
2989
30.1k
   entity_value_utf16_stream );
2990
2991
30.1k
  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
30.1k
  if( libfwevt_internal_xml_tag_free(
3016
30.1k
       (libfwevt_internal_xml_tag_t **) &entity_xml_tag,
3017
30.1k
       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
30.1k
  return( 1 );
3029
3030
859
on_error:
3031
859
  if( entity_value_utf16_stream != NULL )
3032
559
  {
3033
559
    memory_free(
3034
559
     entity_value_utf16_stream );
3035
559
  }
3036
859
  if( entity_name != NULL )
3037
562
  {
3038
562
    memory_free(
3039
562
     entity_name );
3040
562
  }
3041
859
  if( entity_xml_tag != NULL )
3042
679
  {
3043
679
    libfwevt_internal_xml_tag_free(
3044
679
     (libfwevt_internal_xml_tag_t **) &entity_xml_tag,
3045
679
     NULL );
3046
679
  }
3047
859
  return( -1 );
3048
30.1k
}
3049
3050
/* Reads a fragment from a binary XML document
3051
 * Returns 1 if successful or -1 on error
3052
 */
3053
int libfwevt_xml_document_read_fragment(
3054
     libfwevt_internal_xml_document_t *internal_xml_document,
3055
     libfwevt_xml_token_t *xml_token,
3056
     const uint8_t *binary_data,
3057
     size_t binary_data_size,
3058
     size_t binary_data_offset,
3059
     int ascii_codepage,
3060
     uint8_t flags,
3061
     libcdata_array_t *template_values_array,
3062
     libfwevt_xml_tag_t *xml_tag,
3063
     int element_recursion_depth,
3064
     int template_instance_recursion_depth,
3065
     libcerror_error_t **error )
3066
43.6k
{
3067
43.6k
  libfwevt_xml_token_t *xml_sub_token = NULL;
3068
43.6k
  static char *function               = "libfwevt_xml_document_read_fragment";
3069
3070
43.6k
  if( internal_xml_document == NULL )
3071
0
  {
3072
0
    libcerror_error_set(
3073
0
     error,
3074
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3075
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3076
0
     "%s: invalid binary XML document.",
3077
0
     function );
3078
3079
0
    return( -1 );
3080
0
  }
3081
43.6k
  if( xml_token == NULL )
3082
0
  {
3083
0
    libcerror_error_set(
3084
0
     error,
3085
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3086
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3087
0
     "%s: invalid binary XML token.",
3088
0
     function );
3089
3090
0
    return( -1 );
3091
0
  }
3092
43.6k
  if( libfwevt_xml_document_read_fragment_header(
3093
43.6k
       internal_xml_document,
3094
43.6k
       xml_token,
3095
43.6k
       binary_data,
3096
43.6k
       binary_data_size,
3097
43.6k
       binary_data_offset,
3098
43.6k
       error ) != 1 )
3099
22
  {
3100
22
    libcerror_error_set(
3101
22
     error,
3102
22
     LIBCERROR_ERROR_DOMAIN_IO,
3103
22
     LIBCERROR_IO_ERROR_READ_FAILED,
3104
22
     "%s: unable to read fragment header.",
3105
22
     function );
3106
3107
22
    goto on_error;
3108
22
  }
3109
43.6k
  binary_data_offset += xml_token->size;
3110
3111
43.6k
  if( libfwevt_xml_token_initialize(
3112
43.6k
       &xml_sub_token,
3113
43.6k
       error ) != 1 )
3114
0
  {
3115
0
    libcerror_error_set(
3116
0
     error,
3117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3118
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3119
0
     "%s: unable to create binary XML sub token.",
3120
0
     function );
3121
3122
0
    goto on_error;
3123
0
  }
3124
43.6k
  if( libfwevt_xml_token_read_data(
3125
43.6k
       xml_sub_token,
3126
43.6k
       binary_data,
3127
43.6k
       binary_data_size,
3128
43.6k
       binary_data_offset,
3129
43.6k
       error ) != 1 )
3130
7
  {
3131
7
    libcerror_error_set(
3132
7
     error,
3133
7
     LIBCERROR_ERROR_DOMAIN_IO,
3134
7
     LIBCERROR_IO_ERROR_READ_FAILED,
3135
7
     "%s: unable to read binary XML sub token.",
3136
7
     function );
3137
3138
7
    goto on_error;
3139
7
  }
3140
43.5k
  switch( xml_sub_token->type & 0xbf )
3141
43.5k
  {
3142
2.38k
    case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
3143
2.38k
      if( libfwevt_xml_document_read_element(
3144
2.38k
           internal_xml_document,
3145
2.38k
           xml_sub_token,
3146
2.38k
           binary_data,
3147
2.38k
           binary_data_size,
3148
2.38k
           binary_data_offset,
3149
2.38k
           ascii_codepage,
3150
2.38k
           flags,
3151
2.38k
           template_values_array,
3152
2.38k
           xml_tag,
3153
2.38k
           element_recursion_depth + 1,
3154
2.38k
           template_instance_recursion_depth,
3155
2.38k
           error ) != 1 )
3156
1.87k
      {
3157
1.87k
        libcerror_error_set(
3158
1.87k
         error,
3159
1.87k
         LIBCERROR_ERROR_DOMAIN_IO,
3160
1.87k
         LIBCERROR_IO_ERROR_READ_FAILED,
3161
1.87k
         "%s: unable to read element.",
3162
1.87k
         function );
3163
3164
1.87k
        goto on_error;
3165
1.87k
      }
3166
512
      break;
3167
3168
41.1k
    case LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE:
3169
41.1k
      if( libfwevt_xml_document_read_template_instance(
3170
41.1k
           internal_xml_document,
3171
41.1k
           xml_sub_token,
3172
41.1k
           binary_data,
3173
41.1k
           binary_data_size,
3174
41.1k
           binary_data_offset,
3175
41.1k
           ascii_codepage,
3176
41.1k
           flags,
3177
41.1k
           xml_tag,
3178
41.1k
           element_recursion_depth,
3179
41.1k
           template_instance_recursion_depth + 1,
3180
41.1k
           error ) != 1 )
3181
6.09k
      {
3182
6.09k
        libcerror_error_set(
3183
6.09k
         error,
3184
6.09k
         LIBCERROR_ERROR_DOMAIN_IO,
3185
6.09k
         LIBCERROR_IO_ERROR_READ_FAILED,
3186
6.09k
         "%s: unable to read document template instance.",
3187
6.09k
         function );
3188
3189
6.09k
        goto on_error;
3190
6.09k
      }
3191
35.1k
      break;
3192
3193
35.1k
    default:
3194
11
      libcerror_error_set(
3195
11
       error,
3196
11
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3197
11
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3198
11
       "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3199
11
       function,
3200
11
       xml_sub_token->type );
3201
3202
11
      goto on_error;
3203
43.5k
  }
3204
35.6k
  xml_token->size += xml_sub_token->size;
3205
3206
35.6k
  if( libfwevt_xml_token_free(
3207
35.6k
       &xml_sub_token,
3208
35.6k
       error ) != 1 )
3209
0
  {
3210
0
    libcerror_error_set(
3211
0
     error,
3212
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3213
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3214
0
     "%s: unable to free binary XML sub token.",
3215
0
     function );
3216
3217
0
    goto on_error;
3218
0
  }
3219
35.6k
  return( 1 );
3220
3221
8.00k
on_error:
3222
8.00k
  if( xml_sub_token != NULL )
3223
7.98k
  {
3224
7.98k
    libfwevt_xml_token_free(
3225
7.98k
     &xml_sub_token,
3226
7.98k
     NULL );
3227
7.98k
  }
3228
8.00k
  return( -1 );
3229
35.6k
}
3230
3231
/* Reads a fragment header from a binary XML document
3232
 * Returns 1 if successful or -1 on error
3233
 */
3234
int libfwevt_xml_document_read_fragment_header(
3235
     libfwevt_internal_xml_document_t *internal_xml_document,
3236
     libfwevt_xml_token_t *xml_token,
3237
     const uint8_t *binary_data,
3238
     size_t binary_data_size,
3239
     size_t binary_data_offset,
3240
     libcerror_error_t **error )
3241
129k
{
3242
129k
  static char *function            = "libfwevt_xml_document_read_fragment_header";
3243
129k
  size_t xml_document_data_size    = 0;
3244
3245
#if defined( HAVE_DEBUG_OUTPUT )
3246
  const uint8_t *xml_document_data = NULL;
3247
#endif
3248
3249
129k
  if( internal_xml_document == NULL )
3250
0
  {
3251
0
    libcerror_error_set(
3252
0
     error,
3253
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3254
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3255
0
     "%s: invalid binary XML document.",
3256
0
     function );
3257
3258
0
    return( -1 );
3259
0
  }
3260
129k
  if( xml_token == NULL )
3261
0
  {
3262
0
    libcerror_error_set(
3263
0
     error,
3264
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3265
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3266
0
     "%s: invalid binary XML token.",
3267
0
     function );
3268
3269
0
    return( -1 );
3270
0
  }
3271
129k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER )
3272
95
  {
3273
95
    libcerror_error_set(
3274
95
     error,
3275
95
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3276
95
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3277
95
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3278
95
     function,
3279
95
     xml_token->type );
3280
3281
95
    return( -1 );
3282
95
  }
3283
129k
  if( binary_data == NULL )
3284
0
  {
3285
0
    libcerror_error_set(
3286
0
     error,
3287
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3288
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3289
0
     "%s: invalid binary data.",
3290
0
     function );
3291
3292
0
    return( -1 );
3293
0
  }
3294
129k
  if( binary_data_size > (size_t) SSIZE_MAX )
3295
0
  {
3296
0
    libcerror_error_set(
3297
0
     error,
3298
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3299
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3300
0
     "%s: invalid binary XML document data size value exceeds maximum.",
3301
0
     function );
3302
3303
0
    return( -1 );
3304
0
  }
3305
129k
  if( binary_data_offset >= binary_data_size )
3306
0
  {
3307
0
    libcerror_error_set(
3308
0
     error,
3309
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3310
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3311
0
     "%s: invalid binary data offset value out of bounds.",
3312
0
     function );
3313
3314
0
    return( -1 );
3315
0
  }
3316
#if defined( HAVE_DEBUG_OUTPUT )
3317
  xml_document_data = &( binary_data[ binary_data_offset ] );
3318
#endif
3319
3320
129k
  xml_document_data_size = binary_data_size - binary_data_offset;
3321
3322
129k
  if( xml_document_data_size < 4 )
3323
23
  {
3324
23
    libcerror_error_set(
3325
23
     error,
3326
23
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3327
23
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3328
23
     "%s: invalid binary XML document data size value too small.",
3329
23
     function );
3330
3331
23
    return( -1 );
3332
23
  }
3333
#if defined( HAVE_DEBUG_OUTPUT )
3334
  if( libcnotify_verbose != 0 )
3335
  {
3336
    libcnotify_printf(
3337
     "%s: data offset\t\t\t: 0x%08" PRIzx "\n",
3338
     function,
3339
     binary_data_offset );
3340
3341
    libcnotify_printf(
3342
     "%s: fragment header data:\n",
3343
     function );
3344
    libcnotify_print_data(
3345
     xml_document_data,
3346
     4,
3347
     0 );
3348
  }
3349
#endif
3350
#if defined( HAVE_DEBUG_OUTPUT )
3351
  if( libcnotify_verbose != 0 )
3352
  {
3353
    libcnotify_printf(
3354
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
3355
     function,
3356
     xml_document_data[ 0 ] );
3357
3358
    libcnotify_printf(
3359
     "%s: major version\t\t: %" PRIu8 "\n",
3360
     function,
3361
     xml_document_data[ 1 ] );
3362
3363
    libcnotify_printf(
3364
     "%s: minor version\t\t: %" PRIu8 "\n",
3365
     function,
3366
     xml_document_data[ 2 ] );
3367
3368
    libcnotify_printf(
3369
     "%s: flags\t\t\t: 0x%02" PRIx8 "\n",
3370
     function,
3371
     xml_document_data[ 3 ] );
3372
3373
    libcnotify_printf(
3374
     "\n" );
3375
  }
3376
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3377
3378
/* TODO check values */
3379
129k
  xml_token->size = 4;
3380
  
3381
129k
  return( 1 );
3382
129k
}
3383
3384
/* Reads a name from a binary XML document
3385
 * Returns 1 if successful or -1 on error
3386
 */
3387
int libfwevt_xml_document_read_name(
3388
     libfwevt_internal_xml_document_t *internal_xml_document,
3389
     const uint8_t *binary_data,
3390
     size_t binary_data_size,
3391
     size_t binary_data_offset,
3392
     uint8_t flags,
3393
     uint32_t *name_data_size,
3394
     libfwevt_xml_tag_t *xml_tag,
3395
     libcerror_error_t **error )
3396
2.05M
{
3397
2.05M
  const uint8_t *xml_document_data = NULL;
3398
2.05M
  static char *function            = "libfwevt_xml_document_read_name";
3399
2.05M
  size_t additional_value_size     = 0;
3400
2.05M
  size_t xml_document_data_offset  = 0;
3401
2.05M
  size_t xml_document_data_size    = 0;
3402
2.05M
  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.05M
  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.05M
  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.05M
  if( ( binary_data_size < 4 )
3432
2.05M
   || ( 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.05M
  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.05M
  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.05M
  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.05M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3477
2.05M
  xml_document_data_size = binary_data_size - binary_data_offset;
3478
3479
2.05M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
3480
2.05M
  {
3481
2.05M
    additional_value_size += 4;
3482
2.05M
  }
3483
2.05M
  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.05M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
3512
2.05M
  {
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.05M
    xml_document_data_offset += 4;
3527
2.05M
  }
3528
2.05M
  byte_stream_copy_to_uint16_little_endian(
3529
2.05M
   &( xml_document_data[ xml_document_data_offset + 2 ] ),
3530
2.05M
   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.05M
  xml_document_data_offset += 4;
3551
3552
2.05M
  if( ( name_size == 0 )
3553
2.05M
   || ( (size_t) name_size > ( ( MEMORY_MAXIMUM_ALLOCATION_SIZE - 1 ) / 2 ) ) )
3554
33
  {
3555
33
    libcerror_error_set(
3556
33
     error,
3557
33
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3558
33
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3559
33
     "%s: invalid name size value out of bounds.",
3560
33
     function );
3561
3562
33
    return( -1 );
3563
33
  }
3564
2.05M
  name_size = ( name_size + 1 ) * 2;
3565
3566
2.05M
  if( (size_t) name_size > ( xml_document_data_size - xml_document_data_offset ) )
3567
38
  {
3568
38
    libcerror_error_set(
3569
38
     error,
3570
38
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3571
38
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3572
38
     "%s: invalid binary XML document data size value too small.",
3573
38
     function );
3574
3575
38
    return( -1 );
3576
38
  }
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.05M
  if( libfwevt_xml_tag_set_name_data(
3590
2.05M
       xml_tag,
3591
2.05M
       &( xml_document_data[ xml_document_data_offset ] ),
3592
2.05M
       name_size,
3593
2.05M
       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.05M
  *name_data_size = (uint32_t) ( xml_document_data_offset + name_size );
3624
3625
2.05M
  return( 1 );
3626
2.05M
}
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
98.8k
{
3646
98.8k
  const uint8_t *xml_document_data = NULL;
3647
98.8k
  static char *function            = "libfwevt_xml_document_read_normal_substitution";
3648
98.8k
  size_t xml_document_data_size    = 0;
3649
98.8k
  uint16_t template_value_index    = 0;
3650
98.8k
  uint8_t template_value_type      = 0;
3651
98.8k
  int result                       = 0;
3652
3653
98.8k
  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
98.8k
  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
98.8k
  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
98.8k
  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
98.8k
  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
98.8k
  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
98.8k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3721
98.8k
  xml_document_data_size = binary_data_size - binary_data_offset;
3722
3723
98.8k
  if( xml_document_data_size < 4 )
3724
13
  {
3725
13
    libcerror_error_set(
3726
13
     error,
3727
13
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3728
13
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3729
13
     "%s: invalid binary XML document data size value too small.",
3730
13
     function );
3731
3732
13
    return( -1 );
3733
13
  }
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
98.8k
  byte_stream_copy_to_uint16_little_endian(
3752
98.8k
   &( xml_document_data[ 1 ] ),
3753
98.8k
   template_value_index );
3754
3755
98.8k
  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
98.8k
  xml_token->size = 4;
3785
3786
98.8k
  result = libfwevt_xml_document_substitute_template_value(
3787
98.8k
            internal_xml_document,
3788
98.8k
            binary_data,
3789
98.8k
            binary_data_size,
3790
98.8k
            ascii_codepage,
3791
98.8k
            flags,
3792
98.8k
            template_values_array,
3793
98.8k
            template_value_index,
3794
98.8k
            template_value_type,
3795
98.8k
            template_value_offset,
3796
98.8k
            xml_tag,
3797
98.8k
            element_recursion_depth,
3798
98.8k
            template_instance_recursion_depth,
3799
98.8k
            error );
3800
3801
98.8k
  if( result != 1 )
3802
6.15k
  {
3803
6.15k
    libcerror_error_set(
3804
6.15k
     error,
3805
6.15k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3806
6.15k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3807
6.15k
     "%s: unable to substitute template value.",
3808
6.15k
     function );
3809
3810
6.15k
    return( -1 );
3811
6.15k
  }
3812
92.7k
  return( 1 );
3813
98.8k
}
3814
3815
/* Reads an optional substitution from a binary XML document
3816
 * Returns 1 if successful, 0 if no substitution or -1 on error
3817
 */
3818
int libfwevt_xml_document_read_optional_substitution(
3819
     libfwevt_internal_xml_document_t *internal_xml_document,
3820
     libfwevt_xml_token_t *xml_token,
3821
     const uint8_t *binary_data,
3822
     size_t binary_data_size,
3823
     size_t binary_data_offset,
3824
     int ascii_codepage,
3825
     uint8_t flags,
3826
     libcdata_array_t *template_values_array,
3827
     size_t *template_value_offset,
3828
     libfwevt_xml_tag_t *xml_tag,
3829
     int element_recursion_depth,
3830
     int template_instance_recursion_depth,
3831
     libcerror_error_t **error )
3832
1.07M
{
3833
1.07M
  const uint8_t *xml_document_data = NULL;
3834
1.07M
  static char *function            = "libfwevt_xml_document_read_optional_substitution";
3835
1.07M
  size_t xml_document_data_size    = 0;
3836
1.07M
  uint16_t template_value_index    = 0;
3837
1.07M
  uint8_t template_value_type      = 0;
3838
1.07M
  int result                       = 0;
3839
3840
1.07M
  if( internal_xml_document == NULL )
3841
0
  {
3842
0
    libcerror_error_set(
3843
0
     error,
3844
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3845
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3846
0
     "%s: invalid binary XML document.",
3847
0
     function );
3848
3849
0
    return( -1 );
3850
0
  }
3851
1.07M
  if( xml_token == NULL )
3852
0
  {
3853
0
    libcerror_error_set(
3854
0
     error,
3855
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3856
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3857
0
     "%s: invalid binary XML token.",
3858
0
     function );
3859
3860
0
    return( -1 );
3861
0
  }
3862
1.07M
  if( xml_token->type != LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION )
3863
0
  {
3864
0
    libcerror_error_set(
3865
0
     error,
3866
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3867
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3868
0
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3869
0
     function,
3870
0
     xml_token->type );
3871
3872
0
    return( -1 );
3873
0
  }
3874
1.07M
  if( binary_data == NULL )
3875
0
  {
3876
0
    libcerror_error_set(
3877
0
     error,
3878
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3879
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3880
0
     "%s: invalid binary data.",
3881
0
     function );
3882
3883
0
    return( -1 );
3884
0
  }
3885
1.07M
  if( binary_data_size > (size_t) SSIZE_MAX )
3886
0
  {
3887
0
    libcerror_error_set(
3888
0
     error,
3889
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3890
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3891
0
     "%s: invalid binary XML document data size value exceeds maximum.",
3892
0
     function );
3893
3894
0
    return( -1 );
3895
0
  }
3896
1.07M
  if( binary_data_offset >= binary_data_size )
3897
0
  {
3898
0
    libcerror_error_set(
3899
0
     error,
3900
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3901
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3902
0
     "%s: invalid binary data offset value out of bounds.",
3903
0
     function );
3904
3905
0
    return( -1 );
3906
0
  }
3907
1.07M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3908
1.07M
  xml_document_data_size = binary_data_size - binary_data_offset;
3909
3910
1.07M
  if( xml_document_data_size < 4 )
3911
11
  {
3912
11
    libcerror_error_set(
3913
11
     error,
3914
11
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3915
11
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3916
11
     "%s: invalid binary XML document data size value too small.",
3917
11
     function );
3918
3919
11
    return( -1 );
3920
11
  }
3921
#if defined( HAVE_DEBUG_OUTPUT )
3922
  if( libcnotify_verbose != 0 )
3923
  {
3924
    libcnotify_printf(
3925
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
3926
     function,
3927
     binary_data_offset );
3928
3929
    libcnotify_printf(
3930
     "%s: optional substitution data:\n",
3931
     function );
3932
    libcnotify_print_data(
3933
     xml_document_data,
3934
     4,
3935
     0 );
3936
  }
3937
#endif
3938
1.07M
  byte_stream_copy_to_uint16_little_endian(
3939
1.07M
   &( xml_document_data[ 1 ] ),
3940
1.07M
   template_value_index );
3941
3942
1.07M
  template_value_type = xml_document_data[ 3 ];
3943
3944
#if defined( HAVE_DEBUG_OUTPUT )
3945
  if( libcnotify_verbose != 0 )
3946
  {
3947
    libcnotify_printf(
3948
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
3949
     function,
3950
     xml_document_data[ 0 ] );
3951
3952
    libcnotify_printf(
3953
     "%s: identifier\t\t: %" PRIu16 "\n",
3954
     function,
3955
     template_value_index );
3956
3957
    libcnotify_printf(
3958
     "%s: value type\t\t: 0x%02" PRIx8 " (",
3959
     function,
3960
     template_value_type );
3961
    libfwevt_debug_print_value_type(
3962
     template_value_type );
3963
    libcnotify_printf(
3964
     ")\n" );
3965
3966
    libcnotify_printf(
3967
     "\n" );
3968
  }
3969
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3970
3971
1.07M
  xml_token->size = 4;
3972
3973
1.07M
  result = libfwevt_xml_document_substitute_template_value(
3974
1.07M
            internal_xml_document,
3975
1.07M
            binary_data,
3976
1.07M
            binary_data_size,
3977
1.07M
            ascii_codepage,
3978
1.07M
            flags,
3979
1.07M
            template_values_array,
3980
1.07M
            template_value_index,
3981
1.07M
            template_value_type,
3982
1.07M
            template_value_offset,
3983
1.07M
            xml_tag,
3984
1.07M
            element_recursion_depth,
3985
1.07M
            template_instance_recursion_depth,
3986
1.07M
            error );
3987
3988
1.07M
  if( result == -1 )
3989
7.40k
  {
3990
7.40k
    libcerror_error_set(
3991
7.40k
     error,
3992
7.40k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3993
7.40k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3994
7.40k
     "%s: unable to substitute template value.",
3995
7.40k
     function );
3996
3997
7.40k
    return( -1 );
3998
7.40k
  }
3999
1.07M
  return( result );
4000
1.07M
}
4001
4002
/* Reads a PI data from a binary XML document
4003
 * Returns 1 if successful or -1 on error
4004
 */
4005
int libfwevt_xml_document_read_pi_data(
4006
     libfwevt_internal_xml_document_t *internal_xml_document,
4007
     libfwevt_xml_token_t *xml_token,
4008
     const uint8_t *binary_data,
4009
     size_t binary_data_size,
4010
     size_t binary_data_offset,
4011
     libfwevt_xml_tag_t *xml_tag,
4012
     libcerror_error_t **error )
4013
2.57k
{
4014
2.57k
  const uint8_t *xml_document_data = NULL;
4015
2.57k
  static char *function            = "libfwevt_xml_document_read_pi_data";
4016
2.57k
  size_t value_data_size           = 0;
4017
2.57k
  size_t xml_document_data_size    = 0;
4018
4019
2.57k
  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.57k
  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.57k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_PI_DATA )
4042
56
  {
4043
56
    libcerror_error_set(
4044
56
     error,
4045
56
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4046
56
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4047
56
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
4048
56
     function,
4049
56
     xml_token->type );
4050
4051
56
    return( -1 );
4052
56
  }
4053
2.52k
  if( binary_data == NULL )
4054
0
  {
4055
0
    libcerror_error_set(
4056
0
     error,
4057
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4058
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4059
0
     "%s: invalid binary data.",
4060
0
     function );
4061
4062
0
    return( -1 );
4063
0
  }
4064
2.52k
  if( binary_data_size > (size_t) SSIZE_MAX )
4065
0
  {
4066
0
    libcerror_error_set(
4067
0
     error,
4068
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4069
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4070
0
     "%s: invalid binary XML document data size value exceeds maximum.",
4071
0
     function );
4072
4073
0
    return( -1 );
4074
0
  }
4075
2.52k
  if( binary_data_offset >= binary_data_size )
4076
0
  {
4077
0
    libcerror_error_set(
4078
0
     error,
4079
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4080
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4081
0
     "%s: invalid binary data offset value out of bounds.",
4082
0
     function );
4083
4084
0
    return( -1 );
4085
0
  }
4086
2.52k
  if( xml_tag == NULL )
4087
0
  {
4088
0
    libcerror_error_set(
4089
0
     error,
4090
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4091
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4092
0
     "%s: invalid XML tag.",
4093
0
     function );
4094
4095
0
    return( -1 );
4096
0
  }
4097
2.52k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4098
2.52k
  xml_document_data_size = binary_data_size - binary_data_offset;
4099
4100
2.52k
  if( xml_document_data_size < 3 )
4101
8
  {
4102
8
    libcerror_error_set(
4103
8
     error,
4104
8
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4105
8
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4106
8
     "%s: invalid binary XML document data size value too small.",
4107
8
     function );
4108
4109
8
    return( -1 );
4110
8
  }
4111
#if defined( HAVE_DEBUG_OUTPUT )
4112
  if( libcnotify_verbose != 0 )
4113
  {
4114
    libcnotify_printf(
4115
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
4116
     function,
4117
     binary_data_offset );
4118
4119
    libcnotify_printf(
4120
     "%s: PI data:\n",
4121
     function );
4122
    libcnotify_print_data(
4123
     xml_document_data,
4124
     3,
4125
     0 );
4126
  }
4127
#endif
4128
2.51k
  byte_stream_copy_to_uint16_little_endian(
4129
2.51k
   &( xml_document_data[ 1 ] ),
4130
2.51k
   value_data_size );
4131
4132
#if defined( HAVE_DEBUG_OUTPUT )
4133
  if( libcnotify_verbose != 0 )
4134
  {
4135
    libcnotify_printf(
4136
     "%s: type\t\t\t\t: 0x%02" PRIx8 "\n",
4137
     function,
4138
     xml_document_data[ 0 ] );
4139
4140
    libcnotify_printf(
4141
     "%s: number of characters\t\t: %" PRIzd "\n",
4142
     function,
4143
     value_data_size );
4144
  }
4145
#endif
4146
2.51k
  xml_token->size     = 3;
4147
2.51k
  binary_data_offset += 3;
4148
4149
2.51k
  value_data_size *= 2;
4150
4151
2.51k
  if( ( value_data_size > binary_data_size )
4152
2.51k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
4153
86
  {
4154
86
    libcerror_error_set(
4155
86
     error,
4156
86
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4157
86
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4158
86
     "%s: invalid value data size value out of bounds.",
4159
86
     function );
4160
4161
86
    return( -1 );
4162
86
  }
4163
#if defined( HAVE_DEBUG_OUTPUT )
4164
  if( libcnotify_verbose != 0 )
4165
  {
4166
    libcnotify_printf(
4167
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
4168
     function,
4169
     binary_data_offset );
4170
4171
    libcnotify_printf(
4172
     "%s: value data:\n",
4173
     function );
4174
    libcnotify_print_data(
4175
     &( xml_document_data[ 3 ] ),
4176
     value_data_size,
4177
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
4178
  }
4179
#endif
4180
2.42k
  if( libfwevt_xml_tag_set_value_type(
4181
2.42k
       xml_tag,
4182
2.42k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
4183
2.42k
       error ) != 1 )
4184
0
  {
4185
0
    libcerror_error_set(
4186
0
     error,
4187
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4188
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4189
0
     "%s: unable to set value type.",
4190
0
     function );
4191
4192
0
    return( -1 );
4193
0
  }
4194
2.42k
  if( libfwevt_xml_tag_set_value_data(
4195
2.42k
       xml_tag,
4196
2.42k
       &( binary_data[ binary_data_offset ] ),
4197
2.42k
       value_data_size,
4198
2.42k
       error ) != 1 )
4199
0
  {
4200
0
    libcerror_error_set(
4201
0
     error,
4202
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4203
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4204
0
     "%s: unable to set value data.",
4205
0
     function );
4206
4207
0
    return( -1 );
4208
0
  }
4209
#if defined( HAVE_DEBUG_OUTPUT )
4210
  if( libcnotify_verbose != 0 )
4211
  {
4212
    if( libfwevt_xml_tag_debug_print_value_data_segment(
4213
         xml_tag,
4214
         0,
4215
         0,
4216
         error ) != 1 )
4217
    {
4218
      libcerror_error_set(
4219
       error,
4220
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4221
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
4222
       "%s: unable to print value data segment: 0.",
4223
       function );
4224
4225
      return( -1 );
4226
    }
4227
  }
4228
#endif
4229
2.42k
  xml_token->size += value_data_size;
4230
4231
2.42k
  return( 1 );
4232
2.42k
}
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.75k
{
4247
2.75k
  libfwevt_xml_tag_t *pi_xml_tag      = NULL;
4248
2.75k
  libfwevt_xml_token_t *xml_sub_token = NULL;
4249
2.75k
  const uint8_t *xml_document_data    = NULL;
4250
2.75k
  static char *function               = "libfwevt_xml_document_read_pi_target";
4251
2.75k
  size_t additional_value_size        = 0;
4252
2.75k
  size_t trailing_data_size           = 0;
4253
2.75k
  size_t xml_document_data_offset     = 0;
4254
2.75k
  size_t xml_document_data_size       = 0;
4255
2.75k
  uint32_t pi_name_offset             = 0;
4256
2.75k
  uint32_t pi_name_size               = 0;
4257
4258
2.75k
  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.75k
  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.75k
  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.75k
  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.75k
  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.75k
  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.75k
  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.75k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
4337
2.75k
  {
4338
2.75k
    additional_value_size = 4;
4339
2.75k
  }
4340
2.75k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4341
2.75k
  xml_document_data_size = binary_data_size - binary_data_offset;
4342
4343
2.75k
  if( xml_document_data_size < ( 1 + additional_value_size ) )
4344
14
  {
4345
14
    libcerror_error_set(
4346
14
     error,
4347
14
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4348
14
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4349
14
     "%s: invalid binary XML document data size value too small.",
4350
14
     function );
4351
4352
14
    return( -1 );
4353
14
  }
4354
2.74k
  if( libfwevt_xml_tag_initialize(
4355
2.74k
       &pi_xml_tag,
4356
2.74k
       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.74k
  if( libfwevt_xml_tag_set_type(
4368
2.74k
       pi_xml_tag,
4369
2.74k
       LIBFWEVT_XML_TAG_TYPE_PI,
4370
2.74k
       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.74k
  xml_token->size          = 1;
4408
2.74k
  xml_document_data_offset = 1;
4409
4410
2.74k
  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.74k
  else
4417
2.74k
  {
4418
2.74k
    if( ( xml_document_data_size < 4 )
4419
2.74k
     || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
4420
6
    {
4421
6
      libcerror_error_set(
4422
6
       error,
4423
6
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4424
6
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4425
6
       "%s: invalid binary XML document data size value too small.",
4426
6
       function );
4427
4428
6
      goto on_error;
4429
6
    }
4430
2.73k
    byte_stream_copy_to_uint32_little_endian(
4431
2.73k
     &( xml_document_data[ xml_document_data_offset ] ),
4432
2.73k
     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.73k
    xml_token->size           = 4;
4444
2.73k
    xml_document_data_offset += 4;
4445
2.73k
  }
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.73k
  xml_token->size          = 5;
4458
2.73k
  xml_document_data_offset = 5;
4459
4460
2.73k
  if( pi_name_offset > ( binary_data_offset + xml_document_data_offset ) )
4461
146
  {
4462
146
    libcerror_error_set(
4463
146
     error,
4464
146
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4465
146
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4466
146
     "%s: invalid PI name offset value out of bounds.",
4467
146
     function );
4468
4469
146
    goto on_error;
4470
146
  }
4471
2.59k
  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.59k
  if( libfwevt_xml_document_read_name(
4496
2.59k
       internal_xml_document,
4497
2.59k
       binary_data,
4498
2.59k
       binary_data_size,
4499
2.59k
       pi_name_offset,
4500
2.59k
       flags,
4501
2.59k
       &pi_name_size,
4502
2.59k
       pi_xml_tag,
4503
2.59k
       error ) != 1 )
4504
5
  {
4505
5
    libcerror_error_set(
4506
5
     error,
4507
5
     LIBCERROR_ERROR_DOMAIN_IO,
4508
5
     LIBCERROR_IO_ERROR_READ_FAILED,
4509
5
     "%s: unable to read PI name.",
4510
5
     function );
4511
4512
5
    goto on_error;
4513
5
  }
4514
2.58k
  if( ( binary_data_offset + xml_document_data_offset ) == pi_name_offset )
4515
464
  {
4516
464
    xml_token->size          += pi_name_size;
4517
464
    xml_document_data_offset += pi_name_size;
4518
464
  }
4519
2.58k
  if( libfwevt_xml_token_initialize(
4520
2.58k
       &xml_sub_token,
4521
2.58k
       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.58k
  if( libfwevt_xml_token_read_data(
4533
2.58k
       xml_sub_token,
4534
2.58k
       binary_data,
4535
2.58k
       binary_data_size,
4536
2.58k
       binary_data_offset + xml_document_data_offset,
4537
2.58k
       error ) != 1 )
4538
10
  {
4539
10
    libcerror_error_set(
4540
10
     error,
4541
10
     LIBCERROR_ERROR_DOMAIN_IO,
4542
10
     LIBCERROR_IO_ERROR_READ_FAILED,
4543
10
     "%s: unable to read binary XML sub token.",
4544
10
     function );
4545
4546
10
    goto on_error;
4547
10
  }
4548
2.57k
  if( libfwevt_xml_document_read_pi_data(
4549
2.57k
       internal_xml_document,
4550
2.57k
       xml_sub_token,
4551
2.57k
       binary_data,
4552
2.57k
       binary_data_size,
4553
2.57k
       binary_data_offset + xml_document_data_offset,
4554
2.57k
       pi_xml_tag,
4555
2.57k
       error ) != 1 )
4556
150
  {
4557
150
    libcerror_error_set(
4558
150
     error,
4559
150
     LIBCERROR_ERROR_DOMAIN_IO,
4560
150
     LIBCERROR_IO_ERROR_READ_FAILED,
4561
150
     "%s: unable to read PI target.",
4562
150
     function );
4563
4564
150
    goto on_error;
4565
150
  }
4566
2.42k
  xml_token->size += xml_sub_token->size;
4567
4568
2.42k
  if( libfwevt_xml_token_free(
4569
2.42k
       &xml_sub_token,
4570
2.42k
       error ) != 1 )
4571
0
  {
4572
0
    libcerror_error_set(
4573
0
     error,
4574
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4575
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4576
0
     "%s: unable to free binary XML sub token.",
4577
0
     function );
4578
4579
0
    goto on_error;
4580
0
  }
4581
2.42k
  if( libfwevt_xml_tag_append_element(
4582
2.42k
       xml_tag,
4583
2.42k
       pi_xml_tag,
4584
2.42k
       error ) != 1 )
4585
0
  {
4586
0
    libcerror_error_set(
4587
0
     error,
4588
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4589
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4590
0
     "%s: unable to append PI to XML tag.",
4591
0
     function );
4592
4593
0
    goto on_error;
4594
0
  }
4595
2.42k
  pi_xml_tag = NULL;
4596
4597
2.42k
  return( 1 );
4598
4599
317
on_error:
4600
317
  if( xml_sub_token != NULL )
4601
160
  {
4602
160
    libfwevt_xml_token_free(
4603
160
     &xml_sub_token,
4604
160
     NULL );
4605
160
  }
4606
317
  if( pi_xml_tag != NULL )
4607
317
  {
4608
317
    libfwevt_internal_xml_tag_free(
4609
317
     (libfwevt_internal_xml_tag_t **) &pi_xml_tag,
4610
317
     NULL );
4611
317
  }
4612
317
  return( -1 );
4613
2.42k
}
4614
4615
/* Reads a template instance from a binary XML document
4616
 * Returns 1 if successful or -1 on error
4617
 */
4618
int libfwevt_xml_document_read_template_instance(
4619
     libfwevt_internal_xml_document_t *internal_xml_document,
4620
     libfwevt_xml_token_t *xml_token,
4621
     const uint8_t *binary_data,
4622
     size_t binary_data_size,
4623
     size_t binary_data_offset,
4624
     int ascii_codepage,
4625
     uint8_t flags,
4626
     libfwevt_xml_tag_t *xml_tag,
4627
     int element_recursion_depth,
4628
     int template_instance_recursion_depth,
4629
     libcerror_error_t **error )
4630
86.7k
{
4631
86.7k
  libcdata_array_t *template_values_array  = NULL;
4632
86.7k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
4633
86.7k
  const uint8_t *xml_document_data         = NULL;
4634
86.7k
  static char *function                    = "libfwevt_xml_document_read_template_instance";
4635
86.7k
  size_t template_data_offset              = 0;
4636
86.7k
  size_t template_data_size                = 0;
4637
86.7k
  size_t template_values_data_offset       = 0;
4638
86.7k
  size_t template_values_data_size         = 0;
4639
86.7k
  size_t trailing_data_size                = 0;
4640
86.7k
  size_t xml_document_data_size            = 0;
4641
86.7k
  uint32_t template_definition_data_offset = 0;
4642
86.7k
  uint32_t template_definition_data_size   = 0;
4643
4644
#if defined( HAVE_DEBUG_OUTPUT )
4645
  uint32_t value_32bit                     = 0;
4646
#endif
4647
4648
86.7k
  if( internal_xml_document == NULL )
4649
0
  {
4650
0
    libcerror_error_set(
4651
0
     error,
4652
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4653
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4654
0
     "%s: invalid binary XML document.",
4655
0
     function );
4656
4657
0
    return( -1 );
4658
0
  }
4659
86.7k
  if( xml_token == NULL )
4660
0
  {
4661
0
    libcerror_error_set(
4662
0
     error,
4663
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4664
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4665
0
     "%s: invalid binary XML token.",
4666
0
     function );
4667
4668
0
    return( -1 );
4669
0
  }
4670
86.7k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE )
4671
0
  {
4672
0
    libcerror_error_set(
4673
0
     error,
4674
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4675
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4676
0
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
4677
0
     function,
4678
0
     xml_token->type );
4679
4680
0
    return( -1 );
4681
0
  }
4682
86.7k
  if( binary_data == NULL )
4683
0
  {
4684
0
    libcerror_error_set(
4685
0
     error,
4686
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4687
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4688
0
     "%s: invalid binary data.",
4689
0
     function );
4690
4691
0
    return( -1 );
4692
0
  }
4693
86.7k
  if( binary_data_size > (size_t) SSIZE_MAX )
4694
0
  {
4695
0
    libcerror_error_set(
4696
0
     error,
4697
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4698
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4699
0
     "%s: invalid binary XML document data size value exceeds maximum.",
4700
0
     function );
4701
4702
0
    return( -1 );
4703
0
  }
4704
86.7k
  if( binary_data_offset >= binary_data_size )
4705
0
  {
4706
0
    libcerror_error_set(
4707
0
     error,
4708
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4709
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4710
0
     "%s: invalid binary data offset value out of bounds.",
4711
0
     function );
4712
4713
0
    return( -1 );
4714
0
  }
4715
86.7k
  if( ( template_instance_recursion_depth < 0 )
4716
86.7k
   || ( template_instance_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_INSTANCE_RECURSION_DEPTH ) )
4717
194
  {
4718
194
    libcerror_error_set(
4719
194
     error,
4720
194
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4721
194
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4722
194
     "%s: invalid template instance recursion depth value out of bounds.",
4723
194
     function );
4724
4725
194
    return( -1 );
4726
194
  }
4727
86.5k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4728
86.5k
  xml_document_data_size = binary_data_size - binary_data_offset;
4729
4730
86.5k
  if( ( binary_data_size < 10 )
4731
86.5k
   || ( binary_data_offset >= ( binary_data_size - 10 ) ) )
4732
30
  {
4733
30
    libcerror_error_set(
4734
30
     error,
4735
30
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4736
30
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4737
30
     "%s: invalid binary XML document data size value too small.",
4738
30
     function );
4739
4740
30
    goto on_error;
4741
30
  }
4742
#if defined( HAVE_DEBUG_OUTPUT )
4743
  if( libcnotify_verbose != 0 )
4744
  {
4745
    libcnotify_printf(
4746
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
4747
     function,
4748
     binary_data_offset );
4749
4750
    libcnotify_printf(
4751
     "%s: template instance header data:\n",
4752
     function );
4753
    libcnotify_print_data(
4754
     xml_document_data,
4755
     10,
4756
     0 );
4757
  }
4758
#endif
4759
86.4k
  byte_stream_copy_to_uint32_little_endian(
4760
86.4k
   &( xml_document_data[ 6 ] ),
4761
86.4k
   template_definition_data_offset );
4762
4763
#if defined( HAVE_DEBUG_OUTPUT )
4764
  if( libcnotify_verbose != 0 )
4765
  {
4766
    libcnotify_printf(
4767
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
4768
     function,
4769
     xml_document_data[ 0 ] );
4770
4771
    libcnotify_printf(
4772
     "%s: unknown1\t\t\t: %" PRIu8 "\n",
4773
     function,
4774
     xml_document_data[ 1 ] );
4775
4776
    byte_stream_copy_to_uint32_little_endian(
4777
     &( xml_document_data[ 2 ] ),
4778
     value_32bit );
4779
    libcnotify_printf(
4780
     "%s: unknown2\t\t\t: 0x%08" PRIx32 "\n",
4781
     function,
4782
     value_32bit );
4783
4784
    libcnotify_printf(
4785
     "%s: data offset\t\t: 0x%08" PRIx32 "\n",
4786
     function,
4787
     template_definition_data_offset );
4788
4789
    libcnotify_printf(
4790
     "\n" );
4791
  }
4792
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4793
4794
86.4k
  xml_token->size     = 10;
4795
86.4k
  binary_data_offset += 10;
4796
4797
86.4k
  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
86.3k
  if( template_definition_data_offset > binary_data_offset )
4809
1.13k
  {
4810
1.13k
    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.13k
    xml_token->size    += trailing_data_size;
4830
1.13k
    binary_data_offset += trailing_data_size;
4831
1.13k
  }
4832
86.3k
  template_data_offset = template_definition_data_offset;
4833
4834
86.3k
  if( ( binary_data_size < 24 )
4835
86.3k
   || ( template_data_offset >= ( binary_data_size - 24 ) ) )
4836
49
  {
4837
49
    libcerror_error_set(
4838
49
     error,
4839
49
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4840
49
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4841
49
     "%s: invalid binary XML document data size value too small.",
4842
49
     function );
4843
4844
49
    goto on_error;
4845
49
  }
4846
86.3k
  byte_stream_copy_to_uint32_little_endian(
4847
86.3k
   &( binary_data[ template_data_offset + 20 ] ),
4848
86.3k
   template_definition_data_size );
4849
4850
#if defined( HAVE_DEBUG_OUTPUT )
4851
  if( libcnotify_verbose != 0 )
4852
  {
4853
    byte_stream_copy_to_uint32_little_endian(
4854
     &( binary_data[ template_data_offset ] ),
4855
     value_32bit );
4856
    libcnotify_printf(
4857
     "%s: offset next\t\t: 0x%08" PRIx32 "\n",
4858
     function,
4859
     value_32bit );
4860
4861
    if( libfwevt_debug_print_guid_value(
4862
         function,
4863
         "identifier\t\t",
4864
         &( binary_data[ template_data_offset + 4 ] ),
4865
         16,
4866
         LIBFGUID_ENDIAN_LITTLE,
4867
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
4868
         error ) != 1 )
4869
    {
4870
      libcerror_error_set(
4871
       error,
4872
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4873
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
4874
       "%s: unable to print GUID value.",
4875
       function );
4876
4877
      return( -1 );
4878
    }
4879
    libcnotify_printf(
4880
     "%s: definition size\t\t: %" PRIu32 "\n",
4881
     function,
4882
     template_definition_data_size );
4883
4884
    libcnotify_printf(
4885
     "\n" );
4886
  }
4887
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4888
4889
86.3k
  if( template_definition_data_size > binary_data_size )
4890
161
  {
4891
161
    libcerror_error_set(
4892
161
     error,
4893
161
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4894
161
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4895
161
     "%s: invalid template definition data size value out of bounds.",
4896
161
     function );
4897
4898
161
    goto on_error;
4899
161
  }
4900
86.1k
  if( template_data_offset == binary_data_offset )
4901
1.85k
  {
4902
1.85k
    template_values_data_offset = 24 + template_definition_data_size;
4903
1.85k
  }
4904
84.3k
  else
4905
84.3k
  {
4906
84.3k
    template_values_data_offset = 0;
4907
84.3k
  }
4908
86.1k
  template_data_offset += 24;
4909
4910
86.1k
  if( template_values_data_offset >= xml_document_data_size )
4911
42
  {
4912
42
    libcerror_error_set(
4913
42
     error,
4914
42
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4915
42
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4916
42
     "%s: invalid template values data offset value out of bounds.",
4917
42
     function );
4918
4919
42
    goto on_error;
4920
42
  }
4921
86.1k
  if( libfwevt_xml_document_read_template_instance_values(
4922
86.1k
       internal_xml_document,
4923
86.1k
       binary_data,
4924
86.1k
       binary_data_size,
4925
86.1k
       binary_data_offset + template_values_data_offset,
4926
86.1k
       &template_values_array,
4927
86.1k
       &template_values_data_size,
4928
86.1k
       error ) != 1 )
4929
402
  {
4930
402
    libcerror_error_set(
4931
402
     error,
4932
402
     LIBCERROR_ERROR_DOMAIN_IO,
4933
402
     LIBCERROR_IO_ERROR_READ_FAILED,
4934
402
     "%s: unable to read document template instance values.",
4935
402
     function );
4936
4937
402
    goto on_error;
4938
402
  }
4939
85.7k
  xml_token->size += template_values_data_size;
4940
4941
85.7k
  if( libfwevt_xml_token_initialize(
4942
85.7k
       &xml_sub_token,
4943
85.7k
       error ) != 1 )
4944
0
  {
4945
0
    libcerror_error_set(
4946
0
     error,
4947
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4948
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4949
0
     "%s: unable to create binary XML sub token.",
4950
0
     function );
4951
4952
0
    goto on_error;
4953
0
  }
4954
85.7k
  if( libfwevt_xml_token_read_data(
4955
85.7k
       xml_sub_token,
4956
85.7k
       binary_data,
4957
85.7k
       binary_data_size,
4958
85.7k
       template_data_offset,
4959
85.7k
       error ) != 1 )
4960
18
  {
4961
18
    libcerror_error_set(
4962
18
     error,
4963
18
     LIBCERROR_ERROR_DOMAIN_IO,
4964
18
     LIBCERROR_IO_ERROR_READ_FAILED,
4965
18
     "%s: unable to read binary XML sub token.",
4966
18
     function );
4967
4968
18
    goto on_error;
4969
18
  }
4970
85.7k
  if( libfwevt_xml_document_read_fragment_header(
4971
85.7k
       internal_xml_document,
4972
85.7k
       xml_sub_token,
4973
85.7k
       binary_data,
4974
85.7k
       binary_data_size,
4975
85.7k
       template_data_offset,
4976
85.7k
       error ) != 1 )
4977
96
  {
4978
96
    libcerror_error_set(
4979
96
     error,
4980
96
     LIBCERROR_ERROR_DOMAIN_IO,
4981
96
     LIBCERROR_IO_ERROR_READ_FAILED,
4982
96
     "%s: unable to read fragment header.",
4983
96
     function );
4984
4985
96
    goto on_error;
4986
96
  }
4987
85.6k
  template_data_offset += xml_sub_token->size;
4988
4989
85.6k
  if( libfwevt_xml_token_read_data(
4990
85.6k
       xml_sub_token,
4991
85.6k
       binary_data,
4992
85.6k
       binary_data_size,
4993
85.6k
       template_data_offset,
4994
85.6k
       error ) != 1 )
4995
7
  {
4996
7
    libcerror_error_set(
4997
7
     error,
4998
7
     LIBCERROR_ERROR_DOMAIN_IO,
4999
7
     LIBCERROR_IO_ERROR_READ_FAILED,
5000
7
     "%s: unable to read binary XML sub token.",
5001
7
     function );
5002
5003
7
    goto on_error;
5004
7
  }
5005
85.5k
  if( libfwevt_xml_document_read_element(
5006
85.5k
       internal_xml_document,
5007
85.5k
       xml_sub_token,
5008
85.5k
       binary_data,
5009
85.5k
       binary_data_size,
5010
85.5k
       template_data_offset,
5011
85.5k
       ascii_codepage,
5012
85.5k
       flags,
5013
85.5k
       template_values_array,
5014
85.5k
       xml_tag,
5015
85.5k
       element_recursion_depth + 1,
5016
85.5k
       template_instance_recursion_depth,
5017
85.5k
       error ) != 1 )
5018
5.31k
  {
5019
5.31k
    libcerror_error_set(
5020
5.31k
     error,
5021
5.31k
     LIBCERROR_ERROR_DOMAIN_IO,
5022
5.31k
     LIBCERROR_IO_ERROR_READ_FAILED,
5023
5.31k
     "%s: unable to read element.",
5024
5.31k
     function );
5025
5026
5.31k
    goto on_error;
5027
5.31k
  }
5028
80.2k
  template_data_offset += xml_sub_token->size;
5029
5030
80.2k
  if( libfwevt_xml_token_read_data(
5031
80.2k
       xml_sub_token,
5032
80.2k
       binary_data,
5033
80.2k
       binary_data_size,
5034
80.2k
       template_data_offset,
5035
80.2k
       error ) != 1 )
5036
12
  {
5037
12
    libcerror_error_set(
5038
12
     error,
5039
12
     LIBCERROR_ERROR_DOMAIN_IO,
5040
12
     LIBCERROR_IO_ERROR_READ_FAILED,
5041
12
     "%s: unable to read binary XML sub token.",
5042
12
     function );
5043
5044
12
    goto on_error;
5045
12
  }
5046
80.2k
  if( xml_sub_token->type != LIBFWEVT_XML_TOKEN_END_OF_FILE )
5047
17
  {
5048
17
    libcerror_error_set(
5049
17
     error,
5050
17
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5051
17
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5052
17
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
5053
17
     function,
5054
17
     xml_token->type );
5055
5056
17
    goto on_error;
5057
17
  }
5058
80.2k
  if( binary_data_offset >= ( binary_data_size - 1 ) )
5059
0
  {
5060
0
    libcerror_error_set(
5061
0
     error,
5062
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5063
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5064
0
     "%s: invalid binary XML document data size value too small.",
5065
0
     function );
5066
5067
0
    goto on_error;
5068
0
  }
5069
#if defined( HAVE_DEBUG_OUTPUT )
5070
  if( libcnotify_verbose != 0 )
5071
  {
5072
    libcnotify_printf(
5073
     "%s: data offset\t\t: 0x%08" PRIzx "\n",
5074
     function,
5075
     binary_data_offset );
5076
5077
    libcnotify_printf(
5078
     "%s: end of file data:\n",
5079
     function );
5080
    libcnotify_print_data(
5081
     &( binary_data[ binary_data_offset ] ),
5082
     1,
5083
     0 );
5084
  }
5085
#endif
5086
#if defined( HAVE_DEBUG_OUTPUT )
5087
  if( libcnotify_verbose != 0 )
5088
  {
5089
    libcnotify_printf(
5090
     "%s: type\t\t\t: 0x%02" PRIx8 "\n",
5091
     function,
5092
     binary_data[ binary_data_offset ] );
5093
5094
    libcnotify_printf(
5095
     "\n" );
5096
  }
5097
#endif
5098
80.2k
  template_data_offset += 1;
5099
5100
80.2k
  if( libfwevt_xml_token_free(
5101
80.2k
       &xml_sub_token,
5102
80.2k
       error ) != 1 )
5103
0
  {
5104
0
    libcerror_error_set(
5105
0
     error,
5106
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5107
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5108
0
     "%s: unable to free binary XML sub token.",
5109
0
     function );
5110
5111
0
    goto on_error;
5112
0
  }
5113
80.2k
  if( template_definition_data_offset == binary_data_offset )
5114
481
  {
5115
481
    template_data_size = template_data_offset
5116
481
                       - template_definition_data_offset;
5117
5118
481
    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
481
    if( template_definition_data_size < ( template_data_size - 24 ) )
5125
2
    {
5126
2
      libcerror_error_set(
5127
2
       error,
5128
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5129
2
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5130
2
       "%s: invalid template definition data size value too small.",
5131
2
       function );
5132
5133
2
      goto on_error;
5134
2
    }
5135
479
    template_definition_data_size -= (uint32_t) ( template_data_size - 24 );
5136
479
  }
5137
/* TODO check if template_definition_data_size is 0 */
5138
5139
80.2k
  if( libcdata_array_free(
5140
80.2k
       &template_values_array,
5141
80.2k
       (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5142
80.2k
       error ) != 1 )
5143
0
  {
5144
0
    libcerror_error_set(
5145
0
     error,
5146
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5147
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5148
0
     "%s: unable to free template values array.",
5149
0
     function );
5150
5151
0
    goto on_error;
5152
0
  }
5153
80.2k
  return( 1 );
5154
5155
6.26k
on_error:
5156
6.26k
  if( template_values_array != NULL )
5157
5.46k
  {
5158
5.46k
    libcdata_array_free(
5159
5.46k
     &template_values_array,
5160
5.46k
     (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5161
5.46k
     NULL );
5162
5.46k
  }
5163
6.26k
  if( xml_sub_token != NULL )
5164
5.46k
  {
5165
5.46k
    libfwevt_xml_token_free(
5166
5.46k
     &xml_sub_token,
5167
5.46k
     NULL );
5168
5.46k
  }
5169
6.26k
  return( -1 );
5170
80.2k
}
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
86.1k
{
5184
86.1k
  libfwevt_xml_template_value_t *template_value = NULL;
5185
86.1k
  static char *function                         = "libfwevt_xml_document_read_template_instance_values";
5186
86.1k
  size_t safe_template_values_size              = 0;
5187
86.1k
  size_t template_value_definitions_data_size   = 0;
5188
86.1k
  size_t template_values_data_size              = 0;
5189
86.1k
  uint32_t number_of_template_values            = 0;
5190
86.1k
  uint32_t template_value_index                 = 0;
5191
86.1k
  uint16_t template_value_data_size             = 0;
5192
86.1k
  uint8_t template_value_type                   = 0;
5193
5194
86.1k
  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
86.1k
  if( ( binary_data_size < 4 )
5206
86.1k
   || ( binary_data_offset >= ( binary_data_size - 4 ) ) )
5207
40
  {
5208
40
    libcerror_error_set(
5209
40
     error,
5210
40
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5211
40
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5212
40
     "%s: invalid binary data size value out of bounds.",
5213
40
     function );
5214
5215
40
    return( -1 );
5216
40
  }
5217
86.0k
  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
86.0k
  byte_stream_copy_to_uint32_little_endian(
5246
86.0k
   &( binary_data[ binary_data_offset ] ),
5247
86.0k
   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
86.0k
  safe_template_values_size = 4;
5262
86.0k
  binary_data_offset       += 4;
5263
5264
86.0k
  template_value_definitions_data_size = number_of_template_values * 4;
5265
5266
86.0k
  if( ( template_value_definitions_data_size > binary_data_size )
5267
86.0k
   || ( binary_data_offset >= ( binary_data_size - template_value_definitions_data_size ) ) )
5268
155
  {
5269
155
    libcerror_error_set(
5270
155
     error,
5271
155
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5272
155
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5273
155
     "%s: invalid template value definitions data size value out of bounds.",
5274
155
     function );
5275
5276
155
    goto on_error;
5277
155
  }
5278
#if defined( HAVE_DEBUG_OUTPUT )
5279
  if( libcnotify_verbose != 0 )
5280
  {
5281
    libcnotify_printf(
5282
     "%s: data offset\t: 0x%08" PRIzx "\n",
5283
     function,
5284
     binary_data_offset );
5285
5286
    libcnotify_printf(
5287
     "%s: template instance value descriptor data:\n",
5288
     function );
5289
    libcnotify_print_data(
5290
     &( binary_data[ binary_data_offset ] ),
5291
     template_value_definitions_data_size,
5292
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
5293
  }
5294
#endif
5295
85.9k
  if( libcdata_array_initialize(
5296
85.9k
       template_values_array,
5297
85.9k
       number_of_template_values,
5298
85.9k
       error ) != 1 )
5299
42
  {
5300
42
    libcerror_error_set(
5301
42
     error,
5302
42
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5303
42
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5304
42
     "%s: unable to create template values array.",
5305
42
     function );
5306
5307
42
    goto on_error;
5308
42
  }
5309
85.8k
  for( template_value_index = 0;
5310
3.85M
       template_value_index < number_of_template_values;
5311
3.77M
       template_value_index++ )
5312
3.77M
  {
5313
3.77M
    byte_stream_copy_to_uint16_little_endian(
5314
3.77M
     &( binary_data[ binary_data_offset ] ),
5315
3.77M
     template_value_data_size );
5316
5317
3.77M
    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.77M
    safe_template_values_size += 4;
5350
3.77M
    binary_data_offset        += 4;
5351
5352
3.77M
    template_values_data_size += template_value_data_size;
5353
5354
3.77M
    if( libfwevt_xml_template_value_initialize(
5355
3.77M
         &template_value,
5356
3.77M
         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.77M
    if( libfwevt_xml_template_value_set_type(
5368
3.77M
         template_value,
5369
3.77M
         template_value_type,
5370
3.77M
         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.77M
    if( libfwevt_xml_template_value_set_size(
5386
3.77M
         template_value,
5387
3.77M
         template_value_data_size,
5388
3.77M
         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.77M
    if( libcdata_array_set_entry_by_index(
5404
3.77M
         *template_values_array,
5405
3.77M
         (int) template_value_index,
5406
3.77M
         (intptr_t *) template_value,
5407
3.77M
         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.77M
    template_value = NULL;
5424
3.77M
  }
5425
85.8k
  if( ( template_values_data_size > binary_data_size )
5426
85.8k
   || ( binary_data_offset >= ( binary_data_size - template_values_data_size ) ) )
5427
165
  {
5428
165
    libcerror_error_set(
5429
165
     error,
5430
165
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5431
165
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5432
165
     "%s: invalid template values data size value out of bounds.",
5433
165
     function );
5434
5435
165
    goto on_error;
5436
165
  }
5437
#if defined( HAVE_DEBUG_OUTPUT )
5438
  if( libcnotify_verbose != 0 )
5439
  {
5440
    libcnotify_printf(
5441
     "%s: data offset\t: 0x%08" PRIzx "\n",
5442
     function,
5443
     binary_data_offset );
5444
5445
    libcnotify_printf(
5446
     "%s: values data:\n",
5447
     function );
5448
    libcnotify_print_data(
5449
     &( binary_data[ binary_data_offset ] ),
5450
     template_values_data_size,
5451
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
5452
  }
5453
#endif
5454
85.7k
  for( template_value_index = 0;
5455
2.12M
       template_value_index < number_of_template_values;
5456
2.03M
       template_value_index++ )
5457
2.03M
  {
5458
2.03M
    if( libcdata_array_get_entry_by_index(
5459
2.03M
         *template_values_array,
5460
2.03M
         (int) template_value_index,
5461
2.03M
         (intptr_t **) &template_value,
5462
2.03M
         error ) != 1 )
5463
0
    {
5464
0
      libcerror_error_set(
5465
0
       error,
5466
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5467
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5468
0
       "%s: unable to retrieve template value: %" PRIu32 " from array.",
5469
0
       function,
5470
0
       template_value_index );
5471
5472
0
      goto on_error;
5473
0
    }
5474
2.03M
    if( libfwevt_xml_template_value_get_size(
5475
2.03M
         template_value,
5476
2.03M
         &template_value_data_size,
5477
2.03M
         error ) != 1 )
5478
0
    {
5479
0
      libcerror_error_set(
5480
0
       error,
5481
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5482
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5483
0
       "%s: unable to retrieve template value data size.",
5484
0
       function );
5485
5486
0
      goto on_error;
5487
0
    }
5488
#if defined( HAVE_DEBUG_OUTPUT )
5489
    if( libcnotify_verbose != 0 )
5490
    {
5491
      libcnotify_printf(
5492
       "%s: data offset\t: 0x%08" PRIzx "\n",
5493
       function,
5494
       binary_data_offset );
5495
5496
      libcnotify_printf(
5497
       "%s: value: %02" PRIu32 " data:\n",
5498
       function,
5499
       template_value_index );
5500
      libcnotify_print_data(
5501
       &( binary_data[ binary_data_offset ] ),
5502
       template_value_data_size,
5503
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
5504
    }
5505
#endif
5506
    /* Note that template_value_data_size is allowed to be 0.
5507
     * Don't set the template value offset in such a case.
5508
     */
5509
2.03M
    if( template_value_data_size == 0 )
5510
1.26M
    {
5511
1.26M
      continue;
5512
1.26M
    }
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
85.7k
  *template_values_size = safe_template_values_size + template_values_data_size;
5530
5531
85.7k
  return( 1 );
5532
5533
362
on_error:
5534
362
  if( template_values_array != NULL )
5535
362
  {
5536
362
    libcdata_array_free(
5537
362
     template_values_array,
5538
362
     (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5539
362
     NULL );
5540
362
  }
5541
362
  return( -1 );
5542
85.7k
}
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.78M
{
5556
1.78M
  const uint8_t *xml_document_data = NULL;
5557
1.78M
  static char *function            = "libfwevt_xml_document_read_value";
5558
1.78M
  size_t value_data_size           = 0;
5559
1.78M
  size_t xml_document_data_size    = 0;
5560
1.78M
  uint8_t value_type               = 0;
5561
1.78M
  int data_segment_index           = 0;
5562
5563
1.78M
  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.78M
  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.78M
  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.78M
  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.78M
  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.78M
  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.78M
  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.78M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
5642
1.78M
  xml_document_data_size = binary_data_size - binary_data_offset;
5643
5644
1.78M
  if( xml_document_data_size < 4 )
5645
51
  {
5646
51
    libcerror_error_set(
5647
51
     error,
5648
51
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5649
51
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5650
51
     "%s: invalid binary XML document data size value too small.",
5651
51
     function );
5652
5653
51
    return( -1 );
5654
51
  }
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.78M
  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.78M
  xml_token->size     = 4;
5693
1.78M
  binary_data_offset += 4;
5694
5695
1.78M
  switch( value_type )
5696
1.78M
  {
5697
1.78M
    case LIBFWEVT_VALUE_TYPE_STRING_UTF16:
5698
1.78M
      byte_stream_copy_to_uint16_little_endian(
5699
1.78M
       &( xml_document_data[ 2 ] ),
5700
1.78M
       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.78M
      value_data_size *= 2;
5712
5713
1.78M
      break;
5714
5715
31
    default:
5716
31
      libcerror_error_set(
5717
31
       error,
5718
31
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5719
31
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5720
31
       "%s: unsupported value type: 0x%02" PRIx8 ".",
5721
31
       function,
5722
31
       value_type );
5723
5724
31
      return( -1 );
5725
1.78M
  }
5726
1.78M
  if( ( value_data_size > binary_data_size )
5727
1.78M
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
5728
102
  {
5729
102
    libcerror_error_set(
5730
102
     error,
5731
102
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5732
102
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5733
102
     "%s: invalid value data size value out of bounds.",
5734
102
     function );
5735
5736
102
    return( -1 );
5737
102
  }
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.78M
  if( libfwevt_xml_tag_set_value_type(
5756
1.78M
       xml_tag,
5757
1.78M
       value_type,
5758
1.78M
       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.78M
  if( libfwevt_xml_tag_append_value_data(
5770
1.78M
       xml_tag,
5771
1.78M
       &( binary_data[ binary_data_offset ] ),
5772
1.78M
       value_data_size,
5773
1.78M
       &data_segment_index,
5774
1.78M
       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.78M
  xml_token->size += value_data_size;
5807
  
5808
1.78M
  return( 1 );
5809
1.78M
}
5810
5811
/* Substitutes a substitution placeholder with a template value
5812
 * Returns 1 if successful, 0 if no substitution or -1 on error
5813
 */
5814
int libfwevt_xml_document_substitute_template_value(
5815
     libfwevt_internal_xml_document_t *internal_xml_document,
5816
     const uint8_t *binary_data,
5817
     size_t binary_data_size,
5818
     int ascii_codepage,
5819
     uint8_t flags,
5820
     libcdata_array_t *template_values_array,
5821
     uint16_t template_value_index,
5822
     uint8_t template_value_type,
5823
     size_t *template_value_offset,
5824
     libfwevt_xml_tag_t *xml_tag,
5825
     int element_recursion_depth,
5826
     int template_instance_recursion_depth,
5827
     libcerror_error_t **error )
5828
1.17M
{
5829
1.17M
  libfwevt_xml_template_value_t *template_value = NULL;
5830
1.17M
  libfwevt_xml_token_t *xml_sub_token           = NULL;
5831
1.17M
  const uint8_t *template_value_data            = NULL;
5832
1.17M
  static char *function                         = "libfwevt_xml_document_substitute_template_value";
5833
1.17M
  size_t binary_data_offset                     = 0;
5834
1.17M
  size_t safe_template_value_offset             = 0;
5835
1.17M
  size_t template_value_data_offset             = 0;
5836
1.17M
  size_t template_value_data_size               = 0;
5837
1.17M
  size_t template_value_size                    = 0;
5838
1.17M
  uint16_t substitution_value_data_size         = 0;
5839
1.17M
  uint8_t substitution_value_type               = 0;
5840
1.17M
  uint8_t template_value_flags                  = 0;
5841
5842
1.17M
  if( internal_xml_document == NULL )
5843
0
  {
5844
0
    libcerror_error_set(
5845
0
     error,
5846
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5847
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5848
0
     "%s: invalid binary XML document.",
5849
0
     function );
5850
5851
0
    return( -1 );
5852
0
  }
5853
1.17M
  if( template_value_offset == NULL )
5854
0
  {
5855
0
    libcerror_error_set(
5856
0
     error,
5857
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5858
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5859
0
     "%s: invalid template value offset.",
5860
0
     function );
5861
5862
0
    return( -1 );
5863
0
  }
5864
1.17M
  if( xml_tag == NULL )
5865
0
  {
5866
0
    libcerror_error_set(
5867
0
     error,
5868
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5869
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5870
0
     "%s: invalid XML tag.",
5871
0
     function );
5872
5873
0
    return( -1 );
5874
0
  }
5875
1.17M
  if( libcdata_array_get_entry_by_index(
5876
1.17M
       template_values_array,
5877
1.17M
       (int) template_value_index,
5878
1.17M
       (intptr_t **) &template_value,
5879
1.17M
       error ) != 1 )
5880
150
  {
5881
150
    libcerror_error_set(
5882
150
     error,
5883
150
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5884
150
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5885
150
     "%s: unable to retrieve template value: %" PRIu16 " from array.",
5886
150
     function,
5887
150
     template_value_index );
5888
5889
150
    goto on_error;
5890
150
  }
5891
1.17M
  if( libfwevt_xml_template_value_get_flags(
5892
1.17M
       template_value,
5893
1.17M
       &template_value_flags,
5894
1.17M
       error ) != 1 )
5895
0
  {
5896
0
    libcerror_error_set(
5897
0
     error,
5898
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5899
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5900
0
     "%s: unable to retrieve template value flags.",
5901
0
     function );
5902
5903
0
    goto on_error;
5904
0
  }
5905
1.17M
  if( ( template_value_flags & LIBFWEVT_XML_TEMPLATE_VALUE_FLAG_IS_DEFINITION ) != 0 )
5906
0
  {
5907
0
    substitution_value_type = LIBFWEVT_VALUE_TYPE_STRING_UTF16;
5908
0
  }
5909
1.17M
  else
5910
1.17M
  {
5911
1.17M
    if( libfwevt_xml_template_value_get_type(
5912
1.17M
         template_value,
5913
1.17M
         &substitution_value_type,
5914
1.17M
         error ) != 1 )
5915
0
    {
5916
0
      libcerror_error_set(
5917
0
       error,
5918
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5919
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5920
0
       "%s: unable to retrieve template value type.",
5921
0
       function );
5922
5923
0
      goto on_error;
5924
0
    }
5925
1.17M
  }
5926
1.17M
  if( libfwevt_xml_template_value_get_offset(
5927
1.17M
       template_value,
5928
1.17M
       &binary_data_offset,
5929
1.17M
       error ) != 1 )
5930
0
  {
5931
0
    libcerror_error_set(
5932
0
     error,
5933
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5934
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5935
0
     "%s: unable to retrieve template value data offset.",
5936
0
     function );
5937
5938
0
    goto on_error;
5939
0
  }
5940
1.17M
  if( libfwevt_xml_template_value_get_size(
5941
1.17M
       template_value,
5942
1.17M
       &substitution_value_data_size,
5943
1.17M
       error ) != 1 )
5944
0
  {
5945
0
    libcerror_error_set(
5946
0
     error,
5947
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5948
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5949
0
     "%s: unable to retrieve template value data size.",
5950
0
     function );
5951
5952
0
    goto on_error;
5953
0
  }
5954
#if defined( HAVE_DEBUG_OUTPUT )
5955
  if( libcnotify_verbose != 0 )
5956
  {
5957
    libcnotify_printf(
5958
     "%s: value: %02" PRIu32 " offset\t: 0x%08" PRIzx "\n",
5959
     function,
5960
     template_value_index,
5961
     binary_data_offset );
5962
5963
    libcnotify_printf(
5964
     "%s: value: %02" PRIu32 " size\t\t: %" PRIu16 "\n",
5965
     function,
5966
     template_value_index,
5967
     substitution_value_data_size );
5968
5969
    libcnotify_printf(
5970
     "%s: value: %02" PRIu32 " type\t\t: 0x%02" PRIx8 " (",
5971
     function,
5972
     template_value_index,
5973
     substitution_value_type );
5974
    libfwevt_debug_print_value_type(
5975
     substitution_value_type );
5976
    libcnotify_printf(
5977
     ")\n" );
5978
5979
    libcnotify_printf(
5980
     "%s: value: %02" PRIu32 " data:\n",
5981
     function,
5982
     template_value_index );
5983
    libcnotify_print_data(
5984
     &( binary_data[ binary_data_offset ] ),
5985
     substitution_value_data_size,
5986
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
5987
5988
    libcnotify_printf(
5989
     "\n" );
5990
  }
5991
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5992
5993
  /* No substitution
5994
   */
5995
1.17M
  if( substitution_value_type == LIBFWEVT_VALUE_TYPE_NULL )
5996
175k
  {
5997
175k
    *template_value_offset = 0;
5998
5999
175k
    return( 0 );
6000
175k
  }
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.00M
  if( substitution_value_type == LIBFWEVT_VALUE_TYPE_BINARY_XML )
6024
82.7k
  {
6025
82.7k
    if( libfwevt_xml_token_initialize(
6026
82.7k
         &xml_sub_token,
6027
82.7k
         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
82.7k
    if( libfwevt_xml_token_read_data(
6039
82.7k
         xml_sub_token,
6040
82.7k
         binary_data,
6041
82.7k
         binary_data_size,
6042
82.7k
         binary_data_offset,
6043
82.7k
         error ) != 1 )
6044
4
    {
6045
4
      libcerror_error_set(
6046
4
       error,
6047
4
       LIBCERROR_ERROR_DOMAIN_IO,
6048
4
       LIBCERROR_IO_ERROR_READ_FAILED,
6049
4
       "%s: unable to read binary XML sub token.",
6050
4
       function );
6051
6052
4
      goto on_error;
6053
4
    }
6054
82.7k
    switch( xml_sub_token->type & 0xbf )
6055
82.7k
    {
6056
10.0k
      case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
6057
10.0k
        if( libfwevt_xml_document_read_element(
6058
10.0k
             internal_xml_document,
6059
10.0k
             xml_sub_token,
6060
10.0k
             binary_data,
6061
10.0k
             binary_data_size,
6062
10.0k
             binary_data_offset,
6063
10.0k
             ascii_codepage,
6064
10.0k
             flags,
6065
10.0k
             template_values_array,
6066
10.0k
             xml_tag,
6067
10.0k
             element_recursion_depth + 1,
6068
10.0k
             template_instance_recursion_depth,
6069
10.0k
             error ) != 1 )
6070
9.61k
        {
6071
9.61k
          libcerror_error_set(
6072
9.61k
           error,
6073
9.61k
           LIBCERROR_ERROR_DOMAIN_IO,
6074
9.61k
           LIBCERROR_IO_ERROR_READ_FAILED,
6075
9.61k
           "%s: unable to read element.",
6076
9.61k
           function );
6077
6078
9.61k
          goto on_error;
6079
9.61k
        }
6080
407
        break;
6081
6082
27.2k
      case LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER:
6083
27.2k
        if( libfwevt_xml_document_read_fragment(
6084
27.2k
             internal_xml_document,
6085
27.2k
             xml_sub_token,
6086
27.2k
             binary_data,
6087
27.2k
             binary_data_size,
6088
27.2k
             binary_data_offset,
6089
27.2k
             ascii_codepage,
6090
27.2k
             flags,
6091
27.2k
             NULL,
6092
27.2k
             xml_tag,
6093
27.2k
             element_recursion_depth,
6094
27.2k
             template_instance_recursion_depth,
6095
27.2k
             error ) != 1 )
6096
3.21k
        {
6097
3.21k
          libcerror_error_set(
6098
3.21k
           error,
6099
3.21k
           LIBCERROR_ERROR_DOMAIN_IO,
6100
3.21k
           LIBCERROR_IO_ERROR_READ_FAILED,
6101
3.21k
           "%s: unable to read fragment header.",
6102
3.21k
           function );
6103
6104
3.21k
          goto on_error;
6105
3.21k
        }
6106
24.0k
        break;
6107
6108
45.5k
      case LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE:
6109
45.5k
        if( libfwevt_xml_document_read_template_instance(
6110
45.5k
             internal_xml_document,
6111
45.5k
             xml_sub_token,
6112
45.5k
             binary_data,
6113
45.5k
             binary_data_size,
6114
45.5k
             binary_data_offset,
6115
45.5k
             ascii_codepage,
6116
45.5k
             flags,
6117
45.5k
             xml_tag,
6118
45.5k
             element_recursion_depth,
6119
45.5k
             template_instance_recursion_depth + 1,
6120
45.5k
             error ) != 1 )
6121
360
        {
6122
360
          libcerror_error_set(
6123
360
           error,
6124
360
           LIBCERROR_ERROR_DOMAIN_IO,
6125
360
           LIBCERROR_IO_ERROR_READ_FAILED,
6126
360
           "%s: unable to read document template instance.",
6127
360
           function );
6128
6129
360
          goto on_error;
6130
360
        }
6131
45.1k
        break;
6132
6133
45.1k
      default:
6134
9
        libcerror_error_set(
6135
9
         error,
6136
9
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6137
9
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6138
9
         "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
6139
9
         function,
6140
9
         xml_sub_token->type );
6141
6142
9
        goto on_error;
6143
82.7k
    }
6144
69.5k
    if( libfwevt_xml_token_free(
6145
69.5k
         &xml_sub_token,
6146
69.5k
         error ) != 1 )
6147
0
    {
6148
0
      libcerror_error_set(
6149
0
       error,
6150
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6151
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
6152
0
       "%s: unable to free binary XML sub token.",
6153
0
       function );
6154
6155
0
      goto on_error;
6156
0
    }
6157
69.5k
  }
6158
919k
  else
6159
919k
  {
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
919k
    switch( substitution_value_type )
6164
919k
    {
6165
68.7k
      case LIBFWEVT_VALUE_TYPE_STRING_UTF16:
6166
80.9k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_UTF16:
6167
80.9k
        break;
6168
6169
579
      case LIBFWEVT_VALUE_TYPE_STRING_BYTE_STREAM:
6170
25.1k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_BYTE_STREAM:
6171
25.1k
        break;
6172
6173
8.97k
      case LIBFWEVT_VALUE_TYPE_INTEGER_8BIT:
6174
25.1k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_8BIT:
6175
25.1k
        template_value_size = 1;
6176
25.1k
        break;
6177
6178
235k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_8BIT:
6179
266k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_8BIT:
6180
266k
        template_value_size = 1;
6181
266k
        break;
6182
6183
9.40k
      case LIBFWEVT_VALUE_TYPE_INTEGER_16BIT:
6184
10.0k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_16BIT:
6185
10.0k
        template_value_size = 2;
6186
10.0k
        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
443
      case LIBFWEVT_VALUE_TYPE_INTEGER_32BIT:
6194
1.06k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_32BIT:
6195
1.06k
        template_value_size = 4;
6196
1.06k
        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
769
      case LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_32BIT:
6204
1.47k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_HEXADECIMAL_INTEGER_32BIT:
6205
1.47k
        template_value_size = 4;
6206
1.47k
        break;
6207
6208
447
      case LIBFWEVT_VALUE_TYPE_INTEGER_64BIT:
6209
1.14k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_64BIT:
6210
1.14k
        template_value_size = 8;
6211
1.14k
        break;
6212
6213
36.2k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_64BIT:
6214
36.9k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_64BIT:
6215
36.9k
        template_value_size = 8;
6216
36.9k
        break;
6217
6218
69.4k
      case LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_64BIT:
6219
70.1k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_HEXADECIMAL_INTEGER_64BIT:
6220
70.1k
        template_value_size = 8;
6221
70.1k
        break;
6222
6223
509
      case LIBFWEVT_VALUE_TYPE_FLOATING_POINT_32BIT:
6224
1.06k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FLOATING_POINT_32BIT:
6225
1.06k
        template_value_size = 4;
6226
1.06k
        break;
6227
6228
573
      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
521
      case LIBFWEVT_VALUE_TYPE_BOOLEAN:
6234
521
        template_value_size = 4;
6235
521
        break;
6236
6237
15.1k
      case LIBFWEVT_VALUE_TYPE_BINARY_DATA:
6238
15.1k
        break;
6239
6240
420
      case LIBFWEVT_VALUE_TYPE_GUID:
6241
872
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_GUID:
6242
872
        template_value_size = 16;
6243
872
        break;
6244
6245
/* TODO how to deal with array types ? */
6246
1.66k
      case LIBFWEVT_VALUE_TYPE_SIZE:
6247
1.66k
        if( ( substitution_value_data_size != 4 )
6248
1.66k
         && ( substitution_value_data_size != 8 ) )
6249
47
        {
6250
47
          libcerror_error_set(
6251
47
           error,
6252
47
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6253
47
           LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6254
47
           "%s: unsupported value data size: %" PRIu16 ".",
6255
47
           function,
6256
47
           substitution_value_data_size );
6257
6258
47
          goto on_error;
6259
47
        }
6260
1.62k
        break;
6261
6262
69.1k
      case LIBFWEVT_VALUE_TYPE_FILETIME:
6263
69.6k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FILETIME:
6264
69.6k
        template_value_size = 8;
6265
69.6k
        break;
6266
6267
197
      case LIBFWEVT_VALUE_TYPE_SYSTEMTIME:
6268
762
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_SYSTEMTIME:
6269
762
        template_value_size = 16;
6270
762
        break;
6271
6272
3.44k
      case LIBFWEVT_VALUE_TYPE_NT_SECURITY_IDENTIFIER:
6273
3.44k
        break;
6274
6275
9
      default:
6276
9
        libcerror_error_set(
6277
9
         error,
6278
9
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6279
9
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6280
9
         "%s: unsupported value type: 0x%02" PRIx8 ".",
6281
9
         function,
6282
9
         substitution_value_type );
6283
6284
9
        goto on_error;
6285
919k
    }
6286
919k
    if( libfwevt_xml_tag_set_value_type(
6287
919k
         xml_tag,
6288
919k
         substitution_value_type,
6289
919k
         error ) != 1 )
6290
9
    {
6291
9
      libcerror_error_set(
6292
9
       error,
6293
9
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6294
9
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6295
9
       "%s: unable to set value type.",
6296
9
       function );
6297
6298
9
      goto on_error;
6299
9
    }
6300
919k
    if( ( substitution_value_type & LIBFWEVT_VALUE_TYPE_ARRAY ) != 0 )
6301
92.5k
    {
6302
92.5k
      safe_template_value_offset = *template_value_offset;
6303
6304
92.5k
      if( substitution_value_data_size > 0 )
6305
88.4k
      {
6306
88.4k
        if( safe_template_value_offset >= (size_t) substitution_value_data_size )
6307
36
        {
6308
36
          libcerror_error_set(
6309
36
           error,
6310
36
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6311
36
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6312
36
           "%s: invalid template value offset value out of bounds.",
6313
36
           function );
6314
6315
36
          goto on_error;
6316
36
        }
6317
88.4k
        template_value_data      = &( binary_data[ binary_data_offset + safe_template_value_offset ] );
6318
88.4k
        template_value_data_size = substitution_value_data_size - (uint16_t) safe_template_value_offset;
6319
88.4k
      }
6320
92.4k
      if( template_value_data_size > 0 )
6321
88.4k
      {
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
88.4k
        if( substitution_value_type == LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_BYTE_STREAM )
6335
24.2k
        {
6336
24.2k
          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
808k
          while( template_value_data_offset < template_value_data_size ) 
6348
807k
          {
6349
807k
            if( template_value_data[ template_value_data_offset ] == 0 )
6350
23.5k
            {
6351
23.5k
              template_value_data_offset += 1;
6352
6353
23.5k
              break;
6354
23.5k
            }
6355
783k
            template_value_data_offset += 1;
6356
783k
          }
6357
24.2k
          template_value_data_size = template_value_data_offset;
6358
24.2k
        }
6359
64.2k
        else if( substitution_value_type == LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_UTF16 )
6360
11.2k
        {
6361
11.2k
          if( ( template_value_data_size < 2 )
6362
11.2k
           && ( ( template_value_data_size % 2 ) != 0 ) )
6363
6
          {
6364
6
            libcerror_error_set(
6365
6
             error,
6366
6
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6367
6
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6368
6
             "%s: invalid UTF-16 template value data size value out of bounds.",
6369
6
             function );
6370
6371
6
            goto on_error;
6372
6
          }
6373
4.36M
          while( template_value_data_offset < template_value_data_size ) 
6374
4.36M
          {
6375
4.36M
            if( ( template_value_data[ template_value_data_offset ] == 0 )
6376
4.36M
             && ( template_value_data[ template_value_data_offset + 1 ] == 0 ) )
6377
10.5k
            {
6378
10.5k
              template_value_data_offset += 2;
6379
6380
10.5k
              break;
6381
10.5k
            }
6382
4.35M
            template_value_data_offset += 2;
6383
4.35M
          }
6384
11.2k
          template_value_data_size = template_value_data_offset;
6385
11.2k
        }
6386
52.9k
        else
6387
52.9k
        {
6388
52.9k
          if( template_value_size > template_value_data_size )
6389
40
          {
6390
40
            libcerror_error_set(
6391
40
             error,
6392
40
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6393
40
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6394
40
             "%s: invalid template value size value out of bounds.",
6395
40
             function );
6396
6397
40
            goto on_error;
6398
40
          }
6399
52.9k
          template_value_data_size = template_value_size;
6400
52.9k
        }
6401
88.4k
      }
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
92.4k
      if( template_value_data_size > 0 )
6406
88.3k
      {
6407
88.3k
        if( libfwevt_xml_tag_set_value_data(
6408
88.3k
             xml_tag,
6409
88.3k
             template_value_data,
6410
88.3k
             template_value_data_size,
6411
88.3k
             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
88.3k
        safe_template_value_offset += template_value_data_size;
6423
88.3k
      }
6424
92.4k
      if( safe_template_value_offset == substitution_value_data_size )
6425
7.30k
      {
6426
7.30k
        safe_template_value_offset = 0;
6427
7.30k
      }
6428
92.4k
    }
6429
826k
    else
6430
826k
    {
6431
826k
      if( ( template_value_size != 0 )
6432
826k
       && ( template_value_size != substitution_value_data_size ) )
6433
53
      {
6434
53
        libcerror_error_set(
6435
53
         error,
6436
53
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6437
53
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6438
53
         "%s: invalid substitution value data size value out of bounds.",
6439
53
         function );
6440
6441
53
        goto on_error;
6442
53
      }
6443
826k
      else if( ( substitution_value_type == LIBFWEVT_VALUE_TYPE_STRING_UTF16 )
6444
826k
            && ( ( substitution_value_data_size % 2 ) != 0 ) )
6445
3
      {
6446
3
        libcerror_error_set(
6447
3
         error,
6448
3
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6449
3
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6450
3
         "%s: invalid UTF-16 substitution value data size value out of bounds.",
6451
3
         function );
6452
6453
3
        goto on_error;
6454
3
      }
6455
826k
      if( libfwevt_xml_tag_set_value_data(
6456
826k
           xml_tag,
6457
826k
           &( binary_data[ binary_data_offset ] ),
6458
826k
           (size_t) substitution_value_data_size,
6459
826k
           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
826k
    }
6471
919k
    if( libfwevt_xml_tag_set_flags(
6472
919k
         xml_tag,
6473
919k
         LIBFWEVT_XML_TAG_FLAG_IS_TEMPLATE_DEFINITION,
6474
919k
         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
919k
  }
6506
988k
  *template_value_offset = safe_template_value_offset;
6507
6508
988k
  return( 1 );
6509
6510
13.5k
on_error:
6511
13.5k
  if( xml_sub_token != NULL )
6512
13.2k
  {
6513
13.2k
    libfwevt_xml_token_free(
6514
13.2k
     &xml_sub_token,
6515
13.2k
     NULL );
6516
13.2k
  }
6517
13.5k
  return( -1 );
6518
1.00M
}
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