Coverage Report

Created: 2024-02-25 07:20

/src/libfshfs/libfshfs/libfshfs_buffer_data_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The buffer data handle functions
3
 *
4
 * Copyright (C) 2009-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 "libfshfs_buffer_data_handle.h"
27
#include "libfshfs_libcerror.h"
28
#include "libfshfs_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 libfshfs_buffer_data_handle_initialize(
35
     libfshfs_buffer_data_handle_t **data_handle,
36
     const uint8_t *data,
37
     size_t data_size,
38
     libcerror_error_t **error )
39
0
{
40
0
  static char *function = "libfshfs_buffer_data_handle_initialize";
41
42
0
  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
0
  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
0
  if( data_size > 0 )
65
0
  {
66
0
    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
0
  }
78
0
  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
0
  *data_handle = memory_allocate_structure(
90
0
                  libfshfs_buffer_data_handle_t );
91
92
0
  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
0
  if( memory_set(
104
0
       *data_handle,
105
0
       0,
106
0
       sizeof( libfshfs_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
0
  ( *data_handle )->data      = data;
118
0
  ( *data_handle )->data_size = data_size;
119
120
0
  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
0
}
132
133
/* Frees a buffer data handle
134
 * Returns 1 if successful or -1 on error
135
 */
136
int libfshfs_buffer_data_handle_free(
137
     libfshfs_buffer_data_handle_t **data_handle,
138
     libcerror_error_t **error )
139
0
{
140
0
  static char *function = "libfshfs_buffer_data_handle_free";
141
142
0
  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
0
  if( *data_handle != NULL )
154
0
  {
155
0
    memory_free(
156
0
     *data_handle );
157
158
0
    *data_handle = NULL;
159
0
  }
160
0
  return( 1 );
161
0
}
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 libfshfs_buffer_data_handle_read_segment_data(
168
         libfshfs_buffer_data_handle_t *data_handle,
169
         intptr_t *file_io_handle LIBFSHFS_ATTRIBUTE_UNUSED,
170
         int segment_index,
171
         int segment_file_index LIBFSHFS_ATTRIBUTE_UNUSED,
172
         uint8_t *segment_data,
173
         size_t segment_data_size,
174
         uint32_t segment_flags LIBFSHFS_ATTRIBUTE_UNUSED,
175
         uint8_t read_flags LIBFSHFS_ATTRIBUTE_UNUSED,
176
         libcerror_error_t **error )
177
0
{
178
0
  static char *function = "libfshfs_buffer_data_handle_read_segment_data";
179
0
  size_t read_size      = 0;
180
181
0
  LIBFSHFS_UNREFERENCED_PARAMETER( file_io_handle )
182
0
  LIBFSHFS_UNREFERENCED_PARAMETER( segment_file_index )
183
0
  LIBFSHFS_UNREFERENCED_PARAMETER( segment_flags )
184
0
  LIBFSHFS_UNREFERENCED_PARAMETER( read_flags )
185
186
0
  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
0
  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
0
  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
0
  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
0
  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
0
  if( data_handle->current_offset >= (off64_t) data_handle->data_size )
242
0
  {
243
0
    return( 0 );
244
0
  }
245
0
  read_size = data_handle->data_size - (size_t) data_handle->current_offset;
246
247
0
  if( read_size > segment_data_size )
248
0
  {
249
0
    read_size = segment_data_size;
250
0
  }
251
0
  if( memory_copy(
252
0
       segment_data,
253
0
       &( data_handle->data[ data_handle->current_offset ] ),
254
0
       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
0
  data_handle->current_offset += read_size;
266
267
0
  return( (ssize_t) read_size );
268
0
}
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 libfshfs_buffer_data_handle_seek_segment_offset(
275
         libfshfs_buffer_data_handle_t *data_handle,
276
         intptr_t *file_io_handle LIBFSHFS_ATTRIBUTE_UNUSED,
277
         int segment_index,
278
         int segment_file_index LIBFSHFS_ATTRIBUTE_UNUSED,
279
         off64_t segment_offset,
280
         libcerror_error_t **error )
281
0
{
282
0
  static char *function = "libfshfs_buffer_data_handle_seek_segment_offset";
283
284
0
  LIBFSHFS_UNREFERENCED_PARAMETER( file_io_handle )
285
0
  LIBFSHFS_UNREFERENCED_PARAMETER( segment_file_index )
286
287
0
  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
0
  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
0
  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
0
  data_handle->current_offset = segment_offset;
321
322
0
  return( segment_offset );
323
0
}
324