Coverage Report

Created: 2024-02-25 07:20

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