Coverage Report

Created: 2026-10-22 07:28

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