Coverage Report

Created: 2025-06-13 07:22

/src/libfsntfs/libfsntfs/libfsntfs_buffer_data_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The buffer data handle functions
3
 *
4
 * Copyright (C) 2010-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libfsntfs_buffer_data_handle.h"
27
#include "libfsntfs_libcerror.h"
28
#include "libfsntfs_unused.h"
29
30
/* Creates a buffer data handle
31
 * Make sure the value data_handle is referencing, is set to NULL
32
 * Returns 1 if successful or -1 on error
33
 */
34
int libfsntfs_buffer_data_handle_initialize(
35
     libfsntfs_buffer_data_handle_t **data_handle,
36
     const uint8_t *data,
37
     size_t data_size,
38
     libcerror_error_t **error )
39
1.61k
{
40
1.61k
  static char *function = "libfsntfs_buffer_data_handle_initialize";
41
42
1.61k
  if( data_handle == NULL )
43
0
  {
44
0
    libcerror_error_set(
45
0
     error,
46
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
47
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
48
0
     "%s: invalid data handle.",
49
0
     function );
50
51
0
    return( -1 );
52
0
  }
53
1.61k
  if( *data_handle != NULL )
54
0
  {
55
0
    libcerror_error_set(
56
0
     error,
57
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
58
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
59
0
     "%s: invalid data handle value already set.",
60
0
     function );
61
62
0
    return( -1 );
63
0
  }
64
1.61k
  if( data_size > 0 )
65
1.20k
  {
66
1.20k
    if( data == NULL )
67
0
    {
68
0
      libcerror_error_set(
69
0
       error,
70
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
71
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
72
0
       "%s: invalid data.",
73
0
       function );
74
75
0
      return( -1 );
76
0
    }
77
1.20k
  }
78
1.61k
  if( data_size > (size_t) SSIZE_MAX )
79
0
  {
80
0
    libcerror_error_set(
81
0
     error,
82
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
83
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
84
0
     "%s: invalid data size value exceeds maximum.",
85
0
     function );
86
87
0
    return( -1 );
88
0
  }
89
1.61k
  *data_handle = memory_allocate_structure(
90
1.61k
                  libfsntfs_buffer_data_handle_t );
91
92
1.61k
  if( *data_handle == NULL )
93
0
  {
94
0
    libcerror_error_set(
95
0
     error,
96
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
97
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
98
0
     "%s: unable to create data handle.",
99
0
     function );
100
101
0
    goto on_error;
102
0
  }
103
1.61k
  if( memory_set(
104
1.61k
       *data_handle,
105
1.61k
       0,
106
1.61k
       sizeof( libfsntfs_buffer_data_handle_t ) ) == NULL )
107
0
  {
108
0
    libcerror_error_set(
109
0
     error,
110
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
111
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
112
0
     "%s: unable to clear data handle.",
113
0
     function );
114
115
0
    goto on_error;
116
0
  }
117
1.61k
  ( *data_handle )->data      = data;
118
1.61k
  ( *data_handle )->data_size = data_size;
119
120
1.61k
  return( 1 );
121
122
0
on_error:
123
0
  if( *data_handle != NULL )
124
0
  {
125
0
    memory_free(
126
0
     *data_handle );
127
128
0
    *data_handle = NULL;
129
0
  }
130
0
  return( -1 );
131
1.61k
}
132
133
/* Frees a buffer data handle
134
 * Returns 1 if successful or -1 on error
135
 */
136
int libfsntfs_buffer_data_handle_free(
137
     libfsntfs_buffer_data_handle_t **data_handle,
138
     libcerror_error_t **error )
139
1.61k
{
140
1.61k
  static char *function = "libfsntfs_buffer_data_handle_free";
141
142
1.61k
  if( data_handle == NULL )
143
0
  {
144
0
    libcerror_error_set(
145
0
     error,
146
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
147
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
148
0
     "%s: invalid data handle.",
149
0
     function );
150
151
0
    return( -1 );
152
0
  }
153
1.61k
  if( *data_handle != NULL )
154
1.61k
  {
155
1.61k
    memory_free(
156
1.61k
     *data_handle );
157
158
1.61k
    *data_handle = NULL;
159
1.61k
  }
160
1.61k
  return( 1 );
161
1.61k
}
162
163
/* Reads data from the current offset into a buffer
164
 * Callback for the data stream
165
 * Returns the number of bytes read or -1 on error
166
 */
167
ssize_t libfsntfs_buffer_data_handle_read_segment_data(
168
         libfsntfs_buffer_data_handle_t *data_handle,
169
         intptr_t *file_io_handle LIBFSNTFS_ATTRIBUTE_UNUSED,
170
         int segment_index,
171
         int segment_file_index LIBFSNTFS_ATTRIBUTE_UNUSED,
172
         uint8_t *segment_data,
173
         size_t segment_data_size,
174
         uint32_t segment_flags LIBFSNTFS_ATTRIBUTE_UNUSED,
175
         uint8_t read_flags LIBFSNTFS_ATTRIBUTE_UNUSED,
176
         libcerror_error_t **error )
177
2.67k
{
178
2.67k
  static char *function = "libfsntfs_buffer_data_handle_read_segment_data";
179
2.67k
  size_t read_size      = 0;
180
181
2.67k
  LIBFSNTFS_UNREFERENCED_PARAMETER( file_io_handle )
182
2.67k
  LIBFSNTFS_UNREFERENCED_PARAMETER( segment_file_index )
183
2.67k
  LIBFSNTFS_UNREFERENCED_PARAMETER( segment_flags )
184
2.67k
  LIBFSNTFS_UNREFERENCED_PARAMETER( read_flags )
185
186
2.67k
  if( data_handle == NULL )
187
0
  {
188
0
    libcerror_error_set(
189
0
     error,
190
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
191
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
192
0
     "%s: invalid data handle.",
193
0
     function );
194
195
0
    return( -1 );
196
0
  }
197
2.67k
  if( data_handle->current_offset < 0 )
198
0
  {
199
0
    libcerror_error_set(
200
0
     error,
201
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
202
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
203
0
     "%s: invalid data handle - current offset value out of bounds.",
204
0
     function );
205
206
0
    return( -1 );
207
0
  }
208
2.67k
  if( segment_index != 0 )
209
0
  {
210
0
    libcerror_error_set(
211
0
     error,
212
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
213
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
214
0
     "%s: invalid segment index value out of bounds.",
215
0
     function );
216
217
0
    return( -1 );
218
0
  }
219
2.67k
  if( segment_data == NULL )
220
0
  {
221
0
    libcerror_error_set(
222
0
     error,
223
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
224
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
225
0
     "%s: invalid segment data.",
226
0
     function );
227
228
0
    return( -1 );
229
0
  }
230
2.67k
  if( segment_data_size > (size_t) SSIZE_MAX )
231
0
  {
232
0
    libcerror_error_set(
233
0
     error,
234
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
235
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
236
0
     "%s: invalid segment data size value exceeds maximum.",
237
0
     function );
238
239
0
    return( -1 );
240
0
  }
241
2.67k
  if( data_handle->current_offset >= (off64_t) data_handle->data_size )
242
0
  {
243
0
    return( 0 );
244
0
  }
245
2.67k
  read_size = data_handle->data_size - (size_t) data_handle->current_offset;
246
247
2.67k
  if( read_size > segment_data_size )
248
886
  {
249
886
    read_size = segment_data_size;
250
886
  }
251
2.67k
  if( memory_copy(
252
2.67k
       segment_data,
253
2.67k
       &( data_handle->data[ data_handle->current_offset ] ),
254
2.67k
       read_size ) == NULL )
255
0
  {
256
0
    libcerror_error_set(
257
0
     error,
258
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
259
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
260
0
     "%s: unable to copy data.",
261
0
     function );
262
263
0
    return( -1 );
264
0
  }
265
2.67k
  data_handle->current_offset += read_size;
266
267
2.67k
  return( (ssize_t) read_size );
268
2.67k
}
269
270
/* Seeks a certain offset of the data
271
 * Callback for the data stream
272
 * Returns the offset if seek is successful or -1 on error
273
 */
274
off64_t libfsntfs_buffer_data_handle_seek_segment_offset(
275
         libfsntfs_buffer_data_handle_t *data_handle,
276
         intptr_t *file_io_handle LIBFSNTFS_ATTRIBUTE_UNUSED,
277
         int segment_index,
278
         int segment_file_index LIBFSNTFS_ATTRIBUTE_UNUSED,
279
         off64_t segment_offset,
280
         libcerror_error_t **error )
281
2.67k
{
282
2.67k
  static char *function = "libfsntfs_buffer_data_handle_seek_segment_offset";
283
284
2.67k
  LIBFSNTFS_UNREFERENCED_PARAMETER( file_io_handle )
285
2.67k
  LIBFSNTFS_UNREFERENCED_PARAMETER( segment_file_index )
286
287
2.67k
  if( data_handle == NULL )
288
0
  {
289
0
    libcerror_error_set(
290
0
     error,
291
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
292
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
293
0
     "%s: invalid data handle.",
294
0
     function );
295
296
0
    return( -1 );
297
0
  }
298
2.67k
  if( segment_index != 0 )
299
0
  {
300
0
    libcerror_error_set(
301
0
     error,
302
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
303
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
304
0
     "%s: invalid segment index value out of bounds.",
305
0
     function );
306
307
0
    return( -1 );
308
0
  }
309
2.67k
  if( segment_offset < 0 )
310
0
  {
311
0
    libcerror_error_set(
312
0
     error,
313
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
314
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
315
0
     "%s: invalid segment offset value out of bounds.",
316
0
     function );
317
318
0
    return( -1 );
319
0
  }
320
2.67k
  data_handle->current_offset = segment_offset;
321
322
2.67k
  return( segment_offset );
323
2.67k
}
324