Coverage Report

Created: 2023-06-07 06:53

/src/libfwevt/libfwevt/libfwevt_level.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Level functions
3
 *
4
 * Copyright (C) 2011-2023, 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 <narrow_string.h>
26
#include <system_string.h>
27
#include <types.h>
28
#include <wide_string.h>
29
30
#include "libfwevt_debug.h"
31
#include "libfwevt_level.h"
32
#include "libfwevt_libcerror.h"
33
#include "libfwevt_libcnotify.h"
34
#include "libfwevt_libuna.h"
35
#include "libfwevt_types.h"
36
37
#include "fwevt_template.h"
38
39
/* Creates a level
40
 * Make sure the value level is referencing, is set to NULL
41
 * Returns 1 if successful or -1 on error
42
 */
43
int libfwevt_level_initialize(
44
     libfwevt_level_t **level,
45
     libcerror_error_t **error )
46
44.1k
{
47
44.1k
  libfwevt_internal_level_t *internal_level = NULL;
48
44.1k
  static char *function                     = "libfwevt_level_initialize";
49
50
44.1k
  if( level == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid level.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
44.1k
  if( *level != NULL )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
66
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
67
0
     "%s: invalid level value already set.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
44.1k
  internal_level = memory_allocate_structure(
73
44.1k
                    libfwevt_internal_level_t );
74
75
44.1k
  if( internal_level == NULL )
76
0
  {
77
0
    libcerror_error_set(
78
0
     error,
79
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
80
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
81
0
     "%s: unable to create level.",
82
0
     function );
83
84
0
    goto on_error;
85
0
  }
86
44.1k
  if( memory_set(
87
44.1k
       internal_level,
88
44.1k
       0,
89
44.1k
       sizeof( libfwevt_internal_level_t ) ) == NULL )
90
0
  {
91
0
    libcerror_error_set(
92
0
     error,
93
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
94
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
95
0
     "%s: unable to clear level.",
96
0
     function );
97
98
0
    goto on_error;
99
0
  }
100
44.1k
  *level = (libfwevt_level_t *) internal_level;
101
102
44.1k
  return( 1 );
103
104
0
on_error:
105
0
  if( internal_level != NULL )
106
0
  {
107
0
    memory_free(
108
0
     internal_level );
109
0
  }
110
0
  return( -1 );
111
44.1k
}
112
113
/* Frees a level
114
 * Returns 1 if successful or -1 on error
115
 */
116
int libfwevt_level_free(
117
     libfwevt_level_t **level,
118
     libcerror_error_t **error )
119
0
{
120
0
  static char *function = "libfwevt_level_free";
121
122
0
  if( level == NULL )
123
0
  {
124
0
    libcerror_error_set(
125
0
     error,
126
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
127
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
128
0
     "%s: invalid level.",
129
0
     function );
130
131
0
    return( -1 );
132
0
  }
133
0
  if( *level != NULL )
134
0
  {
135
0
    *level = NULL;
136
0
  }
137
0
  return( 1 );
138
0
}
139
140
/* Frees a level
141
 * Returns 1 if successful or -1 on error
142
 */
143
int libfwevt_internal_level_free(
144
     libfwevt_internal_level_t **internal_level,
145
     libcerror_error_t **error )
146
44.1k
{
147
44.1k
  static char *function = "libfwevt_internal_level_free";
148
149
44.1k
  if( internal_level == NULL )
150
0
  {
151
0
    libcerror_error_set(
152
0
     error,
153
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
154
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
155
0
     "%s: invalid level.",
156
0
     function );
157
158
0
    return( -1 );
159
0
  }
160
44.1k
  if( *internal_level != NULL )
161
44.1k
  {
162
44.1k
    memory_free(
163
44.1k
     *internal_level );
164
165
44.1k
    *internal_level = NULL;
166
44.1k
  }
167
44.1k
  return( 1 );
168
44.1k
}
169
170
/* Reads the level
171
 * Returns 1 if successful or -1 on error
172
 */
173
int libfwevt_level_read_data(
174
     libfwevt_level_t *level,
175
     const uint8_t *data,
176
     size_t data_size,
177
     size_t data_offset,
178
     libcerror_error_t **error )
179
44.1k
{
180
44.1k
  fwevt_template_level_t *wevt_level = NULL;
181
44.1k
  static char *function              = "libfwevt_level_read_data";
182
44.1k
  uint32_t level_data_offset         = 0;
183
44.1k
  uint32_t level_data_size           = 0;
184
185
#if defined( HAVE_DEBUG_OUTPUT )
186
  uint32_t value_32bit               = 0;
187
#endif
188
189
44.1k
  if( level == NULL )
190
0
  {
191
0
    libcerror_error_set(
192
0
     error,
193
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
194
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
195
0
     "%s: invalid level.",
196
0
     function );
197
198
0
    return( -1 );
199
0
  }
200
44.1k
  if( data == NULL )
201
0
  {
202
0
    libcerror_error_set(
203
0
     error,
204
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
205
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
206
0
     "%s: invalid data.",
207
0
     function );
208
209
0
    return( -1 );
210
0
  }
211
44.1k
  if( data_size > (size_t) SSIZE_MAX )
212
0
  {
213
0
    libcerror_error_set(
214
0
     error,
215
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
216
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
217
0
     "%s: invalid data size value exceeds maximum.",
218
0
     function );
219
220
0
    return( -1 );
221
0
  }
222
44.1k
  if( data_offset >= data_size )
223
0
  {
224
0
    libcerror_error_set(
225
0
     error,
226
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
227
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
228
0
     "%s: invalid data offset value out of bounds.",
229
0
     function );
230
231
0
    return( -1 );
232
0
  }
233
44.1k
  if( ( data_size < sizeof( fwevt_template_level_t ) )
234
44.1k
   || ( data_offset > ( data_size - sizeof( fwevt_template_level_t ) ) ) )
235
0
  {
236
0
    libcerror_error_set(
237
0
     error,
238
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
239
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
240
0
     "%s: invalid data value too small.",
241
0
     function );
242
243
0
    return( -1 );
244
0
  }
245
44.1k
  wevt_level = (fwevt_template_level_t *) &( data[ data_offset ] );
246
247
#if defined( HAVE_DEBUG_OUTPUT )
248
  if( libcnotify_verbose != 0 )
249
  {
250
    libcnotify_printf(
251
     "%s: level data:\n",
252
     function );
253
    libcnotify_print_data(
254
     (uint8_t *) wevt_level,
255
     sizeof( fwevt_template_level_t ),
256
     0 );
257
  }
258
#endif
259
44.1k
  byte_stream_copy_to_uint32_little_endian(
260
44.1k
   wevt_level->data_offset,
261
44.1k
   level_data_offset );
262
263
#if defined( HAVE_DEBUG_OUTPUT )
264
  if( libcnotify_verbose != 0 )
265
  {
266
    byte_stream_copy_to_uint32_little_endian(
267
     wevt_level->identifier,
268
     value_32bit );
269
    libcnotify_printf(
270
     "%s: identifier\t\t\t\t\t\t: %" PRIu32 "\n",
271
     function,
272
     value_32bit );
273
274
    byte_stream_copy_to_uint32_little_endian(
275
     wevt_level->message_identifier,
276
     value_32bit );
277
    libcnotify_printf(
278
     "%s: message identifier\t\t\t\t\t: 0x%08" PRIx32 "\n",
279
     function,
280
     value_32bit );
281
282
    libcnotify_printf(
283
     "%s: data offset\t\t\t\t\t: 0x%08" PRIx32 "\n",
284
     function,
285
     level_data_offset );
286
  }
287
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
288
289
44.1k
  if( level_data_offset > 0 )
290
875
  {
291
875
    if( level_data_offset >= ( data_size - 4 ) )
292
128
    {
293
128
      libcerror_error_set(
294
128
       error,
295
128
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
296
128
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
297
128
       "%s: invalid level data offset value out of bounds.",
298
128
       function );
299
300
128
      return( -1 );
301
128
    }
302
747
    byte_stream_copy_to_uint32_little_endian(
303
747
     &( data[ level_data_offset ] ),
304
747
     level_data_size );
305
306
747
    if( ( data_size < level_data_size )
307
747
     || ( level_data_offset > ( data_size - level_data_size ) ) )
308
81
    {
309
81
      libcerror_error_set(
310
81
       error,
311
81
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
312
81
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
313
81
       "%s: invalid level data size value out of bounds.",
314
81
       function );
315
316
81
      return( -1 );
317
81
    }
318
#if defined( HAVE_DEBUG_OUTPUT )
319
    if( libcnotify_verbose != 0 )
320
    {
321
      libcnotify_printf(
322
       "%s: data:\n",
323
       function );
324
      libcnotify_print_data(
325
       &( data[ level_data_offset ] ),
326
       level_data_size,
327
       0 );
328
    }
329
#endif
330
#if defined( HAVE_DEBUG_OUTPUT )
331
    if( libcnotify_verbose != 0 )
332
    {
333
      libcnotify_printf(
334
       "%s: data size\t\t\t\t\t\t: %" PRIu32 "\n",
335
       function,
336
       level_data_size );
337
    }
338
#endif
339
666
    if( level_data_size >= 4 )
340
348
    {
341
348
      level_data_offset += 4;
342
348
      level_data_size   -= 4;
343
344
#if defined( HAVE_DEBUG_OUTPUT )
345
      if( libcnotify_verbose != 0 )
346
      {
347
        if( libfwevt_debug_print_utf16_string_value(
348
             function,
349
             "name\t\t\t\t\t\t",
350
             &( data[ level_data_offset ] ),
351
             level_data_size,
352
             LIBUNA_ENDIAN_LITTLE,
353
             error ) != 1 )
354
        {
355
          libcerror_error_set(
356
           error,
357
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
358
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
359
           "%s: unable to print UTF-16 string value.",
360
           function );
361
362
          return( -1 );
363
        }
364
      }
365
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
366
348
    }
367
666
  }
368
#if defined( HAVE_DEBUG_OUTPUT )
369
  if( libcnotify_verbose != 0 )
370
  {
371
    libcnotify_printf(
372
     "\n" );
373
  }
374
#endif
375
43.9k
  return( 1 );
376
44.1k
}
377