Coverage Report

Created: 2026-07-10 07:32

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.10k
{
51
5.10k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
52
5.10k
  static char *function                                   = "libfwevt_xml_document_initialize";
53
54
5.10k
  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.10k
  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.10k
  internal_xml_document = memory_allocate_structure(
77
5.10k
                           libfwevt_internal_xml_document_t );
78
79
5.10k
  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.10k
  if( memory_set(
91
5.10k
       internal_xml_document,
92
5.10k
       0,
93
5.10k
       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.10k
  *xml_document = (libfwevt_xml_document_t *) internal_xml_document;
105
106
5.10k
  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.10k
}
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.10k
{
124
5.10k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
125
5.10k
  static char *function                                   = "libfwevt_xml_document_free";
126
5.10k
  int result                                              = 1;
127
128
5.10k
  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.10k
  if( *xml_document != NULL )
140
5.10k
  {
141
5.10k
    internal_xml_document = (libfwevt_internal_xml_document_t *) *xml_document;
142
5.10k
    *xml_document         = NULL;
143
144
5.10k
    if( internal_xml_document->root_xml_tag != NULL )
145
486
    {
146
486
      if( libfwevt_internal_xml_tag_free(
147
486
           (libfwevt_internal_xml_tag_t **) &( internal_xml_document->root_xml_tag ),
148
486
           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
486
    }
160
5.10k
    memory_free(
161
5.10k
     internal_xml_document );
162
5.10k
  }
163
5.10k
  return( result );
164
5.10k
}
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.10k
{
218
5.10k
  static char *function = "libfwevt_xml_document_read";
219
220
5.10k
  if( libfwevt_xml_document_read_with_template_values(
221
5.10k
       xml_document,
222
5.10k
       binary_data,
223
5.10k
       binary_data_size,
224
5.10k
       binary_data_offset,
225
5.10k
       ascii_codepage,
226
5.10k
       flags,
227
5.10k
       NULL,
228
5.10k
       error ) != 1 )
229
4.98k
  {
230
4.98k
    libcerror_error_set(
231
4.98k
     error,
232
4.98k
     LIBCERROR_ERROR_DOMAIN_IO,
233
4.98k
     LIBCERROR_IO_ERROR_READ_FAILED,
234
4.98k
     "%s: unable to read XML document.",
235
4.98k
     function );
236
237
4.98k
    return( -1 );
238
4.98k
  }
239
118
  return( 1 );
240
5.10k
}
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.10k
{
255
5.10k
  libfwevt_internal_xml_document_t *internal_xml_document = NULL;
256
5.10k
  libfwevt_xml_token_t *xml_token                         = NULL;
257
5.10k
  static char *function                                   = "libfwevt_xml_document_read_with_template_values";
258
5.10k
  uint8_t supported_flags                                 = 0;
259
260
5.10k
  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.10k
  internal_xml_document = (libfwevt_internal_xml_document_t *) xml_document;
272
273
5.10k
  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.10k
  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.10k
  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.10k
  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.10k
  supported_flags = LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS
318
5.10k
                  | LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DEPENDENCY_IDENTIFIERS;
319
320
5.10k
  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.10k
  if( libfwevt_xml_token_initialize(
333
5.10k
       &xml_token,
334
5.10k
       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
20.0k
  while( binary_data_offset < binary_data_size )
346
20.0k
  {
347
20.0k
    if( libfwevt_xml_token_read_data(
348
20.0k
         xml_token,
349
20.0k
         binary_data,
350
20.0k
         binary_data_size,
351
20.0k
         binary_data_offset,
352
20.0k
         error ) != 1 )
353
31
    {
354
31
      libcerror_error_set(
355
31
       error,
356
31
       LIBCERROR_ERROR_DOMAIN_IO,
357
31
       LIBCERROR_IO_ERROR_READ_FAILED,
358
31
       "%s: unable to read binary XML token.",
359
31
       function );
360
361
31
      goto on_error;
362
31
    }
363
/* TODO check for prologue */
364
/* TODO validate the order */
365
/* TODO check for Miscellaneous before end of file token */
366
20.0k
    switch( xml_token->type & 0xbf )
367
20.0k
    {
368
129
      case LIBFWEVT_XML_TOKEN_END_OF_FILE:
369
129
        if( ( binary_data_size < 1 )
370
129
         || ( 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
115
        xml_token->size = 1;
411
412
115
        break;
413
414
19.8k
      case LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER:
415
19.8k
        if( libfwevt_xml_document_read_fragment(
416
19.8k
             internal_xml_document,
417
19.8k
             xml_token,
418
19.8k
             binary_data,
419
19.8k
             binary_data_size,
420
19.8k
             binary_data_offset,
421
19.8k
             ascii_codepage,
422
19.8k
             flags,
423
19.8k
             template_values_array,
424
19.8k
             internal_xml_document->root_xml_tag,
425
19.8k
             0,
426
19.8k
             0,
427
19.8k
             error ) != 1 )
428
4.88k
        {
429
4.88k
          libcerror_error_set(
430
4.88k
           error,
431
4.88k
           LIBCERROR_ERROR_DOMAIN_IO,
432
4.88k
           LIBCERROR_IO_ERROR_READ_FAILED,
433
4.88k
           "%s: unable to read fragment header.",
434
4.88k
           function );
435
436
4.88k
          goto on_error;
437
4.88k
        }
438
14.9k
        break;
439
440
14.9k
      default:
441
61
        libcerror_error_set(
442
61
         error,
443
61
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
444
61
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
445
61
         "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
446
61
         function,
447
61
         xml_token->type );
448
449
61
        goto on_error;
450
20.0k
    }
451
15.0k
    internal_xml_document->size += xml_token->size;
452
15.0k
    binary_data_offset          += xml_token->size;
453
454
15.0k
    if( xml_token->type == LIBFWEVT_XML_TOKEN_END_OF_FILE )
455
115
    {
456
115
      break;
457
115
    }
458
15.0k
  }
459
118
  if( libfwevt_xml_token_free(
460
118
       &xml_token,
461
118
       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
118
  return( 1 );
473
474
4.98k
on_error:
475
4.98k
  if( xml_token != NULL )
476
4.98k
  {
477
4.98k
    libfwevt_xml_token_free(
478
4.98k
     &xml_token,
479
4.98k
     NULL );
480
4.98k
  }
481
4.98k
  return( -1 );
482
118
}
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
788k
{
501
788k
  libfwevt_xml_tag_t *attribute_xml_tag    = NULL;
502
788k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
503
788k
  const uint8_t *xml_document_data         = NULL;
504
788k
  static char *function                    = "libfwevt_xml_document_read_attribute";
505
788k
  size_t additional_value_size             = 0;
506
788k
  size_t template_value_offset             = 0;
507
788k
  size_t trailing_data_size                = 0;
508
788k
  size_t xml_document_data_offset          = 0;
509
788k
  size_t xml_document_data_size            = 0;
510
788k
  uint32_t attribute_name_offset           = 0;
511
788k
  uint32_t attribute_name_size             = 0;
512
788k
  int result                               = 0;
513
788k
  int template_value_array_recursion_depth = 0;
514
515
788k
  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
788k
  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
788k
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_ATTRIBUTE )
538
29
  {
539
29
    libcerror_error_set(
540
29
     error,
541
29
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
542
29
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
543
29
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
544
29
     function,
545
29
     xml_token->type );
546
547
29
    return( -1 );
548
29
  }
549
788k
  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
788k
  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
788k
  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
788k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
583
788k
  {
584
788k
    additional_value_size = 4;
585
586
788k
    if( ( binary_data_size < 4 )
587
788k
     || ( 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
788k
  }
599
788k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
600
788k
  xml_document_data_size = binary_data_size - binary_data_offset;
601
602
788k
  if( libfwevt_xml_token_initialize(
603
788k
       &xml_sub_token,
604
788k
       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
788k
  do
616
790k
  {
617
790k
    if( ( template_value_array_recursion_depth < 0 )
618
790k
     || ( 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
790k
    if( ( xml_document_data_size < ( additional_value_size + 1 ) )
630
790k
     || ( xml_document_data_offset > ( xml_document_data_size - ( additional_value_size + 1 ) ) ) )
631
24
    {
632
24
      libcerror_error_set(
633
24
       error,
634
24
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
635
24
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
636
24
       "%s: invalid binary XML document data size value too small.",
637
24
       function );
638
639
24
      goto on_error;
640
24
    }
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
790k
    xml_document_data_offset += 1;
668
669
790k
    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
790k
    else
674
790k
    {
675
790k
      if( ( xml_document_data_size < 4 )
676
790k
       || ( 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
790k
      byte_stream_copy_to_uint32_little_endian(
688
790k
       &( xml_document_data[ xml_document_data_offset ] ),
689
790k
       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
790k
      xml_document_data_offset += 4;
701
790k
    }
702
#if defined( HAVE_DEBUG_OUTPUT )
703
    if( libcnotify_verbose != 0 )
704
    {
705
      libcnotify_printf(
706
       "\n" );
707
    }
708
#endif
709
790k
    if( attribute_name_offset > ( binary_data_offset + xml_document_data_offset ) )
710
150
    {
711
150
      libcerror_error_set(
712
150
       error,
713
150
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
714
150
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
715
150
       "%s: invalid attribute data offset value out of bounds.",
716
150
       function );
717
718
150
      goto on_error;
719
150
    }
720
790k
    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
790k
    if( libfwevt_xml_tag_initialize(
744
790k
         &attribute_xml_tag,
745
790k
         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
790k
    if( libfwevt_xml_document_read_name(
757
790k
         internal_xml_document,
758
790k
         binary_data,
759
790k
         binary_data_size,
760
790k
         attribute_name_offset,
761
790k
         flags,
762
790k
         &attribute_name_size,
763
790k
         attribute_xml_tag,
764
790k
         error ) != 1 )
765
17
    {
766
17
      libcerror_error_set(
767
17
       error,
768
17
       LIBCERROR_ERROR_DOMAIN_IO,
769
17
       LIBCERROR_IO_ERROR_READ_FAILED,
770
17
       "%s: unable to read attribute name.",
771
17
       function );
772
773
17
      goto on_error;
774
17
    }
775
790k
    if( ( binary_data_offset + xml_document_data_offset ) == attribute_name_offset )
776
77.1k
    {
777
77.1k
      xml_document_data_offset += attribute_name_size;
778
77.1k
    }
779
790k
    if( libfwevt_xml_token_read_data(
780
790k
         xml_sub_token,
781
790k
         binary_data,
782
790k
         binary_data_size,
783
790k
         binary_data_offset + xml_document_data_offset,
784
790k
         error ) != 1 )
785
17
    {
786
17
      libcerror_error_set(
787
17
       error,
788
17
       LIBCERROR_ERROR_DOMAIN_IO,
789
17
       LIBCERROR_IO_ERROR_READ_FAILED,
790
17
       "%s: unable to read binary XML sub token.",
791
17
       function );
792
793
17
      goto on_error;
794
17
    }
795
790k
    result = 1;
796
797
790k
    switch( xml_sub_token->type & 0xbf )
798
790k
    {
799
285k
      case LIBFWEVT_XML_TOKEN_VALUE:
800
285k
        if( template_value_offset != 0 )
801
23
        {
802
23
          libcerror_error_set(
803
23
           error,
804
23
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
805
23
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
806
23
           "%s: invalid template value offset value out of bounds.",
807
23
           function );
808
809
23
          goto on_error;
810
23
        }
811
285k
        if( libfwevt_xml_document_read_value(
812
285k
             internal_xml_document,
813
285k
             xml_sub_token,
814
285k
             binary_data,
815
285k
             binary_data_size,
816
285k
             binary_data_offset + xml_document_data_offset,
817
285k
             attribute_xml_tag,
818
285k
             ascii_codepage,
819
285k
             error ) != 1 )
820
52
        {
821
52
          libcerror_error_set(
822
52
           error,
823
52
           LIBCERROR_ERROR_DOMAIN_IO,
824
52
           LIBCERROR_IO_ERROR_READ_FAILED,
825
52
           "%s: unable to read value.",
826
52
           function );
827
828
52
          goto on_error;
829
52
        }
830
285k
        break;
831
832
285k
      case LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION:
833
71.0k
        result = libfwevt_xml_document_read_normal_substitution(
834
71.0k
                  internal_xml_document,
835
71.0k
                  xml_sub_token,
836
71.0k
                  binary_data,
837
71.0k
                  binary_data_size,
838
71.0k
                  binary_data_offset + xml_document_data_offset,
839
71.0k
                  ascii_codepage,
840
71.0k
                  flags,
841
71.0k
                  template_values_array,
842
71.0k
                  &template_value_offset,
843
71.0k
                  attribute_xml_tag,
844
71.0k
                  element_recursion_depth,
845
71.0k
                  template_instance_recursion_depth,
846
71.0k
                  error );
847
848
71.0k
        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.0k
        break;
860
861
433k
      case LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION:
862
433k
        result = libfwevt_xml_document_read_optional_substitution(
863
433k
            internal_xml_document,
864
433k
            xml_sub_token,
865
433k
            binary_data,
866
433k
            binary_data_size,
867
433k
            binary_data_offset + xml_document_data_offset,
868
433k
            ascii_codepage,
869
433k
            flags,
870
433k
            template_values_array,
871
433k
            &template_value_offset,
872
433k
            attribute_xml_tag,
873
433k
                  element_recursion_depth,
874
433k
                  template_instance_recursion_depth,
875
433k
            error );
876
877
433k
        if( result == -1 )
878
1.16k
        {
879
1.16k
          libcerror_error_set(
880
1.16k
           error,
881
1.16k
           LIBCERROR_ERROR_DOMAIN_IO,
882
1.16k
           LIBCERROR_IO_ERROR_READ_FAILED,
883
1.16k
           "%s: unable to read optional substitution.",
884
1.16k
           function );
885
886
1.16k
          goto on_error;
887
1.16k
        }
888
432k
        break;
889
890
432k
      default:
891
42
        libcerror_error_set(
892
42
         error,
893
42
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
894
42
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
895
42
         "%s: invalid binary XML sub token - unsupported type: 0x%02" PRIx8 ".",
896
42
         function,
897
42
         xml_sub_token->type );
898
899
42
        goto on_error;
900
790k
    }
901
787k
    if( result != 0 )
902
681k
    {
903
681k
      if( libfwevt_xml_tag_append_attribute(
904
681k
           xml_tag,
905
681k
           attribute_xml_tag,
906
681k
           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
681k
      attribute_xml_tag = NULL;
918
681k
    }
919
787k
    xml_document_data_offset += xml_sub_token->size;
920
921
787k
    template_value_array_recursion_depth++;
922
787k
  }
923
788k
  while( template_value_offset > 0 );
924
925
785k
  xml_token->size = xml_document_data_offset;
926
927
785k
  if( attribute_xml_tag != NULL )
928
106k
  {
929
106k
    if( libfwevt_internal_xml_tag_free(
930
106k
         (libfwevt_internal_xml_tag_t **) &attribute_xml_tag,
931
106k
         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
106k
  }
943
785k
  if( libfwevt_xml_token_free(
944
785k
       &xml_sub_token,
945
785k
       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
785k
  return( 1 );
957
958
3.53k
on_error:
959
3.53k
  if( attribute_xml_tag != NULL )
960
3.35k
  {
961
3.35k
    libfwevt_internal_xml_tag_free(
962
3.35k
     (libfwevt_internal_xml_tag_t **) &attribute_xml_tag,
963
3.35k
     NULL );
964
3.35k
  }
965
3.53k
  if( xml_sub_token != NULL )
966
3.53k
  {
967
3.53k
    libfwevt_xml_token_free(
968
3.53k
     &xml_sub_token,
969
3.53k
     NULL );
970
3.53k
  }
971
3.53k
  return( -1 );
972
785k
}
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
9.70k
{
987
9.70k
  const uint8_t *xml_document_data = NULL;
988
9.70k
  static char *function            = "libfwevt_xml_document_read_cdata_section";
989
9.70k
  size_t value_data_size           = 0;
990
9.70k
  size_t xml_document_data_size    = 0;
991
992
9.70k
  LIBFWEVT_UNREFERENCED_PARAMETER( ascii_codepage )
993
994
9.70k
  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
9.70k
  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
9.70k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_CDATA_SECTION )
1017
6
  {
1018
6
    libcerror_error_set(
1019
6
     error,
1020
6
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1021
6
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1022
6
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1023
6
     function,
1024
6
     xml_token->type );
1025
1026
6
    return( -1 );
1027
6
  }
1028
9.69k
  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
9.69k
  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
9.69k
  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
9.69k
  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
9.69k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1073
9.69k
  xml_document_data_size = binary_data_size - binary_data_offset;
1074
1075
9.69k
  if( xml_document_data_size < 3 )
1076
20
  {
1077
20
    libcerror_error_set(
1078
20
     error,
1079
20
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1080
20
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1081
20
     "%s: invalid binary XML document data size value too small.",
1082
20
     function );
1083
1084
20
    return( -1 );
1085
20
  }
1086
9.67k
  if( libfwevt_xml_tag_set_type(
1087
9.67k
       xml_tag,
1088
9.67k
       LIBFWEVT_XML_TAG_TYPE_CDATA,
1089
9.67k
       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
9.67k
  byte_stream_copy_to_uint16_little_endian(
1118
9.67k
   &( xml_document_data[ 1 ] ),
1119
9.67k
   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
9.67k
  xml_token->size     = 3;
1136
9.67k
  binary_data_offset += 3;
1137
1138
9.67k
  value_data_size *= 2;
1139
1140
9.67k
  if( ( value_data_size > binary_data_size )
1141
9.63k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
1142
87
  {
1143
87
    libcerror_error_set(
1144
87
     error,
1145
87
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1146
87
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1147
87
     "%s: invalid value data size value out of bounds.",
1148
87
     function );
1149
1150
87
    return( -1 );
1151
87
  }
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
9.58k
  if( libfwevt_xml_tag_set_value_type(
1170
9.58k
       xml_tag,
1171
9.58k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
1172
9.58k
       error ) != 1 )
1173
3
  {
1174
3
    libcerror_error_set(
1175
3
     error,
1176
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1177
3
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1178
3
     "%s: unable to set value type.",
1179
3
     function );
1180
1181
3
    return( -1 );
1182
3
  }
1183
9.58k
  if( libfwevt_xml_tag_set_value_data(
1184
9.58k
       xml_tag,
1185
9.58k
       &( binary_data[ binary_data_offset ] ),
1186
9.58k
       value_data_size,
1187
9.58k
       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
9.58k
  xml_token->size += value_data_size;
1221
1222
9.58k
  return( 1 );
1223
9.58k
}
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.18M
{
1603
1.18M
  libfwevt_xml_tag_t *element_xml_tag      = NULL;
1604
1.18M
  libfwevt_xml_token_t *xml_sub_token      = NULL;
1605
1.18M
  const uint8_t *xml_document_data         = NULL;
1606
1.18M
  static char *function                    = "libfwevt_xml_document_read_element";
1607
1.18M
  size_t additional_value_size             = 0;
1608
1.18M
  size_t element_size_offset               = 0;
1609
1.18M
  size_t template_value_offset             = 0;
1610
1.18M
  size_t trailing_data_size                = 0;
1611
1.18M
  size_t xml_document_data_offset          = 0;
1612
1.18M
  size_t xml_document_data_size            = 0;
1613
1.18M
  uint32_t attribute_list_size             = 0;
1614
1.18M
  uint32_t element_name_offset             = 0;
1615
1.18M
  uint32_t element_name_size               = 0;
1616
1.18M
  uint32_t element_size                    = 0;
1617
1.18M
  int result                               = 0;
1618
1.18M
  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.18M
  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.18M
  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.18M
  if( ( xml_token->type & 0xbf ) != LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG )
1647
9
  {
1648
9
    libcerror_error_set(
1649
9
     error,
1650
9
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1651
9
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1652
9
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
1653
9
     function,
1654
9
     xml_token->type );
1655
1656
9
    return( -1 );
1657
9
  }
1658
1.18M
  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.18M
  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.18M
  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.18M
  if( ( element_recursion_depth < 0 )
1692
1.18M
   || ( element_recursion_depth > LIBFWEVT_XML_DOCUMENT_ELEMENT_RECURSION_DEPTH ) )
1693
54
  {
1694
54
    libcerror_error_set(
1695
54
     error,
1696
54
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1697
54
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1698
54
     "%s: invalid element recursion depth value out of bounds.",
1699
54
     function );
1700
1701
54
    return( -1 );
1702
54
  }
1703
1.18M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
1704
1.18M
  {
1705
1.18M
    additional_value_size = 4;
1706
1.18M
  }
1707
1.18M
  if( ( binary_data_size < ( 5 + additional_value_size ) )
1708
1.18M
   || ( binary_data_offset > ( binary_data_size - 5 - additional_value_size ) ) )
1709
46
  {
1710
46
    libcerror_error_set(
1711
46
     error,
1712
46
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1713
46
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1714
46
     "%s: invalid binary XML document data size value too small.",
1715
46
     function );
1716
1717
46
    goto on_error;
1718
46
  }
1719
1.18M
  if( libfwevt_xml_token_initialize(
1720
1.18M
       &xml_sub_token,
1721
1.18M
       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.18M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
1733
1.18M
  xml_document_data_size = binary_data_size - binary_data_offset;
1734
1735
1.18M
  do
1736
1.66M
  {
1737
1.66M
    if( ( template_value_array_recursion_depth < 0 )
1738
1.66M
     || ( template_value_array_recursion_depth > LIBFWEVT_XML_DOCUMENT_TEMPLATE_VALUE_ARRAY_RECURSION_DEPTH ) )
1739
75
    {
1740
75
      libcerror_error_set(
1741
75
       error,
1742
75
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1743
75
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1744
75
       "%s: invalid template value array recursion depth value out of bounds.",
1745
75
       function );
1746
1747
75
      goto on_error;
1748
75
    }
1749
1.66M
    if( libfwevt_xml_tag_initialize(
1750
1.66M
         &element_xml_tag,
1751
1.66M
         error ) != 1 )
1752
32
    {
1753
32
      libcerror_error_set(
1754
32
       error,
1755
32
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1756
32
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1757
32
       "%s: unable to create element XML tag.",
1758
32
       function );
1759
1760
32
      goto on_error;
1761
32
    }
1762
    /* Note that the dependency identifier is an optional value.
1763
     */
1764
1.66M
    element_size_offset = 1;
1765
1766
1.66M
    byte_stream_copy_to_uint32_little_endian(
1767
1.66M
     &( xml_document_data[ element_size_offset ] ),
1768
1.66M
     element_size );
1769
1770
1.66M
    if( ( xml_document_data_size > 7 )
1771
1.66M
     && ( element_size > ( xml_document_data_size - 7 ) ) )
1772
1.15M
    {
1773
1.15M
      element_size_offset = 3;
1774
1.15M
    }
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.66M
    byte_stream_copy_to_uint32_little_endian(
1793
1.66M
     &( xml_document_data[ element_size_offset ] ),
1794
1.66M
     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.66M
    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.66M
    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.66M
    else
1831
1.66M
    {
1832
1.66M
      if( xml_document_data_offset >= ( xml_document_data_size - 4 ) )
1833
67
      {
1834
67
        libcerror_error_set(
1835
67
         error,
1836
67
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1837
67
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1838
67
         "%s: invalid binary XML document data size value too small.",
1839
67
         function );
1840
1841
67
        goto on_error;
1842
67
      }
1843
1.66M
      byte_stream_copy_to_uint32_little_endian(
1844
1.66M
       &( xml_document_data[ xml_document_data_offset ] ),
1845
1.66M
       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.66M
      xml_document_data_offset += 4;
1857
1.66M
      element_size             -= 4;
1858
1.66M
    }
1859
#if defined( HAVE_DEBUG_OUTPUT )
1860
    if( libcnotify_verbose != 0 )
1861
    {
1862
      libcnotify_printf(
1863
       "\n" );
1864
    }
1865
#endif
1866
1.66M
    if( element_name_offset > ( binary_data_offset + xml_document_data_offset ) )
1867
148
    {
1868
148
      libcerror_error_set(
1869
148
       error,
1870
148
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1871
148
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1872
148
       "%s: invalid element data offset value out of bounds.",
1873
148
       function );
1874
1875
148
      goto on_error;
1876
148
    }
1877
1.66M
    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.66M
    if( libfwevt_xml_document_read_name(
1902
1.66M
         internal_xml_document,
1903
1.66M
         binary_data,
1904
1.66M
         binary_data_size,
1905
1.66M
         element_name_offset,
1906
1.66M
         flags,
1907
1.66M
         &element_name_size,
1908
1.66M
         element_xml_tag,
1909
1.66M
         error ) != 1 )
1910
45
    {
1911
45
      libcerror_error_set(
1912
45
       error,
1913
45
       LIBCERROR_ERROR_DOMAIN_IO,
1914
45
       LIBCERROR_IO_ERROR_READ_FAILED,
1915
45
       "%s: unable to read element name.",
1916
45
       function );
1917
1918
45
      goto on_error;
1919
45
    }
1920
1.66M
    if( ( binary_data_offset + xml_document_data_offset ) == element_name_offset )
1921
14.0k
    {
1922
14.0k
      xml_document_data_offset += element_name_size;
1923
14.0k
      element_size             -= element_name_size;
1924
14.0k
    }
1925
1.66M
    if( ( xml_token->type & LIBFWEVT_XML_TOKEN_FLAG_HAS_MORE_DATA ) != 0 )
1926
509k
    {
1927
509k
      if( xml_document_data_offset >= ( xml_document_data_size - 4 ) )
1928
11
      {
1929
11
        libcerror_error_set(
1930
11
         error,
1931
11
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1932
11
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1933
11
         "%s: invalid binary XML document data size value too small.",
1934
11
         function );
1935
1936
11
        goto on_error;
1937
11
      }
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
509k
      byte_stream_copy_to_uint32_little_endian(
1956
509k
       &( xml_document_data[ xml_document_data_offset ] ),
1957
509k
       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
509k
      xml_document_data_offset += 4;
1973
509k
      element_size             -= 4;
1974
1975
509k
      if( attribute_list_size > ( binary_data_size - ( binary_data_offset + xml_document_data_offset ) ) )
1976
80
      {
1977
80
        libcerror_error_set(
1978
80
         error,
1979
80
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1980
80
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1981
80
         "%s: invalid attribute list size value out of bounds.",
1982
80
         function );
1983
1984
80
        goto on_error;
1985
80
      }
1986
1.29M
      while( attribute_list_size > 0 )
1987
788k
      {
1988
788k
        if( libfwevt_xml_token_read_data(
1989
788k
             xml_sub_token,
1990
788k
             binary_data,
1991
788k
             binary_data_size,
1992
788k
             binary_data_offset + xml_document_data_offset,
1993
788k
             error ) != 1 )
1994
22
        {
1995
22
          libcerror_error_set(
1996
22
           error,
1997
22
           LIBCERROR_ERROR_DOMAIN_IO,
1998
22
           LIBCERROR_IO_ERROR_READ_FAILED,
1999
22
           "%s: unable to read binary XML sub token.",
2000
22
           function );
2001
2002
22
          goto on_error;
2003
22
        }
2004
788k
        if( libfwevt_xml_document_read_attribute(
2005
788k
             internal_xml_document,
2006
788k
             xml_sub_token,
2007
788k
             binary_data,
2008
788k
             binary_data_size,
2009
788k
             binary_data_offset + xml_document_data_offset,
2010
788k
             ascii_codepage,
2011
788k
             flags,
2012
788k
             template_values_array,
2013
788k
             element_xml_tag,
2014
788k
             element_recursion_depth,
2015
788k
             template_instance_recursion_depth,
2016
788k
             error ) != 1 )
2017
3.57k
        {
2018
3.57k
          libcerror_error_set(
2019
3.57k
           error,
2020
3.57k
           LIBCERROR_ERROR_DOMAIN_IO,
2021
3.57k
           LIBCERROR_IO_ERROR_READ_FAILED,
2022
3.57k
           "%s: unable to read attribute.",
2023
3.57k
           function );
2024
2025
3.57k
          goto on_error;
2026
3.57k
        }
2027
785k
        xml_document_data_offset += xml_sub_token->size;
2028
785k
        element_size             -= (uint32_t) xml_sub_token->size;
2029
2030
785k
        if( attribute_list_size < xml_sub_token->size )
2031
83
        {
2032
83
          libcerror_error_set(
2033
83
           error,
2034
83
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2035
83
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2036
83
           "%s: invalid attribute list size value too small.",
2037
83
           function );
2038
2039
83
          goto on_error;
2040
83
        }
2041
785k
        attribute_list_size -= (uint32_t) xml_sub_token->size;
2042
785k
      }
2043
509k
    }
2044
1.66M
    if( libfwevt_xml_token_read_data(
2045
1.66M
         xml_sub_token,
2046
1.66M
         binary_data,
2047
1.66M
         binary_data_size,
2048
1.66M
         binary_data_offset + xml_document_data_offset,
2049
1.66M
         error ) != 1 )
2050
26
    {
2051
26
      libcerror_error_set(
2052
26
       error,
2053
26
       LIBCERROR_ERROR_DOMAIN_IO,
2054
26
       LIBCERROR_IO_ERROR_READ_FAILED,
2055
26
       "%s: unable to read binary XML sub token.",
2056
26
       function );
2057
2058
26
      goto on_error;
2059
26
    }
2060
1.66M
    if( ( xml_sub_token->type != LIBFWEVT_XML_TOKEN_CLOSE_START_ELEMENT_TAG )
2061
365k
     && ( xml_sub_token->type != LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG ) )
2062
66
    {
2063
66
      libcerror_error_set(
2064
66
       error,
2065
66
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2066
66
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2067
66
       "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
2068
66
       function,
2069
66
       xml_token->type );
2070
2071
66
      goto on_error;
2072
66
    }
2073
1.66M
    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.66M
    xml_document_data_offset += 1;
2114
1.66M
    element_size             -= 1;
2115
2116
1.66M
    if( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_START_ELEMENT_TAG )
2117
1.29M
    {
2118
1.29M
      result = 1;
2119
2120
4.19M
      while( element_size > 0 )
2121
3.71M
      {
2122
3.71M
        if( libfwevt_xml_token_read_data(
2123
3.71M
             xml_sub_token,
2124
3.71M
             binary_data,
2125
3.71M
             binary_data_size,
2126
3.71M
             binary_data_offset + xml_document_data_offset,
2127
3.71M
             error ) != 1 )
2128
245
        {
2129
245
          libcerror_error_set(
2130
245
           error,
2131
245
           LIBCERROR_ERROR_DOMAIN_IO,
2132
245
           LIBCERROR_IO_ERROR_READ_FAILED,
2133
245
           "%s: unable to read binary XML sub token.",
2134
245
           function );
2135
2136
245
          goto on_error;
2137
245
        }
2138
3.71M
        switch( xml_sub_token->type & 0xbf )
2139
3.71M
        {
2140
1.07M
          case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
2141
1.07M
            if( libfwevt_xml_document_read_element(
2142
1.07M
                 internal_xml_document,
2143
1.07M
                 xml_sub_token,
2144
1.07M
                 binary_data,
2145
1.07M
                 binary_data_size,
2146
1.07M
                 binary_data_offset + xml_document_data_offset,
2147
1.07M
                 ascii_codepage,
2148
1.07M
                 flags,
2149
1.07M
                 template_values_array,
2150
1.07M
                 element_xml_tag,
2151
1.07M
                 element_recursion_depth + 1,
2152
1.07M
                 template_instance_recursion_depth,
2153
1.07M
                 error ) != 1 )
2154
9.78k
            {
2155
9.78k
              libcerror_error_set(
2156
9.78k
               error,
2157
9.78k
               LIBCERROR_ERROR_DOMAIN_IO,
2158
9.78k
               LIBCERROR_IO_ERROR_READ_FAILED,
2159
9.78k
               "%s: unable to read element.",
2160
9.78k
               function );
2161
2162
9.78k
              goto on_error;
2163
9.78k
            }
2164
1.06M
            break;
2165
2166
1.06M
          case LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG:
2167
789k
          case LIBFWEVT_XML_TOKEN_END_ELEMENT_TAG:
2168
789k
            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
789k
            xml_sub_token->size = 1;
2209
2210
789k
            break;
2211
2212
9.70k
          case LIBFWEVT_XML_TOKEN_CDATA_SECTION:
2213
9.70k
            if( template_value_offset != 0 )
2214
7
            {
2215
7
              libcerror_error_set(
2216
7
               error,
2217
7
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2218
7
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2219
7
               "%s: invalid template value offset value out of bounds.",
2220
7
               function );
2221
2222
7
              goto on_error;
2223
7
            }
2224
9.70k
            if( libfwevt_xml_document_read_cdata_section(
2225
9.70k
                 internal_xml_document,
2226
9.70k
                 xml_sub_token,
2227
9.70k
                 binary_data,
2228
9.70k
                 binary_data_size,
2229
9.70k
                 binary_data_offset + xml_document_data_offset,
2230
9.70k
                 element_xml_tag,
2231
9.70k
                 ascii_codepage,
2232
9.70k
                 error ) != 1 )
2233
116
            {
2234
116
              libcerror_error_set(
2235
116
               error,
2236
116
               LIBCERROR_ERROR_DOMAIN_IO,
2237
116
               LIBCERROR_IO_ERROR_READ_FAILED,
2238
116
               "%s: unable to read CDATA section.",
2239
116
               function );
2240
2241
116
              goto on_error;
2242
116
            }
2243
9.58k
            break;
2244
2245
9.58k
          case LIBFWEVT_XML_TOKEN_PI_TARGET:
2246
2.88k
            if( template_value_offset != 0 )
2247
19
            {
2248
19
              libcerror_error_set(
2249
19
               error,
2250
19
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2251
19
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2252
19
               "%s: invalid template value offset value out of bounds.",
2253
19
               function );
2254
2255
19
              goto on_error;
2256
19
            }
2257
2.86k
            if( libfwevt_xml_document_read_pi_target(
2258
2.86k
                 internal_xml_document,
2259
2.86k
                 xml_sub_token,
2260
2.86k
                 binary_data,
2261
2.86k
                 binary_data_size,
2262
2.86k
                 binary_data_offset + xml_document_data_offset,
2263
2.86k
                 flags,
2264
2.86k
                 element_xml_tag,
2265
2.86k
                 ascii_codepage,
2266
2.86k
                 error ) != 1 )
2267
339
            {
2268
339
              libcerror_error_set(
2269
339
               error,
2270
339
               LIBCERROR_ERROR_DOMAIN_IO,
2271
339
               LIBCERROR_IO_ERROR_READ_FAILED,
2272
339
               "%s: unable to read PI target.",
2273
339
               function );
2274
2275
339
              goto on_error;
2276
339
            }
2277
2.52k
            break;
2278
2279
2.52k
          case LIBFWEVT_XML_TOKEN_CHARACTER_REFERENCE:
2280
12
            if( template_value_offset != 0 )
2281
9
            {
2282
9
              libcerror_error_set(
2283
9
               error,
2284
9
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2285
9
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2286
9
               "%s: invalid template value offset value out of bounds.",
2287
9
               function );
2288
2289
9
              goto on_error;
2290
9
            }
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
40.7k
          case LIBFWEVT_XML_TOKEN_ENTITY_REFERENCE:
2313
40.7k
            if( template_value_offset != 0 )
2314
15
            {
2315
15
              libcerror_error_set(
2316
15
               error,
2317
15
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2318
15
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2319
15
               "%s: invalid template value offset value out of bounds.",
2320
15
               function );
2321
2322
15
              goto on_error;
2323
15
            }
2324
40.7k
            if( libfwevt_xml_document_read_entity_reference(
2325
40.7k
                 internal_xml_document,
2326
40.7k
                 xml_sub_token,
2327
40.7k
                 binary_data,
2328
40.7k
                 binary_data_size,
2329
40.7k
                 binary_data_offset + xml_document_data_offset,
2330
40.7k
                 flags,
2331
40.7k
                 element_xml_tag,
2332
40.7k
                 ascii_codepage,
2333
40.7k
                 error ) != 1 )
2334
892
            {
2335
892
              libcerror_error_set(
2336
892
               error,
2337
892
               LIBCERROR_ERROR_DOMAIN_IO,
2338
892
               LIBCERROR_IO_ERROR_READ_FAILED,
2339
892
               "%s: unable to read entity reference.",
2340
892
               function );
2341
2342
892
              goto on_error;
2343
892
            }
2344
39.8k
            break;
2345
2346
704k
          case LIBFWEVT_XML_TOKEN_VALUE:
2347
704k
            if( template_value_offset != 0 )
2348
25
            {
2349
25
              libcerror_error_set(
2350
25
               error,
2351
25
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2352
25
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2353
25
               "%s: invalid template value offset value out of bounds.",
2354
25
               function );
2355
2356
25
              goto on_error;
2357
25
            }
2358
704k
            if( libfwevt_xml_document_read_value(
2359
704k
                 internal_xml_document,
2360
704k
                 xml_sub_token,
2361
704k
                 binary_data,
2362
704k
                 binary_data_size,
2363
704k
                 binary_data_offset + xml_document_data_offset,
2364
704k
                 element_xml_tag,
2365
704k
                 ascii_codepage,
2366
704k
                 error ) != 1 )
2367
116
            {
2368
116
              libcerror_error_set(
2369
116
               error,
2370
116
               LIBCERROR_ERROR_DOMAIN_IO,
2371
116
               LIBCERROR_IO_ERROR_READ_FAILED,
2372
116
               "%s: unable to read value.",
2373
116
               function );
2374
2375
116
              goto on_error;
2376
116
            }
2377
704k
            break;
2378
2379
704k
          case LIBFWEVT_XML_TOKEN_NORMAL_SUBSTITUTION:
2380
469k
            result = libfwevt_xml_document_read_normal_substitution(
2381
469k
                internal_xml_document,
2382
469k
                xml_sub_token,
2383
469k
                binary_data,
2384
469k
                binary_data_size,
2385
469k
                binary_data_offset + xml_document_data_offset,
2386
469k
                ascii_codepage,
2387
469k
                flags,
2388
469k
                template_values_array,
2389
469k
                &template_value_offset,
2390
469k
                element_xml_tag,
2391
469k
                element_recursion_depth,
2392
469k
                template_instance_recursion_depth,
2393
469k
                error );
2394
2395
469k
            if( result == -1 )
2396
5.09k
            {
2397
5.09k
              libcerror_error_set(
2398
5.09k
               error,
2399
5.09k
               LIBCERROR_ERROR_DOMAIN_IO,
2400
5.09k
               LIBCERROR_IO_ERROR_READ_FAILED,
2401
5.09k
               "%s: unable to read normal substitution.",
2402
5.09k
               function );
2403
2404
5.09k
              goto on_error;
2405
5.09k
            }
2406
464k
            break;
2407
2408
619k
          case LIBFWEVT_XML_TOKEN_OPTIONAL_SUBSTITUTION:
2409
619k
            result = libfwevt_xml_document_read_optional_substitution(
2410
619k
                internal_xml_document,
2411
619k
                xml_sub_token,
2412
619k
                binary_data,
2413
619k
                binary_data_size,
2414
619k
                binary_data_offset + xml_document_data_offset,
2415
619k
                ascii_codepage,
2416
619k
                flags,
2417
619k
                template_values_array,
2418
619k
                &template_value_offset,
2419
619k
                element_xml_tag,
2420
619k
                      element_recursion_depth,
2421
619k
                template_instance_recursion_depth,
2422
619k
                error );
2423
2424
619k
            if( result == -1 )
2425
6.97k
            {
2426
6.97k
              libcerror_error_set(
2427
6.97k
               error,
2428
6.97k
               LIBCERROR_ERROR_DOMAIN_IO,
2429
6.97k
               LIBCERROR_IO_ERROR_READ_FAILED,
2430
6.97k
               "%s: unable to read optional substitution.",
2431
6.97k
               function );
2432
2433
6.97k
              goto on_error;
2434
6.97k
            }
2435
612k
            break;
2436
2437
612k
          default:
2438
122
            libcerror_error_set(
2439
122
             error,
2440
122
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2441
122
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2442
122
             "%s: invalid binary XML sub token - unsupported type: 0x%02" PRIx8 ".",
2443
122
             function,
2444
122
             xml_sub_token->type );
2445
2446
122
            goto on_error;
2447
3.71M
        }
2448
3.69M
        xml_document_data_offset += xml_sub_token->size;
2449
2450
3.69M
        if( element_size < xml_sub_token->size )
2451
60
        {
2452
60
          libcerror_error_set(
2453
60
           error,
2454
60
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2455
60
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2456
60
           "%s: invalid element size value too small.",
2457
60
           function );
2458
2459
60
          goto on_error;
2460
60
        }
2461
3.69M
        element_size -= (uint32_t) xml_sub_token->size;
2462
2463
3.69M
        if( ( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG )
2464
3.69M
         || ( xml_sub_token->type == LIBFWEVT_XML_TOKEN_END_ELEMENT_TAG ) )
2465
789k
        {
2466
789k
          break;
2467
789k
        }
2468
3.69M
      }
2469
1.29M
    }
2470
365k
    else if( xml_sub_token->type == LIBFWEVT_XML_TOKEN_CLOSE_EMPTY_ELEMENT_TAG )
2471
365k
    {
2472
365k
      result = 1;
2473
365k
    }
2474
1.63M
    if( element_size > 0 )
2475
200
    {
2476
200
      libcerror_error_set(
2477
200
       error,
2478
200
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2479
200
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2480
200
       "%s: invalid element size value out of bounds.",
2481
200
       function );
2482
2483
200
      goto on_error;
2484
200
    }
2485
1.63M
    if( result != 0 )
2486
1.57M
    {
2487
1.57M
      if( xml_tag != NULL )
2488
1.56M
      {
2489
1.56M
        if( libfwevt_xml_tag_append_element(
2490
1.56M
             xml_tag,
2491
1.56M
             element_xml_tag,
2492
1.56M
             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.56M
        element_xml_tag = NULL;
2504
1.56M
      }
2505
526
      else if( internal_xml_document->root_xml_tag == NULL )
2506
486
      {
2507
486
        internal_xml_document->root_xml_tag = element_xml_tag;
2508
2509
486
        element_xml_tag = NULL;
2510
486
      }
2511
1.57M
    }
2512
1.63M
    template_value_array_recursion_depth++;
2513
1.63M
  }
2514
1.63M
  while( template_value_offset > 0 );
2515
2516
1.15M
  xml_token->size = xml_document_data_offset;
2517
2518
1.15M
  if( element_xml_tag != NULL )
2519
68.2k
  {
2520
68.2k
    if( libfwevt_internal_xml_tag_free(
2521
68.2k
         (libfwevt_internal_xml_tag_t **) &element_xml_tag,
2522
68.2k
         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.2k
  }
2534
1.15M
  if( libfwevt_xml_token_free(
2535
1.15M
       &xml_sub_token,
2536
1.15M
       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.15M
  return( 1 );
2548
2549
28.3k
on_error:
2550
28.3k
  if( ( element_xml_tag != NULL )
2551
28.1k
   && ( element_xml_tag != internal_xml_document->root_xml_tag ) )
2552
28.1k
  {
2553
28.1k
    libfwevt_internal_xml_tag_free(
2554
28.1k
     (libfwevt_internal_xml_tag_t **) &element_xml_tag,
2555
28.1k
     NULL );
2556
28.1k
  }
2557
28.3k
  if( xml_sub_token != NULL )
2558
28.2k
  {
2559
28.2k
    libfwevt_xml_token_free(
2560
28.2k
     &xml_sub_token,
2561
28.2k
     NULL );
2562
28.2k
  }
2563
28.3k
  return( -1 );
2564
1.15M
}
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
40.7k
{
2580
40.7k
  libfwevt_xml_tag_t *entity_xml_tag = NULL;
2581
40.7k
  uint8_t *entity_name               = NULL;
2582
40.7k
  uint8_t *entity_value_utf16_stream = NULL;
2583
40.7k
  const uint8_t *xml_document_data   = NULL;
2584
40.7k
  static char *function              = "libfwevt_xml_document_read_entity_reference";
2585
40.7k
  size_t additional_value_size       = 0;
2586
40.7k
  size_t trailing_data_size          = 0;
2587
40.7k
  size_t utf8_string_size            = 0;
2588
40.7k
  size_t xml_document_data_offset    = 0;
2589
40.7k
  size_t xml_document_data_size      = 0;
2590
40.7k
  uint32_t entity_name_offset        = 0;
2591
40.7k
  uint32_t entity_name_size          = 0;
2592
40.7k
  uint8_t entity_name_match          = 0;
2593
40.7k
  int data_segment_index             = 0;
2594
2595
40.7k
  LIBFWEVT_UNREFERENCED_PARAMETER( ascii_codepage )
2596
2597
40.7k
  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
40.7k
  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
40.7k
  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
40.7k
  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
40.7k
  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
40.7k
  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
40.7k
  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
40.7k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
2676
40.7k
  {
2677
40.7k
    additional_value_size = 4;
2678
40.7k
  }
2679
40.7k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
2680
40.7k
  xml_document_data_size = binary_data_size - binary_data_offset;
2681
2682
40.7k
  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
40.6k
  xml_token->size          = 1;
2720
40.6k
  xml_document_data_offset = 1;
2721
2722
40.6k
  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
40.6k
  else
2727
40.6k
  {
2728
40.6k
    if( ( xml_document_data_size < 4 )
2729
40.6k
     || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
2730
8
    {
2731
8
      libcerror_error_set(
2732
8
       error,
2733
8
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2734
8
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2735
8
       "%s: invalid binary XML document data size value too small.",
2736
8
       function );
2737
2738
8
      goto on_error;
2739
8
    }
2740
40.6k
    byte_stream_copy_to_uint32_little_endian(
2741
40.6k
     &( xml_document_data[ xml_document_data_offset ] ),
2742
40.6k
     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
40.6k
    xml_token->size          += 4;
2754
40.6k
    xml_document_data_offset += 4;
2755
40.6k
  }
2756
#if defined( HAVE_DEBUG_OUTPUT )
2757
  if( libcnotify_verbose != 0 )
2758
  {
2759
    libcnotify_printf(
2760
     "\n" );
2761
  }
2762
#endif
2763
40.6k
  if( entity_name_offset > ( binary_data_offset + xml_document_data_offset ) )
2764
128
  {
2765
128
    libcerror_error_set(
2766
128
     error,
2767
128
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2768
128
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2769
128
     "%s: invalid entity name offset value out of bounds.",
2770
128
     function );
2771
2772
128
    goto on_error;
2773
128
  }
2774
40.5k
  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
40.5k
  if( libfwevt_xml_tag_initialize(
2799
40.5k
       &entity_xml_tag,
2800
40.5k
       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
40.5k
  if( libfwevt_xml_document_read_name(
2812
40.5k
       internal_xml_document,
2813
40.5k
       binary_data,
2814
40.5k
       binary_data_size,
2815
40.5k
       entity_name_offset,
2816
40.5k
       flags,
2817
40.5k
       &entity_name_size,
2818
40.5k
       entity_xml_tag,
2819
40.5k
       error ) != 1 )
2820
19
  {
2821
19
    libcerror_error_set(
2822
19
     error,
2823
19
     LIBCERROR_ERROR_DOMAIN_IO,
2824
19
     LIBCERROR_IO_ERROR_READ_FAILED,
2825
19
     "%s: unable to read entity name.",
2826
19
     function );
2827
2828
19
    goto on_error;
2829
19
  }
2830
40.5k
  if( ( binary_data_offset + xml_document_data_offset ) == entity_name_offset )
2831
146
  {
2832
146
    xml_token->size += entity_name_size;
2833
146
  }
2834
40.5k
  if( libfwevt_xml_tag_get_utf8_name_size(
2835
40.5k
       entity_xml_tag,
2836
40.5k
       &utf8_string_size,
2837
40.5k
       error ) != 1 )
2838
93
  {
2839
93
    libcerror_error_set(
2840
93
     error,
2841
93
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2842
93
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2843
93
     "%s: unable to retrieve UTF-8 string size of entity name.",
2844
93
     function );
2845
2846
93
    goto on_error;
2847
93
  }
2848
40.4k
  if( ( utf8_string_size == 0 )
2849
40.4k
   || ( 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
40.4k
  entity_name = (uint8_t *) memory_allocate(
2861
40.4k
                             sizeof( uint8_t ) * utf8_string_size );
2862
2863
40.4k
  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
40.4k
  if( libfwevt_xml_tag_get_utf8_name(
2875
40.4k
       entity_xml_tag,
2876
40.4k
       entity_name,
2877
40.4k
       utf8_string_size,
2878
40.4k
       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
40.4k
  if( libfwevt_xml_tag_set_value_type(
2890
40.4k
       xml_tag,
2891
40.4k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
2892
40.4k
       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
40.4k
  entity_value_utf16_stream = (uint8_t *) memory_allocate(
2906
40.4k
                                           sizeof( uint8_t ) * 4 );
2907
2908
40.4k
  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
40.4k
  if( utf8_string_size == 3 )
2920
39.2k
  {
2921
39.2k
    if( ( entity_name[ 0 ] == (uint8_t) 'g' )
2922
1.36k
     && ( entity_name[ 1 ] == (uint8_t) 't' ) )
2923
1.35k
    {
2924
1.35k
      entity_value_utf16_stream[ 0 ] = (uint8_t) '>';
2925
1.35k
      entity_value_utf16_stream[ 1 ] = 0;
2926
2927
1.35k
      entity_name_match = 1;
2928
1.35k
    }
2929
37.8k
    else if( ( entity_name[ 0 ] == (uint8_t) 'l' )
2930
37.8k
          && ( entity_name[ 1 ] == (uint8_t) 't' ) )
2931
37.7k
    {
2932
37.7k
      entity_value_utf16_stream[ 0 ] = (uint8_t) '<';
2933
37.7k
      entity_value_utf16_stream[ 1 ] = 0;
2934
2935
37.7k
      entity_name_match = 1;
2936
37.7k
    }
2937
39.2k
  }
2938
1.22k
  else if( utf8_string_size == 4 )
2939
286
  {
2940
286
    if( ( entity_name[ 0 ] == (uint8_t) 'a' )
2941
244
     && ( entity_name[ 1 ] == (uint8_t) 'm' )
2942
230
     && ( entity_name[ 2 ] == (uint8_t) 'p' ) )
2943
221
    {
2944
221
      entity_value_utf16_stream[ 0 ] = (uint8_t) '&';
2945
221
      entity_value_utf16_stream[ 1 ] = 0;
2946
2947
221
      entity_name_match = 1;
2948
221
    }
2949
286
  }
2950
942
  else if( utf8_string_size == 5 )
2951
646
  {
2952
646
    if( ( entity_name[ 0 ] == (uint8_t) 'a' )
2953
312
     && ( entity_name[ 1 ] == (uint8_t) 'p' )
2954
294
     && ( entity_name[ 2 ] == (uint8_t) 'o' )
2955
292
     && ( entity_name[ 3 ] == (uint8_t) 's' ) )
2956
281
    {
2957
281
      entity_value_utf16_stream[ 0 ] = (uint8_t) '\'';
2958
281
      entity_value_utf16_stream[ 1 ] = 0;
2959
2960
281
      entity_name_match = 1;
2961
281
    }
2962
365
    else if( ( entity_name[ 0 ] == (uint8_t) 'q' )
2963
235
          && ( entity_name[ 1 ] == (uint8_t) 'u' )
2964
223
          && ( entity_name[ 2 ] == (uint8_t) 'o' )
2965
210
          && ( entity_name[ 3 ] == (uint8_t) 't' ) )
2966
202
    {
2967
202
      entity_value_utf16_stream[ 0 ] = (uint8_t) '"';
2968
202
      entity_value_utf16_stream[ 1 ] = 0;
2969
2970
202
      entity_name_match = 1;
2971
202
    }
2972
646
  }
2973
40.4k
  if( entity_name_match == 0 )
2974
586
  {
2975
586
    libcerror_error_set(
2976
586
     error,
2977
586
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2978
586
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2979
586
     "%s: unsupported entity name: %s\n",
2980
586
     function,
2981
586
     entity_name );
2982
2983
586
    goto on_error;
2984
586
  }
2985
39.8k
  entity_value_utf16_stream[ 2 ] = 0;
2986
39.8k
  entity_value_utf16_stream[ 3 ] = 0;
2987
2988
39.8k
  memory_free(
2989
39.8k
   entity_name );
2990
2991
39.8k
  entity_name = NULL;
2992
2993
39.8k
  if( libfwevt_xml_tag_append_value_data(
2994
39.8k
       xml_tag,
2995
39.8k
       entity_value_utf16_stream,
2996
39.8k
       4,
2997
39.8k
       &data_segment_index,
2998
39.8k
       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
39.8k
  memory_free(
3010
39.8k
   entity_value_utf16_stream );
3011
3012
39.8k
  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
39.8k
  if( libfwevt_internal_xml_tag_free(
3038
39.8k
       (libfwevt_internal_xml_tag_t **) &entity_xml_tag,
3039
39.8k
       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
39.8k
  return( 1 );
3051
3052
892
on_error:
3053
892
  if( entity_value_utf16_stream != NULL )
3054
586
  {
3055
586
    memory_free(
3056
586
     entity_value_utf16_stream );
3057
586
  }
3058
892
  if( entity_name != NULL )
3059
589
  {
3060
589
    memory_free(
3061
589
     entity_name );
3062
589
  }
3063
892
  if( entity_xml_tag != NULL )
3064
701
  {
3065
701
    libfwevt_internal_xml_tag_free(
3066
701
     (libfwevt_internal_xml_tag_t **) &entity_xml_tag,
3067
701
     NULL );
3068
701
  }
3069
892
  return( -1 );
3070
39.8k
}
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
46.7k
{
3089
46.7k
  libfwevt_xml_token_t *xml_sub_token = NULL;
3090
46.7k
  static char *function               = "libfwevt_xml_document_read_fragment";
3091
3092
46.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
46.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
46.7k
  if( libfwevt_xml_document_read_fragment_header(
3115
46.7k
       internal_xml_document,
3116
46.7k
       xml_token,
3117
46.7k
       binary_data,
3118
46.7k
       binary_data_size,
3119
46.7k
       binary_data_offset,
3120
46.7k
       error ) != 1 )
3121
22
  {
3122
22
    libcerror_error_set(
3123
22
     error,
3124
22
     LIBCERROR_ERROR_DOMAIN_IO,
3125
22
     LIBCERROR_IO_ERROR_READ_FAILED,
3126
22
     "%s: unable to read fragment header.",
3127
22
     function );
3128
3129
22
    goto on_error;
3130
22
  }
3131
46.7k
  binary_data_offset += xml_token->size;
3132
3133
46.7k
  if( libfwevt_xml_token_initialize(
3134
46.7k
       &xml_sub_token,
3135
46.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
46.7k
  if( libfwevt_xml_token_read_data(
3147
46.7k
       xml_sub_token,
3148
46.7k
       binary_data,
3149
46.7k
       binary_data_size,
3150
46.7k
       binary_data_offset,
3151
46.7k
       error ) != 1 )
3152
10
  {
3153
10
    libcerror_error_set(
3154
10
     error,
3155
10
     LIBCERROR_ERROR_DOMAIN_IO,
3156
10
     LIBCERROR_IO_ERROR_READ_FAILED,
3157
10
     "%s: unable to read binary XML sub token.",
3158
10
     function );
3159
3160
10
    goto on_error;
3161
10
  }
3162
46.6k
  switch( xml_sub_token->type & 0xbf )
3163
46.6k
  {
3164
2.72k
    case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
3165
2.72k
      if( libfwevt_xml_document_read_element(
3166
2.72k
           internal_xml_document,
3167
2.72k
           xml_sub_token,
3168
2.72k
           binary_data,
3169
2.72k
           binary_data_size,
3170
2.72k
           binary_data_offset,
3171
2.72k
           ascii_codepage,
3172
2.72k
           flags,
3173
2.72k
           template_values_array,
3174
2.72k
           xml_tag,
3175
2.72k
           element_recursion_depth + 1,
3176
2.72k
           template_instance_recursion_depth,
3177
2.72k
           error ) != 1 )
3178
1.93k
      {
3179
1.93k
        libcerror_error_set(
3180
1.93k
         error,
3181
1.93k
         LIBCERROR_ERROR_DOMAIN_IO,
3182
1.93k
         LIBCERROR_IO_ERROR_READ_FAILED,
3183
1.93k
         "%s: unable to read element.",
3184
1.93k
         function );
3185
3186
1.93k
        goto on_error;
3187
1.93k
      }
3188
795
      break;
3189
3190
43.9k
    case LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE:
3191
43.9k
      if( libfwevt_xml_document_read_template_instance(
3192
43.9k
           internal_xml_document,
3193
43.9k
           xml_sub_token,
3194
43.9k
           binary_data,
3195
43.9k
           binary_data_size,
3196
43.9k
           binary_data_offset,
3197
43.9k
           ascii_codepage,
3198
43.9k
           flags,
3199
43.9k
           xml_tag,
3200
43.9k
           element_recursion_depth,
3201
43.9k
           template_instance_recursion_depth + 1,
3202
43.9k
           error ) != 1 )
3203
6.15k
      {
3204
6.15k
        libcerror_error_set(
3205
6.15k
         error,
3206
6.15k
         LIBCERROR_ERROR_DOMAIN_IO,
3207
6.15k
         LIBCERROR_IO_ERROR_READ_FAILED,
3208
6.15k
         "%s: unable to read document template instance.",
3209
6.15k
         function );
3210
3211
6.15k
        goto on_error;
3212
6.15k
      }
3213
37.7k
      break;
3214
3215
37.7k
    default:
3216
16
      libcerror_error_set(
3217
16
       error,
3218
16
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3219
16
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3220
16
       "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3221
16
       function,
3222
16
       xml_sub_token->type );
3223
3224
16
      goto on_error;
3225
46.6k
  }
3226
38.5k
  xml_token->size += xml_sub_token->size;
3227
3228
38.5k
  if( libfwevt_xml_token_free(
3229
38.5k
       &xml_sub_token,
3230
38.5k
       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
38.5k
  return( 1 );
3242
3243
8.13k
on_error:
3244
8.13k
  if( xml_sub_token != NULL )
3245
8.11k
  {
3246
8.11k
    libfwevt_xml_token_free(
3247
8.11k
     &xml_sub_token,
3248
8.11k
     NULL );
3249
8.11k
  }
3250
8.13k
  return( -1 );
3251
38.5k
}
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
135k
{
3264
135k
  static char *function            = "libfwevt_xml_document_read_fragment_header";
3265
135k
  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
135k
  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
135k
  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
135k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_FRAGMENT_HEADER )
3294
89
  {
3295
89
    libcerror_error_set(
3296
89
     error,
3297
89
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3298
89
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3299
89
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
3300
89
     function,
3301
89
     xml_token->type );
3302
3303
89
    return( -1 );
3304
89
  }
3305
135k
  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
135k
  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
135k
  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
135k
  xml_document_data_size = binary_data_size - binary_data_offset;
3343
3344
135k
  if( xml_document_data_size < 4 )
3345
24
  {
3346
24
    libcerror_error_set(
3347
24
     error,
3348
24
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3349
24
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3350
24
     "%s: invalid binary XML document data size value too small.",
3351
24
     function );
3352
3353
24
    return( -1 );
3354
24
  }
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
135k
  xml_token->size = 4;
3402
3403
135k
  return( 1 );
3404
135k
}
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.50M
{
3419
2.50M
  const uint8_t *xml_document_data = NULL;
3420
2.50M
  static char *function            = "libfwevt_xml_document_read_name";
3421
2.50M
  size_t additional_value_size     = 0;
3422
2.50M
  size_t xml_document_data_offset  = 0;
3423
2.50M
  size_t xml_document_data_size    = 0;
3424
2.50M
  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.50M
  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.50M
  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.50M
  if( ( binary_data_size < 4 )
3454
2.50M
   || ( 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.50M
  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.50M
  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.50M
  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.50M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3499
2.50M
  xml_document_data_size = binary_data_size - binary_data_offset;
3500
3501
2.50M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
3502
2.50M
  {
3503
2.50M
    additional_value_size += 4;
3504
2.50M
  }
3505
2.50M
  if( ( additional_value_size + 4 ) > xml_document_data_size )
3506
10
  {
3507
10
    libcerror_error_set(
3508
10
     error,
3509
10
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3510
10
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3511
10
     "%s: invalid binary XML document data size value too small.",
3512
10
     function );
3513
3514
10
    return( -1 );
3515
10
  }
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.50M
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
3534
2.50M
  {
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.50M
    xml_document_data_offset += 4;
3549
2.50M
  }
3550
2.50M
  byte_stream_copy_to_uint16_little_endian(
3551
2.50M
   &( xml_document_data[ xml_document_data_offset + 2 ] ),
3552
2.50M
   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.50M
  xml_document_data_offset += 4;
3573
3574
2.50M
  if( ( name_size == 0 )
3575
2.50M
   || ( (size_t) name_size > ( ( MEMORY_MAXIMUM_ALLOCATION_SIZE - 1 ) / 2 ) ) )
3576
32
  {
3577
32
    libcerror_error_set(
3578
32
     error,
3579
32
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3580
32
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3581
32
     "%s: invalid name size value out of bounds.",
3582
32
     function );
3583
3584
32
    return( -1 );
3585
32
  }
3586
2.50M
  name_size = ( name_size + 1 ) * 2;
3587
3588
2.50M
  if( (size_t) name_size > ( xml_document_data_size - xml_document_data_offset ) )
3589
45
  {
3590
45
    libcerror_error_set(
3591
45
     error,
3592
45
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3593
45
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3594
45
     "%s: invalid binary XML document data size value too small.",
3595
45
     function );
3596
3597
45
    return( -1 );
3598
45
  }
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.50M
  if( libfwevt_xml_tag_set_name_data(
3612
2.50M
       xml_tag,
3613
2.50M
       &( xml_document_data[ xml_document_data_offset ] ),
3614
2.50M
       name_size,
3615
2.50M
       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.50M
  *name_data_size = (uint32_t) ( xml_document_data_offset + name_size );
3646
3647
2.50M
  return( 1 );
3648
2.50M
}
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
540k
{
3668
540k
  const uint8_t *xml_document_data = NULL;
3669
540k
  static char *function            = "libfwevt_xml_document_read_normal_substitution";
3670
540k
  size_t xml_document_data_size    = 0;
3671
540k
  uint16_t template_value_index    = 0;
3672
540k
  uint8_t template_value_type      = 0;
3673
540k
  int result                       = 0;
3674
3675
540k
  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
540k
  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
540k
  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
540k
  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
540k
  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
540k
  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
540k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3743
540k
  xml_document_data_size = binary_data_size - binary_data_offset;
3744
3745
540k
  if( xml_document_data_size < 4 )
3746
14
  {
3747
14
    libcerror_error_set(
3748
14
     error,
3749
14
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3750
14
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3751
14
     "%s: invalid binary XML document data size value too small.",
3752
14
     function );
3753
3754
14
    return( -1 );
3755
14
  }
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
540k
  byte_stream_copy_to_uint16_little_endian(
3774
540k
   &( xml_document_data[ 1 ] ),
3775
540k
   template_value_index );
3776
3777
540k
  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
540k
  xml_token->size = 4;
3807
3808
540k
  result = libfwevt_xml_document_substitute_template_value(
3809
540k
            internal_xml_document,
3810
540k
            binary_data,
3811
540k
            binary_data_size,
3812
540k
            ascii_codepage,
3813
540k
            flags,
3814
540k
            template_values_array,
3815
540k
            template_value_index,
3816
540k
            template_value_type,
3817
540k
            template_value_offset,
3818
540k
            xml_tag,
3819
540k
            element_recursion_depth,
3820
540k
            template_instance_recursion_depth,
3821
540k
            error );
3822
3823
540k
  if( result != 1 )
3824
7.12k
  {
3825
7.12k
    libcerror_error_set(
3826
7.12k
     error,
3827
7.12k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3828
7.12k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3829
7.12k
     "%s: unable to substitute template value.",
3830
7.12k
     function );
3831
3832
7.12k
    return( -1 );
3833
7.12k
  }
3834
533k
  return( 1 );
3835
540k
}
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.05M
{
3855
1.05M
  const uint8_t *xml_document_data = NULL;
3856
1.05M
  static char *function            = "libfwevt_xml_document_read_optional_substitution";
3857
1.05M
  size_t xml_document_data_size    = 0;
3858
1.05M
  uint16_t template_value_index    = 0;
3859
1.05M
  uint8_t template_value_type      = 0;
3860
1.05M
  int result                       = 0;
3861
3862
1.05M
  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.05M
  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.05M
  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.05M
  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.05M
  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.05M
  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.05M
  xml_document_data      = &( binary_data[ binary_data_offset ] );
3930
1.05M
  xml_document_data_size = binary_data_size - binary_data_offset;
3931
3932
1.05M
  if( xml_document_data_size < 4 )
3933
13
  {
3934
13
    libcerror_error_set(
3935
13
     error,
3936
13
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3937
13
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3938
13
     "%s: invalid binary XML document data size value too small.",
3939
13
     function );
3940
3941
13
    return( -1 );
3942
13
  }
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.05M
  byte_stream_copy_to_uint16_little_endian(
3961
1.05M
   &( xml_document_data[ 1 ] ),
3962
1.05M
   template_value_index );
3963
3964
1.05M
  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.05M
  xml_token->size = 4;
3994
3995
1.05M
  result = libfwevt_xml_document_substitute_template_value(
3996
1.05M
            internal_xml_document,
3997
1.05M
            binary_data,
3998
1.05M
            binary_data_size,
3999
1.05M
            ascii_codepage,
4000
1.05M
            flags,
4001
1.05M
            template_values_array,
4002
1.05M
            template_value_index,
4003
1.05M
            template_value_type,
4004
1.05M
            template_value_offset,
4005
1.05M
            xml_tag,
4006
1.05M
            element_recursion_depth,
4007
1.05M
            template_instance_recursion_depth,
4008
1.05M
            error );
4009
4010
1.05M
  if( result == -1 )
4011
8.11k
  {
4012
8.11k
    libcerror_error_set(
4013
8.11k
     error,
4014
8.11k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4015
8.11k
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4016
8.11k
     "%s: unable to substitute template value.",
4017
8.11k
     function );
4018
4019
8.11k
    return( -1 );
4020
8.11k
  }
4021
1.04M
  return( result );
4022
1.05M
}
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.68k
{
4037
2.68k
  const uint8_t *xml_document_data = NULL;
4038
2.68k
  static char *function            = "libfwevt_xml_document_read_pi_data";
4039
2.68k
  size_t value_data_size           = 0;
4040
2.68k
  size_t xml_document_data_size    = 0;
4041
4042
2.68k
  LIBFWEVT_UNREFERENCED_PARAMETER( ascii_codepage )
4043
4044
2.68k
  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.68k
  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.68k
  if( xml_token->type != LIBFWEVT_XML_TOKEN_PI_DATA )
4067
51
  {
4068
51
    libcerror_error_set(
4069
51
     error,
4070
51
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4071
51
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4072
51
     "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
4073
51
     function,
4074
51
     xml_token->type );
4075
4076
51
    return( -1 );
4077
51
  }
4078
2.62k
  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.62k
  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.62k
  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.62k
  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.62k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4123
2.62k
  xml_document_data_size = binary_data_size - binary_data_offset;
4124
4125
2.62k
  if( xml_document_data_size < 3 )
4126
14
  {
4127
14
    libcerror_error_set(
4128
14
     error,
4129
14
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4130
14
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4131
14
     "%s: invalid binary XML document data size value too small.",
4132
14
     function );
4133
4134
14
    return( -1 );
4135
14
  }
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.61k
  byte_stream_copy_to_uint16_little_endian(
4154
2.61k
   &( xml_document_data[ 1 ] ),
4155
2.61k
   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.61k
  xml_token->size     = 3;
4172
2.61k
  binary_data_offset += 3;
4173
4174
2.61k
  value_data_size *= 2;
4175
4176
2.61k
  if( ( value_data_size > binary_data_size )
4177
2.56k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
4178
90
  {
4179
90
    libcerror_error_set(
4180
90
     error,
4181
90
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4182
90
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4183
90
     "%s: invalid value data size value out of bounds.",
4184
90
     function );
4185
4186
90
    return( -1 );
4187
90
  }
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.52k
  if( libfwevt_xml_tag_set_value_type(
4206
2.52k
       xml_tag,
4207
2.52k
       LIBFWEVT_VALUE_TYPE_STRING_UTF16,
4208
2.52k
       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.52k
  if( libfwevt_xml_tag_set_value_data(
4220
2.52k
       xml_tag,
4221
2.52k
       &( binary_data[ binary_data_offset ] ),
4222
2.52k
       value_data_size,
4223
2.52k
       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.52k
  xml_token->size += value_data_size;
4257
4258
2.52k
  return( 1 );
4259
2.52k
}
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.86k
{
4275
2.86k
  libfwevt_xml_tag_t *pi_xml_tag      = NULL;
4276
2.86k
  libfwevt_xml_token_t *xml_sub_token = NULL;
4277
2.86k
  const uint8_t *xml_document_data    = NULL;
4278
2.86k
  static char *function               = "libfwevt_xml_document_read_pi_target";
4279
2.86k
  size_t additional_value_size        = 0;
4280
2.86k
  size_t trailing_data_size           = 0;
4281
2.86k
  size_t xml_document_data_offset     = 0;
4282
2.86k
  size_t xml_document_data_size       = 0;
4283
2.86k
  uint32_t pi_name_offset             = 0;
4284
2.86k
  uint32_t pi_name_size               = 0;
4285
4286
2.86k
  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.86k
  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.86k
  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.86k
  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.86k
  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.86k
  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.86k
  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.86k
  if( ( flags & LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DATA_OFFSETS ) != 0 )
4365
2.86k
  {
4366
2.86k
    additional_value_size = 4;
4367
2.86k
  }
4368
2.86k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4369
2.86k
  xml_document_data_size = binary_data_size - binary_data_offset;
4370
4371
2.86k
  if( xml_document_data_size < ( 1 + additional_value_size ) )
4372
17
  {
4373
17
    libcerror_error_set(
4374
17
     error,
4375
17
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4376
17
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4377
17
     "%s: invalid binary XML document data size value too small.",
4378
17
     function );
4379
4380
17
    return( -1 );
4381
17
  }
4382
2.84k
  if( libfwevt_xml_tag_initialize(
4383
2.84k
       &pi_xml_tag,
4384
2.84k
       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.84k
  if( libfwevt_xml_tag_set_type(
4396
2.84k
       pi_xml_tag,
4397
2.84k
       LIBFWEVT_XML_TAG_TYPE_PI,
4398
2.84k
       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.84k
  xml_token->size          = 1;
4436
2.84k
  xml_document_data_offset = 1;
4437
4438
2.84k
  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.84k
  else
4445
2.84k
  {
4446
2.84k
    if( ( xml_document_data_size < 4 )
4447
2.84k
     || ( xml_document_data_offset >= ( xml_document_data_size - 4 ) ) )
4448
7
    {
4449
7
      libcerror_error_set(
4450
7
       error,
4451
7
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4452
7
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4453
7
       "%s: invalid binary XML document data size value too small.",
4454
7
       function );
4455
4456
7
      goto on_error;
4457
7
    }
4458
2.84k
    byte_stream_copy_to_uint32_little_endian(
4459
2.84k
     &( xml_document_data[ xml_document_data_offset ] ),
4460
2.84k
     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.84k
    xml_token->size           = 4;
4472
/* TODO
4473
    xml_document_data_offset += 4;
4474
*/
4475
2.84k
  }
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.84k
  xml_token->size          = 5;
4488
2.84k
  xml_document_data_offset = 5;
4489
4490
2.84k
  if( pi_name_offset > ( binary_data_offset + xml_document_data_offset ) )
4491
143
  {
4492
143
    libcerror_error_set(
4493
143
     error,
4494
143
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4495
143
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4496
143
     "%s: invalid PI name offset value out of bounds.",
4497
143
     function );
4498
4499
143
    goto on_error;
4500
143
  }
4501
2.69k
  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.69k
  if( libfwevt_xml_document_read_name(
4526
2.69k
       internal_xml_document,
4527
2.69k
       binary_data,
4528
2.69k
       binary_data_size,
4529
2.69k
       pi_name_offset,
4530
2.69k
       flags,
4531
2.69k
       &pi_name_size,
4532
2.69k
       pi_xml_tag,
4533
2.69k
       error ) != 1 )
4534
6
  {
4535
6
    libcerror_error_set(
4536
6
     error,
4537
6
     LIBCERROR_ERROR_DOMAIN_IO,
4538
6
     LIBCERROR_IO_ERROR_READ_FAILED,
4539
6
     "%s: unable to read PI name.",
4540
6
     function );
4541
4542
6
    goto on_error;
4543
6
  }
4544
2.69k
  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.69k
  if( libfwevt_xml_token_initialize(
4550
2.69k
       &xml_sub_token,
4551
2.69k
       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.69k
  if( libfwevt_xml_token_read_data(
4563
2.69k
       xml_sub_token,
4564
2.69k
       binary_data,
4565
2.69k
       binary_data_size,
4566
2.69k
       binary_data_offset + xml_document_data_offset,
4567
2.69k
       error ) != 1 )
4568
11
  {
4569
11
    libcerror_error_set(
4570
11
     error,
4571
11
     LIBCERROR_ERROR_DOMAIN_IO,
4572
11
     LIBCERROR_IO_ERROR_READ_FAILED,
4573
11
     "%s: unable to read binary XML sub token.",
4574
11
     function );
4575
4576
11
    goto on_error;
4577
11
  }
4578
2.68k
  if( libfwevt_xml_document_read_pi_data(
4579
2.68k
       internal_xml_document,
4580
2.68k
       xml_sub_token,
4581
2.68k
       binary_data,
4582
2.68k
       binary_data_size,
4583
2.68k
       binary_data_offset + xml_document_data_offset,
4584
2.68k
       pi_xml_tag,
4585
2.68k
       ascii_codepage,
4586
2.68k
       error ) != 1 )
4587
155
  {
4588
155
    libcerror_error_set(
4589
155
     error,
4590
155
     LIBCERROR_ERROR_DOMAIN_IO,
4591
155
     LIBCERROR_IO_ERROR_READ_FAILED,
4592
155
     "%s: unable to read PI target.",
4593
155
     function );
4594
4595
155
    goto on_error;
4596
155
  }
4597
2.52k
  xml_token->size += xml_sub_token->size;
4598
4599
2.52k
  if( libfwevt_xml_token_free(
4600
2.52k
       &xml_sub_token,
4601
2.52k
       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.52k
  if( libfwevt_xml_tag_append_element(
4613
2.52k
       xml_tag,
4614
2.52k
       pi_xml_tag,
4615
2.52k
       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.52k
  pi_xml_tag = NULL;
4627
4628
2.52k
  return( 1 );
4629
4630
322
on_error:
4631
322
  if( xml_sub_token != NULL )
4632
166
  {
4633
166
    libfwevt_xml_token_free(
4634
166
     &xml_sub_token,
4635
166
     NULL );
4636
166
  }
4637
322
  if( pi_xml_tag != NULL )
4638
322
  {
4639
322
    libfwevt_internal_xml_tag_free(
4640
322
     (libfwevt_internal_xml_tag_t **) &pi_xml_tag,
4641
322
     NULL );
4642
322
  }
4643
322
  return( -1 );
4644
2.52k
}
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
89.5k
{
4662
89.5k
  libcdata_array_t *template_values_array  = NULL;
4663
89.5k
  libfwevt_xml_token_t *xml_sub_token      = NULL;
4664
89.5k
  const uint8_t *xml_document_data         = NULL;
4665
89.5k
  static char *function                    = "libfwevt_xml_document_read_template_instance";
4666
89.5k
  size_t template_data_offset              = 0;
4667
89.5k
  size_t template_data_size                = 0;
4668
89.5k
  size_t template_values_data_offset       = 0;
4669
89.5k
  size_t template_values_data_size         = 0;
4670
89.5k
  size_t trailing_data_size                = 0;
4671
89.5k
  size_t xml_document_data_size            = 0;
4672
89.5k
  uint32_t template_definition_data_offset = 0;
4673
89.5k
  uint32_t template_definition_data_size   = 0;
4674
4675
#if defined( HAVE_DEBUG_OUTPUT )
4676
  uint32_t value_32bit                     = 0;
4677
#endif
4678
4679
89.5k
  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
89.5k
  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
89.5k
  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
89.5k
  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
89.5k
  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
89.5k
  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
89.5k
  if( ( template_instance_recursion_depth < 0 )
4747
89.5k
   || ( 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
89.3k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
4759
89.3k
  xml_document_data_size = binary_data_size - binary_data_offset;
4760
4761
89.3k
  if( ( binary_data_size < 10 )
4762
89.3k
   || ( binary_data_offset >= ( binary_data_size - 10 ) ) )
4763
36
  {
4764
36
    libcerror_error_set(
4765
36
     error,
4766
36
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4767
36
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4768
36
     "%s: invalid binary XML document data size value too small.",
4769
36
     function );
4770
4771
36
    goto on_error;
4772
36
  }
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
89.2k
  byte_stream_copy_to_uint32_little_endian(
4791
89.2k
   &( xml_document_data[ 6 ] ),
4792
89.2k
   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
89.2k
  xml_token->size     = 10;
4826
89.2k
  binary_data_offset += 10;
4827
4828
89.2k
  if( template_definition_data_offset >= binary_data_size )
4829
117
  {
4830
117
    libcerror_error_set(
4831
117
     error,
4832
117
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4833
117
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4834
117
     "%s: invalid template definition data offset value out of bounds.",
4835
117
     function );
4836
4837
117
    goto on_error;
4838
117
  }
4839
89.1k
  if( template_definition_data_offset > binary_data_offset )
4840
1.08k
  {
4841
1.08k
    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.08k
    xml_token->size    += trailing_data_size;
4861
1.08k
    binary_data_offset += trailing_data_size;
4862
1.08k
  }
4863
89.1k
  template_data_offset = template_definition_data_offset;
4864
4865
89.1k
  if( ( binary_data_size < 24 )
4866
89.1k
   || ( template_data_offset >= ( binary_data_size - 24 ) ) )
4867
67
  {
4868
67
    libcerror_error_set(
4869
67
     error,
4870
67
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4871
67
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4872
67
     "%s: invalid binary XML document data size value too small.",
4873
67
     function );
4874
4875
67
    goto on_error;
4876
67
  }
4877
89.0k
  byte_stream_copy_to_uint32_little_endian(
4878
89.0k
   &( binary_data[ template_data_offset + 20 ] ),
4879
89.0k
   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
89.0k
  if( template_definition_data_size > binary_data_size )
4921
126
  {
4922
126
    libcerror_error_set(
4923
126
     error,
4924
126
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4925
126
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4926
126
     "%s: invalid template definition data size value out of bounds.",
4927
126
     function );
4928
4929
126
    goto on_error;
4930
126
  }
4931
88.9k
  if( template_data_offset == binary_data_offset )
4932
1.91k
  {
4933
1.91k
    template_values_data_offset = 24 + template_definition_data_size;
4934
1.91k
  }
4935
87.0k
  else
4936
87.0k
  {
4937
87.0k
    template_values_data_offset = 0;
4938
87.0k
  }
4939
88.9k
  template_data_offset += 24;
4940
4941
88.9k
  if( template_values_data_offset >= xml_document_data_size )
4942
34
  {
4943
34
    libcerror_error_set(
4944
34
     error,
4945
34
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4946
34
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4947
34
     "%s: invalid template values data offset value out of bounds.",
4948
34
     function );
4949
4950
34
    goto on_error;
4951
34
  }
4952
88.9k
  if( libfwevt_xml_document_read_template_instance_values(
4953
88.9k
       internal_xml_document,
4954
88.9k
       binary_data,
4955
88.9k
       binary_data_size,
4956
88.9k
       binary_data_offset + template_values_data_offset,
4957
88.9k
       &template_values_array,
4958
88.9k
       &template_values_data_size,
4959
88.9k
       error ) != 1 )
4960
380
  {
4961
380
    libcerror_error_set(
4962
380
     error,
4963
380
     LIBCERROR_ERROR_DOMAIN_IO,
4964
380
     LIBCERROR_IO_ERROR_READ_FAILED,
4965
380
     "%s: unable to read document template instance values.",
4966
380
     function );
4967
4968
380
    goto on_error;
4969
380
  }
4970
88.5k
  xml_token->size += template_values_data_size;
4971
4972
88.5k
  if( libfwevt_xml_token_initialize(
4973
88.5k
       &xml_sub_token,
4974
88.5k
       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
88.5k
  if( libfwevt_xml_token_read_data(
4986
88.5k
       xml_sub_token,
4987
88.5k
       binary_data,
4988
88.5k
       binary_data_size,
4989
88.5k
       template_data_offset,
4990
88.5k
       error ) != 1 )
4991
17
  {
4992
17
    libcerror_error_set(
4993
17
     error,
4994
17
     LIBCERROR_ERROR_DOMAIN_IO,
4995
17
     LIBCERROR_IO_ERROR_READ_FAILED,
4996
17
     "%s: unable to read binary XML sub token.",
4997
17
     function );
4998
4999
17
    goto on_error;
5000
17
  }
5001
88.5k
  if( libfwevt_xml_document_read_fragment_header(
5002
88.5k
       internal_xml_document,
5003
88.5k
       xml_sub_token,
5004
88.5k
       binary_data,
5005
88.5k
       binary_data_size,
5006
88.5k
       template_data_offset,
5007
88.5k
       error ) != 1 )
5008
91
  {
5009
91
    libcerror_error_set(
5010
91
     error,
5011
91
     LIBCERROR_ERROR_DOMAIN_IO,
5012
91
     LIBCERROR_IO_ERROR_READ_FAILED,
5013
91
     "%s: unable to read fragment header.",
5014
91
     function );
5015
5016
91
    goto on_error;
5017
91
  }
5018
88.4k
  template_data_offset += xml_sub_token->size;
5019
5020
88.4k
  if( libfwevt_xml_token_read_data(
5021
88.4k
       xml_sub_token,
5022
88.4k
       binary_data,
5023
88.4k
       binary_data_size,
5024
88.4k
       template_data_offset,
5025
88.4k
       error ) != 1 )
5026
4
  {
5027
4
    libcerror_error_set(
5028
4
     error,
5029
4
     LIBCERROR_ERROR_DOMAIN_IO,
5030
4
     LIBCERROR_IO_ERROR_READ_FAILED,
5031
4
     "%s: unable to read binary XML sub token.",
5032
4
     function );
5033
5034
4
    goto on_error;
5035
4
  }
5036
88.4k
  if( libfwevt_xml_document_read_element(
5037
88.4k
       internal_xml_document,
5038
88.4k
       xml_sub_token,
5039
88.4k
       binary_data,
5040
88.4k
       binary_data_size,
5041
88.4k
       template_data_offset,
5042
88.4k
       ascii_codepage,
5043
88.4k
       flags,
5044
88.4k
       template_values_array,
5045
88.4k
       xml_tag,
5046
88.4k
       element_recursion_depth + 1,
5047
88.4k
       template_instance_recursion_depth,
5048
88.4k
       error ) != 1 )
5049
5.44k
  {
5050
5.44k
    libcerror_error_set(
5051
5.44k
     error,
5052
5.44k
     LIBCERROR_ERROR_DOMAIN_IO,
5053
5.44k
     LIBCERROR_IO_ERROR_READ_FAILED,
5054
5.44k
     "%s: unable to read element.",
5055
5.44k
     function );
5056
5057
5.44k
    goto on_error;
5058
5.44k
  }
5059
82.9k
  template_data_offset += xml_sub_token->size;
5060
5061
82.9k
  if( libfwevt_xml_token_read_data(
5062
82.9k
       xml_sub_token,
5063
82.9k
       binary_data,
5064
82.9k
       binary_data_size,
5065
82.9k
       template_data_offset,
5066
82.9k
       error ) != 1 )
5067
9
  {
5068
9
    libcerror_error_set(
5069
9
     error,
5070
9
     LIBCERROR_ERROR_DOMAIN_IO,
5071
9
     LIBCERROR_IO_ERROR_READ_FAILED,
5072
9
     "%s: unable to read binary XML sub token.",
5073
9
     function );
5074
5075
9
    goto on_error;
5076
9
  }
5077
82.9k
  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.9k
  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.9k
  template_data_offset += 1;
5130
5131
82.9k
  if( libfwevt_xml_token_free(
5132
82.9k
       &xml_sub_token,
5133
82.9k
       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.9k
  if( template_definition_data_offset == binary_data_offset )
5145
548
  {
5146
548
    template_data_size = template_data_offset
5147
548
                       - template_definition_data_offset;
5148
5149
548
    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
548
    if( template_definition_data_size < ( template_data_size - 24 ) )
5156
7
    {
5157
7
      libcerror_error_set(
5158
7
       error,
5159
7
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5160
7
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5161
7
       "%s: invalid template definition data size value too small.",
5162
7
       function );
5163
5164
7
      goto on_error;
5165
7
    }
5166
/* TODO
5167
    template_definition_data_size -= (uint32_t) ( template_data_size - 24 );
5168
*/
5169
548
  }
5170
/* TODO check if template_definition_data_size is 0 */
5171
5172
82.9k
  if( libcdata_array_free(
5173
82.9k
       &template_values_array,
5174
82.9k
       (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5175
82.9k
       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.9k
  return( 1 );
5187
5188
6.35k
on_error:
5189
6.35k
  if( template_values_array != NULL )
5190
5.59k
  {
5191
5.59k
    libcdata_array_free(
5192
5.59k
     &template_values_array,
5193
5.59k
     (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5194
5.59k
     NULL );
5195
5.59k
  }
5196
6.35k
  if( xml_sub_token != NULL )
5197
5.58k
  {
5198
5.58k
    libfwevt_xml_token_free(
5199
5.58k
     &xml_sub_token,
5200
5.58k
     NULL );
5201
5.58k
  }
5202
6.35k
  return( -1 );
5203
82.9k
}
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.9k
{
5217
88.9k
  libfwevt_xml_template_value_t *template_value = NULL;
5218
88.9k
  static char *function                         = "libfwevt_xml_document_read_template_instance_values";
5219
88.9k
  size_t safe_template_values_size              = 0;
5220
88.9k
  size_t template_value_definitions_data_size   = 0;
5221
88.9k
  size_t template_values_data_size              = 0;
5222
88.9k
  uint32_t number_of_template_values            = 0;
5223
88.9k
  uint32_t template_value_index                 = 0;
5224
88.9k
  uint16_t template_value_data_size             = 0;
5225
88.9k
  uint8_t template_value_type                   = 0;
5226
5227
88.9k
  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.9k
  if( ( binary_data_size < 4 )
5239
88.9k
   || ( binary_data_offset >= ( binary_data_size - 4 ) ) )
5240
75
  {
5241
75
    libcerror_error_set(
5242
75
     error,
5243
75
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5244
75
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5245
75
     "%s: invalid binary data size value out of bounds.",
5246
75
     function );
5247
5248
75
    return( -1 );
5249
75
  }
5250
88.8k
  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
88.8k
  byte_stream_copy_to_uint32_little_endian(
5279
88.8k
   &( binary_data[ binary_data_offset ] ),
5280
88.8k
   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
88.8k
  safe_template_values_size = 4;
5295
88.8k
  binary_data_offset       += 4;
5296
5297
88.8k
  template_value_definitions_data_size = number_of_template_values * 4;
5298
5299
88.8k
  if( ( template_value_definitions_data_size > binary_data_size )
5300
88.7k
   || ( binary_data_offset >= ( binary_data_size - template_value_definitions_data_size ) ) )
5301
96
  {
5302
96
    libcerror_error_set(
5303
96
     error,
5304
96
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5305
96
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5306
96
     "%s: invalid template value definitions data size value out of bounds.",
5307
96
     function );
5308
5309
96
    goto on_error;
5310
96
  }
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
88.7k
  if( libcdata_array_initialize(
5329
88.7k
       template_values_array,
5330
88.7k
       number_of_template_values,
5331
88.7k
       error ) != 1 )
5332
43
  {
5333
43
    libcerror_error_set(
5334
43
     error,
5335
43
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5336
43
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5337
43
     "%s: unable to create template values array.",
5338
43
     function );
5339
5340
43
    goto on_error;
5341
43
  }
5342
88.7k
  for( template_value_index = 0;
5343
3.74M
       template_value_index < number_of_template_values;
5344
3.66M
       template_value_index++ )
5345
3.66M
  {
5346
3.66M
    byte_stream_copy_to_uint16_little_endian(
5347
3.66M
     &( binary_data[ binary_data_offset ] ),
5348
3.66M
     template_value_data_size );
5349
5350
3.66M
    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.66M
    safe_template_values_size += 4;
5383
3.66M
    binary_data_offset        += 4;
5384
5385
3.66M
    template_values_data_size += template_value_data_size;
5386
5387
3.66M
    if( libfwevt_xml_template_value_initialize(
5388
3.66M
         &template_value,
5389
3.66M
         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.66M
    if( libfwevt_xml_template_value_set_type(
5401
3.66M
         template_value,
5402
3.66M
         template_value_type,
5403
3.66M
         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.66M
    if( libfwevt_xml_template_value_set_size(
5419
3.66M
         template_value,
5420
3.66M
         template_value_data_size,
5421
3.66M
         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.66M
    if( libcdata_array_set_entry_by_index(
5437
3.66M
         *template_values_array,
5438
3.66M
         (int) template_value_index,
5439
3.66M
         (intptr_t *) template_value,
5440
3.66M
         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.66M
    template_value = NULL;
5457
3.66M
  }
5458
88.7k
  if( ( template_values_data_size > binary_data_size )
5459
88.5k
   || ( binary_data_offset >= ( binary_data_size - template_values_data_size ) ) )
5460
166
  {
5461
166
    libcerror_error_set(
5462
166
     error,
5463
166
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5464
166
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5465
166
     "%s: invalid template values data size value out of bounds.",
5466
166
     function );
5467
5468
166
    goto on_error;
5469
166
  }
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
88.5k
  for( template_value_index = 0;
5488
2.03M
       template_value_index < number_of_template_values;
5489
1.94M
       template_value_index++ )
5490
1.94M
  {
5491
1.94M
    if( libcdata_array_get_entry_by_index(
5492
1.94M
         *template_values_array,
5493
1.94M
         (int) template_value_index,
5494
1.94M
         (intptr_t **) &template_value,
5495
1.94M
         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.94M
    if( libfwevt_xml_template_value_get_size(
5508
1.94M
         template_value,
5509
1.94M
         &template_value_data_size,
5510
1.94M
         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.94M
    if( template_value_data_size == 0 )
5543
1.17M
    {
5544
1.17M
      continue;
5545
1.17M
    }
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
88.5k
  *template_values_size = safe_template_values_size + template_values_data_size;
5563
5564
88.5k
  return( 1 );
5565
5566
305
on_error:
5567
305
  if( template_values_array != NULL )
5568
305
  {
5569
305
    libcdata_array_free(
5570
305
     template_values_array,
5571
305
     (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
5572
305
     NULL );
5573
305
  }
5574
305
  return( -1 );
5575
88.5k
}
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
990k
{
5590
990k
  const uint8_t *xml_document_data = NULL;
5591
990k
  static char *function            = "libfwevt_xml_document_read_value";
5592
990k
  size_t value_data_size           = 0;
5593
990k
  size_t xml_document_data_size    = 0;
5594
990k
  uint8_t value_type               = 0;
5595
990k
  int data_segment_index           = 0;
5596
5597
990k
  LIBFWEVT_UNREFERENCED_PARAMETER( ascii_codepage )
5598
5599
990k
  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
990k
  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
990k
  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
990k
  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
990k
  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
990k
  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
990k
  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
990k
  xml_document_data      = &( binary_data[ binary_data_offset ] );
5678
990k
  xml_document_data_size = binary_data_size - binary_data_offset;
5679
5680
990k
  if( xml_document_data_size < 4 )
5681
33
  {
5682
33
    libcerror_error_set(
5683
33
     error,
5684
33
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5685
33
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5686
33
     "%s: invalid binary XML document data size value too small.",
5687
33
     function );
5688
5689
33
    return( -1 );
5690
33
  }
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
990k
  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
990k
  xml_token->size     = 4;
5729
990k
  binary_data_offset += 4;
5730
5731
990k
  switch( value_type )
5732
990k
  {
5733
989k
    case LIBFWEVT_VALUE_TYPE_STRING_UTF16:
5734
989k
      byte_stream_copy_to_uint16_little_endian(
5735
989k
       &( xml_document_data[ 2 ] ),
5736
989k
       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
989k
      value_data_size *= 2;
5748
5749
989k
      break;
5750
5751
35
    default:
5752
35
      libcerror_error_set(
5753
35
       error,
5754
35
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5755
35
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5756
35
       "%s: unsupported value type: 0x%02" PRIx8 ".",
5757
35
       function,
5758
35
       value_type );
5759
5760
35
      return( -1 );
5761
990k
  }
5762
989k
  if( ( value_data_size > binary_data_size )
5763
989k
   || ( binary_data_offset >= ( binary_data_size - value_data_size ) ) )
5764
98
  {
5765
98
    libcerror_error_set(
5766
98
     error,
5767
98
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5768
98
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5769
98
     "%s: invalid value data size value out of bounds.",
5770
98
     function );
5771
5772
98
    return( -1 );
5773
98
  }
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
989k
  if( libfwevt_xml_tag_set_value_type(
5792
989k
       xml_tag,
5793
989k
       value_type,
5794
989k
       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
989k
  if( libfwevt_xml_tag_append_value_data(
5806
989k
       xml_tag,
5807
989k
       &( binary_data[ binary_data_offset ] ),
5808
989k
       value_data_size,
5809
989k
       &data_segment_index,
5810
989k
       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
989k
  xml_token->size += value_data_size;
5845
5846
989k
  return( 1 );
5847
989k
}
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.59M
{
5867
1.59M
  libfwevt_xml_template_value_t *template_value = NULL;
5868
1.59M
  libfwevt_xml_token_t *xml_sub_token           = NULL;
5869
1.59M
  const uint8_t *template_value_data            = NULL;
5870
1.59M
  static char *function                         = "libfwevt_xml_document_substitute_template_value";
5871
1.59M
  size_t binary_data_offset                     = 0;
5872
1.59M
  size_t safe_template_value_offset             = 0;
5873
1.59M
  size_t template_value_data_offset             = 0;
5874
1.59M
  size_t template_value_data_size               = 0;
5875
1.59M
  size_t template_value_size                    = 0;
5876
1.59M
  uint16_t substitution_value_data_size         = 0;
5877
1.59M
  uint8_t substitution_value_type               = 0;
5878
1.59M
  uint8_t template_value_flags                  = 0;
5879
5880
1.59M
  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.59M
  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.59M
  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.59M
  if( libcdata_array_get_entry_by_index(
5914
1.59M
       template_values_array,
5915
1.59M
       (int) template_value_index,
5916
1.59M
       (intptr_t **) &template_value,
5917
1.59M
       error ) != 1 )
5918
179
  {
5919
179
    libcerror_error_set(
5920
179
     error,
5921
179
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5922
179
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5923
179
     "%s: unable to retrieve template value: %" PRIu16 " from array.",
5924
179
     function,
5925
179
     template_value_index );
5926
5927
179
    goto on_error;
5928
179
  }
5929
1.59M
  if( libfwevt_xml_template_value_get_flags(
5930
1.59M
       template_value,
5931
1.59M
       &template_value_flags,
5932
1.59M
       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.59M
  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.59M
  else
5948
1.59M
  {
5949
1.59M
    if( libfwevt_xml_template_value_get_type(
5950
1.59M
         template_value,
5951
1.59M
         &substitution_value_type,
5952
1.59M
         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.59M
  }
5964
1.59M
  if( libfwevt_xml_template_value_get_offset(
5965
1.59M
       template_value,
5966
1.59M
       &binary_data_offset,
5967
1.59M
       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.59M
  if( libfwevt_xml_template_value_get_size(
5979
1.59M
       template_value,
5980
1.59M
       &substitution_value_data_size,
5981
1.59M
       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.59M
  if( substitution_value_type == LIBFWEVT_VALUE_TYPE_NULL )
6034
176k
  {
6035
176k
    *template_value_offset = 0;
6036
6037
176k
    return( 0 );
6038
176k
  }
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.41M
  if( substitution_value_type == LIBFWEVT_VALUE_TYPE_BINARY_XML )
6062
84.0k
  {
6063
84.0k
    if( libfwevt_xml_token_initialize(
6064
84.0k
         &xml_sub_token,
6065
84.0k
         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
84.0k
    if( libfwevt_xml_token_read_data(
6077
84.0k
         xml_sub_token,
6078
84.0k
         binary_data,
6079
84.0k
         binary_data_size,
6080
84.0k
         binary_data_offset,
6081
84.0k
         error ) != 1 )
6082
7
    {
6083
7
      libcerror_error_set(
6084
7
       error,
6085
7
       LIBCERROR_ERROR_DOMAIN_IO,
6086
7
       LIBCERROR_IO_ERROR_READ_FAILED,
6087
7
       "%s: unable to read binary XML sub token.",
6088
7
       function );
6089
6090
7
      goto on_error;
6091
7
    }
6092
84.0k
    switch( xml_sub_token->type & 0xbf )
6093
84.0k
    {
6094
11.6k
      case LIBFWEVT_XML_TOKEN_OPEN_START_ELEMENT_TAG:
6095
11.6k
        if( libfwevt_xml_document_read_element(
6096
11.6k
             internal_xml_document,
6097
11.6k
             xml_sub_token,
6098
11.6k
             binary_data,
6099
11.6k
             binary_data_size,
6100
11.6k
             binary_data_offset,
6101
11.6k
             ascii_codepage,
6102
11.6k
             flags,
6103
11.6k
             template_values_array,
6104
11.6k
             xml_tag,
6105
11.6k
             element_recursion_depth + 1,
6106
11.6k
             template_instance_recursion_depth,
6107
11.6k
             error ) != 1 )
6108
11.2k
        {
6109
11.2k
          libcerror_error_set(
6110
11.2k
           error,
6111
11.2k
           LIBCERROR_ERROR_DOMAIN_IO,
6112
11.2k
           LIBCERROR_IO_ERROR_READ_FAILED,
6113
11.2k
           "%s: unable to read element.",
6114
11.2k
           function );
6115
6116
11.2k
          goto on_error;
6117
11.2k
        }
6118
404
        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.5k
      case LIBFWEVT_XML_TOKEN_TEMPLATE_INSTANCE:
6147
45.5k
        if( libfwevt_xml_document_read_template_instance(
6148
45.5k
             internal_xml_document,
6149
45.5k
             xml_sub_token,
6150
45.5k
             binary_data,
6151
45.5k
             binary_data_size,
6152
45.5k
             binary_data_offset,
6153
45.5k
             ascii_codepage,
6154
45.5k
             flags,
6155
45.5k
             xml_tag,
6156
45.5k
             element_recursion_depth,
6157
45.5k
             template_instance_recursion_depth + 1,
6158
45.5k
             error ) != 1 )
6159
390
        {
6160
390
          libcerror_error_set(
6161
390
           error,
6162
390
           LIBCERROR_ERROR_DOMAIN_IO,
6163
390
           LIBCERROR_IO_ERROR_READ_FAILED,
6164
390
           "%s: unable to read document template instance.",
6165
390
           function );
6166
6167
390
          goto on_error;
6168
390
        }
6169
45.1k
        break;
6170
6171
45.1k
      default:
6172
13
        libcerror_error_set(
6173
13
         error,
6174
13
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6175
13
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6176
13
         "%s: invalid binary XML token - unsupported type: 0x%02" PRIx8 ".",
6177
13
         function,
6178
13
         xml_sub_token->type );
6179
6180
13
        goto on_error;
6181
84.0k
    }
6182
69.2k
    if( libfwevt_xml_token_free(
6183
69.2k
         &xml_sub_token,
6184
69.2k
         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.2k
  }
6196
1.33M
  else
6197
1.33M
  {
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.33M
    switch( substitution_value_type )
6202
1.33M
    {
6203
69.3k
      case LIBFWEVT_VALUE_TYPE_STRING_UTF16:
6204
80.9k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_UTF16:
6205
80.9k
        break;
6206
6207
770
      case LIBFWEVT_VALUE_TYPE_STRING_BYTE_STREAM:
6208
461k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_BYTE_STREAM:
6209
461k
        break;
6210
6211
9.18k
      case LIBFWEVT_VALUE_TYPE_INTEGER_8BIT:
6212
27.9k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_8BIT:
6213
27.9k
        template_value_size = 1;
6214
27.9k
        break;
6215
6216
234k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_8BIT:
6217
244k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_8BIT:
6218
244k
        template_value_size = 1;
6219
244k
        break;
6220
6221
9.14k
      case LIBFWEVT_VALUE_TYPE_INTEGER_16BIT:
6222
9.78k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_16BIT:
6223
9.78k
        template_value_size = 2;
6224
9.78k
        break;
6225
6226
200k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_16BIT:
6227
201k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_16BIT:
6228
201k
        template_value_size = 2;
6229
201k
        break;
6230
6231
436
      case LIBFWEVT_VALUE_TYPE_INTEGER_32BIT:
6232
1.02k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_32BIT:
6233
1.02k
        template_value_size = 4;
6234
1.02k
        break;
6235
6236
104k
      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
753
      case LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_32BIT:
6242
1.32k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_HEXADECIMAL_INTEGER_32BIT:
6243
1.32k
        template_value_size = 4;
6244
1.32k
        break;
6245
6246
697
      case LIBFWEVT_VALUE_TYPE_INTEGER_64BIT:
6247
1.29k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_INTEGER_64BIT:
6248
1.29k
        template_value_size = 8;
6249
1.29k
        break;
6250
6251
36.3k
      case LIBFWEVT_VALUE_TYPE_UNSIGNED_INTEGER_64BIT:
6252
37.1k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_UNSIGNED_INTEGER_64BIT:
6253
37.1k
        template_value_size = 8;
6254
37.1k
        break;
6255
6256
69.7k
      case LIBFWEVT_VALUE_TYPE_HEXADECIMAL_INTEGER_64BIT:
6257
70.4k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_HEXADECIMAL_INTEGER_64BIT:
6258
70.4k
        template_value_size = 8;
6259
70.4k
        break;
6260
6261
502
      case LIBFWEVT_VALUE_TYPE_FLOATING_POINT_32BIT:
6262
1.25k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FLOATING_POINT_32BIT:
6263
1.25k
        template_value_size = 4;
6264
1.25k
        break;
6265
6266
604
      case LIBFWEVT_VALUE_TYPE_FLOATING_POINT_64BIT:
6267
1.39k
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_FLOATING_POINT_64BIT:
6268
1.39k
        template_value_size = 8;
6269
1.39k
        break;
6270
6271
510
      case LIBFWEVT_VALUE_TYPE_BOOLEAN:
6272
510
        template_value_size = 4;
6273
510
        break;
6274
6275
9.21k
      case LIBFWEVT_VALUE_TYPE_BINARY_DATA:
6276
9.21k
        break;
6277
6278
430
      case LIBFWEVT_VALUE_TYPE_GUID:
6279
944
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_GUID:
6280
944
        template_value_size = 16;
6281
944
        break;
6282
6283
/* TODO how to deal with array types ? */
6284
1.72k
      case LIBFWEVT_VALUE_TYPE_SIZE:
6285
1.72k
        if( ( substitution_value_data_size != 4 )
6286
1.25k
         && ( substitution_value_data_size != 8 ) )
6287
32
        {
6288
32
          libcerror_error_set(
6289
32
           error,
6290
32
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6291
32
           LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6292
32
           "%s: unsupported value data size: %" PRIu16 ".",
6293
32
           function,
6294
32
           substitution_value_data_size );
6295
6296
32
          goto on_error;
6297
32
        }
6298
1.69k
        break;
6299
6300
69.4k
      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
203
      case LIBFWEVT_VALUE_TYPE_SYSTEMTIME:
6306
791
      case LIBFWEVT_VALUE_TYPE_ARRAY_OF_SYSTEMTIME:
6307
791
        template_value_size = 16;
6308
791
        break;
6309
6310
4.25k
      case LIBFWEVT_VALUE_TYPE_NT_SECURITY_IDENTIFIER:
6311
4.25k
        break;
6312
6313
11
      default:
6314
11
        libcerror_error_set(
6315
11
         error,
6316
11
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6317
11
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6318
11
         "%s: unsupported value type: 0x%02" PRIx8 ".",
6319
11
         function,
6320
11
         substitution_value_type );
6321
6322
11
        goto on_error;
6323
1.33M
    }
6324
1.33M
    if( libfwevt_xml_tag_set_value_type(
6325
1.33M
         xml_tag,
6326
1.33M
         substitution_value_type,
6327
1.33M
         error ) != 1 )
6328
17
    {
6329
17
      libcerror_error_set(
6330
17
       error,
6331
17
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6332
17
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6333
17
       "%s: unable to set value type.",
6334
17
       function );
6335
6336
17
      goto on_error;
6337
17
    }
6338
1.33M
    if( ( substitution_value_type & LIBFWEVT_VALUE_TYPE_ARRAY ) != 0 )
6339
510k
    {
6340
510k
      safe_template_value_offset = *template_value_offset;
6341
6342
510k
      if( substitution_value_data_size > 0 )
6343
506k
      {
6344
506k
        if( safe_template_value_offset >= (size_t) substitution_value_data_size )
6345
33
        {
6346
33
          libcerror_error_set(
6347
33
           error,
6348
33
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6349
33
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6350
33
           "%s: invalid template value offset value out of bounds.",
6351
33
           function );
6352
6353
33
          goto on_error;
6354
33
        }
6355
506k
        template_value_data      = &( binary_data[ binary_data_offset + safe_template_value_offset ] );
6356
506k
        template_value_data_size = substitution_value_data_size - (uint16_t) safe_template_value_offset;
6357
506k
      }
6358
510k
      if( template_value_data_size > 0 )
6359
506k
      {
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
506k
        if( substitution_value_type == LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_BYTE_STREAM )
6373
460k
        {
6374
460k
          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.29M
          while( template_value_data_offset < template_value_data_size )
6386
1.28M
          {
6387
1.28M
            if( template_value_data[ template_value_data_offset ] == 0 )
6388
453k
            {
6389
453k
              template_value_data_offset += 1;
6390
6391
453k
              break;
6392
453k
            }
6393
833k
            template_value_data_offset += 1;
6394
833k
          }
6395
460k
          template_value_data_size = template_value_data_offset;
6396
460k
        }
6397
45.8k
        else if( substitution_value_type == LIBFWEVT_VALUE_TYPE_ARRAY_OF_STRING_UTF16 )
6398
10.6k
        {
6399
10.6k
          if( ( template_value_data_size < 2 )
6400
8
           && ( ( template_value_data_size % 2 ) != 0 ) )
6401
8
          {
6402
8
            libcerror_error_set(
6403
8
             error,
6404
8
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6405
8
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6406
8
             "%s: invalid UTF-16 template value data size value out of bounds.",
6407
8
             function );
6408
6409
8
            goto on_error;
6410
8
          }
6411
3.06M
          while( template_value_data_offset < template_value_data_size )
6412
3.06M
          {
6413
3.06M
            if( ( template_value_data[ template_value_data_offset ] == 0 )
6414
28.2k
             && ( template_value_data[ template_value_data_offset + 1 ] == 0 ) )
6415
9.90k
            {
6416
9.90k
              template_value_data_offset += 2;
6417
6418
9.90k
              break;
6419
9.90k
            }
6420
3.05M
            template_value_data_offset += 2;
6421
3.05M
          }
6422
10.6k
          template_value_data_size = template_value_data_offset;
6423
10.6k
        }
6424
35.2k
        else
6425
35.2k
        {
6426
35.2k
          if( template_value_size > template_value_data_size )
6427
46
          {
6428
46
            libcerror_error_set(
6429
46
             error,
6430
46
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6431
46
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6432
46
             "%s: invalid template value size value out of bounds.",
6433
46
             function );
6434
6435
46
            goto on_error;
6436
46
          }
6437
35.2k
          template_value_data_size = template_value_size;
6438
35.2k
        }
6439
506k
      }
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
510k
      if( template_value_data_size > 0 )
6444
506k
      {
6445
506k
        if( libfwevt_xml_tag_set_value_data(
6446
506k
             xml_tag,
6447
506k
             template_value_data,
6448
506k
             template_value_data_size,
6449
506k
             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
506k
        safe_template_value_offset += template_value_data_size;
6461
506k
      }
6462
510k
      if( safe_template_value_offset == substitution_value_data_size )
6463
13.7k
      {
6464
13.7k
        safe_template_value_offset = 0;
6465
13.7k
      }
6466
510k
    }
6467
823k
    else
6468
823k
    {
6469
823k
      if( ( template_value_size != 0 )
6470
737k
       && ( template_value_size != substitution_value_data_size ) )
6471
47
      {
6472
47
        libcerror_error_set(
6473
47
         error,
6474
47
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6475
47
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6476
47
         "%s: invalid substitution value data size value out of bounds.",
6477
47
         function );
6478
6479
47
        goto on_error;
6480
47
      }
6481
823k
      else if( ( substitution_value_type == LIBFWEVT_VALUE_TYPE_STRING_UTF16 )
6482
69.3k
            && ( ( substitution_value_data_size % 2 ) != 0 ) )
6483
3
      {
6484
3
        libcerror_error_set(
6485
3
         error,
6486
3
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6487
3
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
6488
3
         "%s: invalid UTF-16 substitution value data size value out of bounds.",
6489
3
         function );
6490
6491
3
        goto on_error;
6492
3
      }
6493
823k
      if( libfwevt_xml_tag_set_value_data(
6494
823k
           xml_tag,
6495
823k
           &( binary_data[ binary_data_offset ] ),
6496
823k
           (size_t) substitution_value_data_size,
6497
823k
           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
823k
    }
6509
1.33M
    if( libfwevt_xml_tag_set_flags(
6510
1.33M
         xml_tag,
6511
1.33M
         LIBFWEVT_XML_TAG_FLAG_IS_TEMPLATE_DEFINITION,
6512
1.33M
         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.33M
  }
6545
1.40M
  *template_value_offset = safe_template_value_offset;
6546
6547
1.40M
  return( 1 );
6548
6549
15.2k
on_error:
6550
15.2k
  if( xml_sub_token != NULL )
6551
14.8k
  {
6552
14.8k
    libfwevt_xml_token_free(
6553
14.8k
     &xml_sub_token,
6554
14.8k
     NULL );
6555
14.8k
  }
6556
15.2k
  return( -1 );
6557
1.41M
}
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