/src/libcreg/libcreg/libcreg_value_entry.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Value entry functions |
3 | | * |
4 | | * Copyright (C) 2013-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 <byte_stream.h> |
24 | | #include <memory.h> |
25 | | #include <types.h> |
26 | | |
27 | | #if defined( HAVE_WCTYPE_H ) |
28 | | #include <wctype.h> |
29 | | #endif |
30 | | |
31 | | #include "libcreg_data_type.h" |
32 | | #include "libcreg_debug.h" |
33 | | #include "libcreg_libcerror.h" |
34 | | #include "libcreg_libcnotify.h" |
35 | | #include "libcreg_libuna.h" |
36 | | #include "libcreg_unused.h" |
37 | | #include "libcreg_value_entry.h" |
38 | | |
39 | | #include "creg_data_block.h" |
40 | | |
41 | | /* Creates a value entry |
42 | | * Make sure the value value_entry is referencing, is set to NULL |
43 | | * Returns 1 if successful or -1 on error |
44 | | */ |
45 | | int libcreg_value_entry_initialize( |
46 | | libcreg_value_entry_t **value_entry, |
47 | | libcerror_error_t **error ) |
48 | 21.2k | { |
49 | 21.2k | static char *function = "libcreg_value_entry_initialize"; |
50 | | |
51 | 21.2k | if( value_entry == NULL ) |
52 | 0 | { |
53 | 0 | libcerror_error_set( |
54 | 0 | error, |
55 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
56 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
57 | 0 | "%s: invalid value entry.", |
58 | 0 | function ); |
59 | |
|
60 | 0 | return( -1 ); |
61 | 0 | } |
62 | 21.2k | if( *value_entry != NULL ) |
63 | 0 | { |
64 | 0 | libcerror_error_set( |
65 | 0 | error, |
66 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
67 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, |
68 | 0 | "%s: invalid value entry value already set.", |
69 | 0 | function ); |
70 | |
|
71 | 0 | return( -1 ); |
72 | 0 | } |
73 | 21.2k | *value_entry = memory_allocate_structure( |
74 | 21.2k | libcreg_value_entry_t ); |
75 | | |
76 | 21.2k | if( *value_entry == NULL ) |
77 | 0 | { |
78 | 0 | libcerror_error_set( |
79 | 0 | error, |
80 | 0 | LIBCERROR_ERROR_DOMAIN_MEMORY, |
81 | 0 | LIBCERROR_MEMORY_ERROR_INSUFFICIENT, |
82 | 0 | "%s: unable to create value entry.", |
83 | 0 | function ); |
84 | |
|
85 | 0 | goto on_error; |
86 | 0 | } |
87 | 21.2k | if( memory_set( |
88 | 21.2k | *value_entry, |
89 | 21.2k | 0, |
90 | 21.2k | sizeof( libcreg_value_entry_t ) ) == NULL ) |
91 | 0 | { |
92 | 0 | libcerror_error_set( |
93 | 0 | error, |
94 | 0 | LIBCERROR_ERROR_DOMAIN_MEMORY, |
95 | 0 | LIBCERROR_MEMORY_ERROR_SET_FAILED, |
96 | 0 | "%s: unable to clear value entry.", |
97 | 0 | function ); |
98 | |
|
99 | 0 | goto on_error; |
100 | 0 | } |
101 | 21.2k | return( 1 ); |
102 | | |
103 | 0 | on_error: |
104 | 0 | if( *value_entry != NULL ) |
105 | 0 | { |
106 | 0 | memory_free( |
107 | 0 | *value_entry ); |
108 | |
|
109 | 0 | *value_entry = NULL; |
110 | 0 | } |
111 | 0 | return( -1 ); |
112 | 21.2k | } |
113 | | |
114 | | /* Frees a value entry |
115 | | * Returns 1 if successful or -1 on error |
116 | | */ |
117 | | int libcreg_value_entry_free( |
118 | | libcreg_value_entry_t **value_entry, |
119 | | libcerror_error_t **error ) |
120 | 21.2k | { |
121 | 21.2k | static char *function = "libcreg_value_entry_free"; |
122 | | |
123 | 21.2k | if( value_entry == NULL ) |
124 | 0 | { |
125 | 0 | libcerror_error_set( |
126 | 0 | error, |
127 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
128 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
129 | 0 | "%s: invalid value entry.", |
130 | 0 | function ); |
131 | |
|
132 | 0 | return( -1 ); |
133 | 0 | } |
134 | 21.2k | if( *value_entry != NULL ) |
135 | 21.2k | { |
136 | 21.2k | if( ( *value_entry )->data != NULL ) |
137 | 4.10k | { |
138 | 4.10k | memory_free( |
139 | 4.10k | ( *value_entry )->data ); |
140 | 4.10k | } |
141 | 21.2k | if( ( *value_entry )->name != NULL ) |
142 | 3.41k | { |
143 | 3.41k | memory_free( |
144 | 3.41k | ( *value_entry )->name ); |
145 | 3.41k | } |
146 | 21.2k | memory_free( |
147 | 21.2k | *value_entry ); |
148 | | |
149 | 21.2k | *value_entry = NULL; |
150 | 21.2k | } |
151 | 21.2k | return( 1 ); |
152 | 21.2k | } |
153 | | |
154 | | /* Reads a value entry |
155 | | * Returns 1 if successful or -1 on error |
156 | | */ |
157 | | int libcreg_value_entry_read_data( |
158 | | libcreg_value_entry_t *value_entry, |
159 | | const uint8_t *data, |
160 | | size_t data_size, |
161 | | int ascii_codepage LIBCREG_ATTRIBUTE_UNUSED, |
162 | | libcerror_error_t **error ) |
163 | 21.2k | { |
164 | 21.2k | static char *function = "libcreg_value_entry_read_data"; |
165 | 21.2k | size_t value_data_offset = 0; |
166 | | |
167 | | #if defined( HAVE_DEBUG_OUTPUT ) |
168 | | uint32_t value_32bit = 0; |
169 | | #endif |
170 | | |
171 | 21.2k | LIBCREG_UNREFERENCED_PARAMETER( ascii_codepage ) |
172 | | |
173 | 21.2k | if( value_entry == NULL ) |
174 | 0 | { |
175 | 0 | libcerror_error_set( |
176 | 0 | error, |
177 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
178 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
179 | 0 | "%s: invalid value entry.", |
180 | 0 | function ); |
181 | |
|
182 | 0 | return( -1 ); |
183 | 0 | } |
184 | 21.2k | if( data == NULL ) |
185 | 0 | { |
186 | 0 | libcerror_error_set( |
187 | 0 | error, |
188 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
189 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
190 | 0 | "%s: invalid data.", |
191 | 0 | function ); |
192 | |
|
193 | 0 | return( -1 ); |
194 | 0 | } |
195 | 21.2k | if( data_size < sizeof( creg_value_entry_t ) ) |
196 | 103 | { |
197 | 103 | libcerror_error_set( |
198 | 103 | error, |
199 | 103 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
200 | 103 | LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, |
201 | 103 | "%s: invalid data size value too small.", |
202 | 103 | function ); |
203 | | |
204 | 103 | return( -1 ); |
205 | 103 | } |
206 | 21.1k | if( data_size > (size_t) SSIZE_MAX ) |
207 | 0 | { |
208 | 0 | libcerror_error_set( |
209 | 0 | error, |
210 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
211 | 0 | LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, |
212 | 0 | "%s: invalid data size value exceeds maximum.", |
213 | 0 | function ); |
214 | |
|
215 | 0 | return( -1 ); |
216 | 0 | } |
217 | 21.1k | byte_stream_copy_to_uint32_little_endian( |
218 | 21.1k | ( (creg_value_entry_t *) data )->data_type, |
219 | 21.1k | value_entry->type ); |
220 | | |
221 | 21.1k | byte_stream_copy_to_uint16_little_endian( |
222 | 21.1k | ( (creg_value_entry_t *) data )->name_size, |
223 | 21.1k | value_entry->name_size ); |
224 | | |
225 | 21.1k | byte_stream_copy_to_uint16_little_endian( |
226 | 21.1k | ( (creg_value_entry_t *) data )->data_size, |
227 | 21.1k | value_entry->data_size ); |
228 | | |
229 | 21.1k | value_entry->size = sizeof( creg_value_entry_t ) + value_entry->name_size + value_entry->data_size; |
230 | | |
231 | | #if SIZEOF_SIZE_T <= 4 |
232 | | if( value_entry->size > (size_t) SSIZE_MAX ) |
233 | | #else |
234 | 21.1k | if( (uint32_t) value_entry->size > (uint32_t) SSIZE_MAX ) |
235 | 0 | #endif |
236 | 0 | { |
237 | 0 | libcerror_error_set( |
238 | 0 | error, |
239 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
240 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
241 | 0 | "%s: invalid value entry size value out of bounds.", |
242 | 0 | function ); |
243 | |
|
244 | 0 | return( -1 ); |
245 | 0 | } |
246 | 21.1k | if( data_size < (size_t) value_entry->size ) |
247 | 149 | { |
248 | 149 | libcerror_error_set( |
249 | 149 | error, |
250 | 149 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
251 | 149 | LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, |
252 | 149 | "%s: invalid data size value too small.", |
253 | 149 | function ); |
254 | | |
255 | 149 | return( -1 ); |
256 | 149 | } |
257 | | #if defined( HAVE_DEBUG_OUTPUT ) |
258 | | if( libcnotify_verbose != 0 ) |
259 | | { |
260 | | libcnotify_printf( |
261 | | "%s: data:\n", |
262 | | function ); |
263 | | libcnotify_print_data( |
264 | | data, |
265 | | value_entry->size, |
266 | | 0 ); |
267 | | } |
268 | | #endif |
269 | | #if defined( HAVE_DEBUG_OUTPUT ) |
270 | | if( libcnotify_verbose != 0 ) |
271 | | { |
272 | | libcnotify_printf( |
273 | | "%s: data type\t\t\t\t: 0x%08" PRIx32 " (%s) %s\n", |
274 | | function, |
275 | | value_entry->type, |
276 | | libcreg_data_type_get_identifier( |
277 | | value_entry->type ), |
278 | | libcreg_data_type_get_description( |
279 | | value_entry->type ) ); |
280 | | |
281 | | byte_stream_copy_to_uint32_little_endian( |
282 | | ( (creg_value_entry_t *) data )->unknown1, |
283 | | value_32bit ); |
284 | | libcnotify_printf( |
285 | | "%s: unknown1\t\t\t\t\t: 0x%08" PRIx32 "\n", |
286 | | function, |
287 | | value_32bit ); |
288 | | |
289 | | libcnotify_printf( |
290 | | "%s: name size\t\t\t\t: %" PRIu16 "\n", |
291 | | function, |
292 | | value_entry->name_size ); |
293 | | |
294 | | libcnotify_printf( |
295 | | "%s: data size\t\t\t\t: %" PRIu16 "\n", |
296 | | function, |
297 | | value_entry->data_size ); |
298 | | } |
299 | | #endif /* defined( HAVE_DEBUG_OUTPUT ) */ |
300 | | |
301 | 21.0k | value_data_offset = sizeof( creg_value_entry_t ); |
302 | | |
303 | 21.0k | if( value_entry->name_size > 0 ) |
304 | 3.41k | { |
305 | 3.41k | if( value_entry->name_size > ( value_entry->size - value_data_offset ) ) |
306 | 0 | { |
307 | 0 | libcerror_error_set( |
308 | 0 | error, |
309 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
310 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
311 | 0 | "%s: invalid name size value out of bounds.", |
312 | 0 | function ); |
313 | |
|
314 | 0 | goto on_error; |
315 | 0 | } |
316 | 3.41k | value_entry->name = (uint8_t *) memory_allocate( |
317 | 3.41k | sizeof( uint8_t ) * (size_t) value_entry->name_size ); |
318 | | |
319 | 3.41k | if( value_entry->name == NULL ) |
320 | 0 | { |
321 | 0 | libcerror_error_set( |
322 | 0 | error, |
323 | 0 | LIBCERROR_ERROR_DOMAIN_MEMORY, |
324 | 0 | LIBCERROR_MEMORY_ERROR_INSUFFICIENT, |
325 | 0 | "%s: unable to create name.", |
326 | 0 | function ); |
327 | |
|
328 | 0 | goto on_error; |
329 | 0 | } |
330 | 3.41k | if( memory_copy( |
331 | 3.41k | value_entry->name, |
332 | 3.41k | &( data[ value_data_offset ] ), |
333 | 3.41k | (size_t) value_entry->name_size ) == NULL ) |
334 | 0 | { |
335 | 0 | libcerror_error_set( |
336 | 0 | error, |
337 | 0 | LIBCERROR_ERROR_DOMAIN_MEMORY, |
338 | 0 | LIBCERROR_MEMORY_ERROR_COPY_FAILED, |
339 | 0 | "%s: unable to copy name.", |
340 | 0 | function ); |
341 | |
|
342 | 0 | goto on_error; |
343 | 0 | } |
344 | 3.41k | value_entry->name_hash = 0; |
345 | | |
346 | | #if defined( HAVE_DEBUG_OUTPUT ) |
347 | | if( libcnotify_verbose != 0 ) |
348 | | { |
349 | | if( libcreg_debug_print_string_value( |
350 | | function, |
351 | | "name\t\t\t\t\t", |
352 | | &( data[ value_data_offset ] ), |
353 | | (size_t) value_entry->name_size, |
354 | | ascii_codepage, |
355 | | error ) != 1 ) |
356 | | { |
357 | | libcerror_error_set( |
358 | | error, |
359 | | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
360 | | LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, |
361 | | "%s: unable to print string value.", |
362 | | function ); |
363 | | |
364 | | goto on_error; |
365 | | } |
366 | | } |
367 | | #endif /* defined( HAVE_DEBUG_OUTPUT ) */ |
368 | | |
369 | 3.41k | value_data_offset += value_entry->name_size; |
370 | 3.41k | } |
371 | 21.0k | if( value_entry->data_size > 0 ) |
372 | 4.10k | { |
373 | 4.10k | if( value_entry->data_size > ( value_entry->size - value_data_offset ) ) |
374 | 0 | { |
375 | 0 | libcerror_error_set( |
376 | 0 | error, |
377 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
378 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
379 | 0 | "%s: invalid data size value out of bounds.", |
380 | 0 | function ); |
381 | |
|
382 | 0 | goto on_error; |
383 | 0 | } |
384 | 4.10k | value_entry->data = (uint8_t *) memory_allocate( |
385 | 4.10k | sizeof( uint8_t ) * (size_t) value_entry->data_size ); |
386 | | |
387 | 4.10k | if( value_entry->data == NULL ) |
388 | 0 | { |
389 | 0 | libcerror_error_set( |
390 | 0 | error, |
391 | 0 | LIBCERROR_ERROR_DOMAIN_MEMORY, |
392 | 0 | LIBCERROR_MEMORY_ERROR_INSUFFICIENT, |
393 | 0 | "%s: unable to create data.", |
394 | 0 | function ); |
395 | |
|
396 | 0 | goto on_error; |
397 | 0 | } |
398 | 4.10k | if( memory_copy( |
399 | 4.10k | value_entry->data, |
400 | 4.10k | &( data[ value_data_offset ] ), |
401 | 4.10k | (size_t) value_entry->data_size ) == NULL ) |
402 | 0 | { |
403 | 0 | libcerror_error_set( |
404 | 0 | error, |
405 | 0 | LIBCERROR_ERROR_DOMAIN_MEMORY, |
406 | 0 | LIBCERROR_MEMORY_ERROR_COPY_FAILED, |
407 | 0 | "%s: unable to copy data.", |
408 | 0 | function ); |
409 | |
|
410 | 0 | goto on_error; |
411 | 0 | } |
412 | | #if defined( HAVE_DEBUG_OUTPUT ) |
413 | | if( libcnotify_verbose != 0 ) |
414 | | { |
415 | | libcnotify_printf( |
416 | | "%s: data:\n", |
417 | | function ); |
418 | | libcnotify_print_data( |
419 | | &( data[ value_data_offset ] ), |
420 | | (size_t) value_entry->data_size, |
421 | | 0 ); |
422 | | } |
423 | | #endif |
424 | 4.10k | } |
425 | | /* TODO trailing data */ |
426 | 21.0k | return( 1 ); |
427 | | |
428 | 0 | on_error: |
429 | 0 | if( value_entry->data != NULL ) |
430 | 0 | { |
431 | 0 | memory_free( |
432 | 0 | value_entry->data ); |
433 | |
|
434 | 0 | value_entry->data = NULL; |
435 | 0 | } |
436 | 0 | value_entry->data_size = 0; |
437 | |
|
438 | 0 | if( value_entry->name != NULL ) |
439 | 0 | { |
440 | 0 | memory_free( |
441 | 0 | value_entry->name ); |
442 | |
|
443 | 0 | value_entry->name = NULL; |
444 | 0 | } |
445 | 0 | value_entry->name_size = 0; |
446 | |
|
447 | 0 | return( -1 ); |
448 | 21.0k | } |
449 | | |
450 | | /* Retrieves the data size |
451 | | * Returns 1 if successful or -1 on error |
452 | | */ |
453 | | int libcreg_value_entry_get_data_size( |
454 | | libcreg_value_entry_t *value_entry, |
455 | | size_t *data_size, |
456 | | libcerror_error_t **error ) |
457 | 0 | { |
458 | 0 | static char *function = "libcreg_value_entry_get_data_size"; |
459 | |
|
460 | 0 | if( value_entry == NULL ) |
461 | 0 | { |
462 | 0 | libcerror_error_set( |
463 | 0 | error, |
464 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
465 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
466 | 0 | "%s: invalid value entry.", |
467 | 0 | function ); |
468 | |
|
469 | 0 | return( -1 ); |
470 | 0 | } |
471 | 0 | if( data_size == NULL ) |
472 | 0 | { |
473 | 0 | libcerror_error_set( |
474 | 0 | error, |
475 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
476 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
477 | 0 | "%s: invalid data size.", |
478 | 0 | function ); |
479 | |
|
480 | 0 | return( -1 ); |
481 | 0 | } |
482 | 0 | *data_size = (size_t) value_entry->data_size; |
483 | |
|
484 | 0 | return( 1 ); |
485 | 0 | } |
486 | | |
487 | | /* Retrieves the data |
488 | | * Returns 1 if successful or -1 on error |
489 | | */ |
490 | | int libcreg_value_entry_get_data( |
491 | | libcreg_value_entry_t *value_entry, |
492 | | uint8_t **data, |
493 | | size_t *data_size, |
494 | | libcerror_error_t **error ) |
495 | 0 | { |
496 | 0 | static char *function = "libcreg_value_entry_get_data"; |
497 | |
|
498 | 0 | if( value_entry == NULL ) |
499 | 0 | { |
500 | 0 | libcerror_error_set( |
501 | 0 | error, |
502 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
503 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
504 | 0 | "%s: invalid value entry.", |
505 | 0 | function ); |
506 | |
|
507 | 0 | return( -1 ); |
508 | 0 | } |
509 | 0 | if( data == NULL ) |
510 | 0 | { |
511 | 0 | libcerror_error_set( |
512 | 0 | error, |
513 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
514 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
515 | 0 | "%s: invalid data.", |
516 | 0 | function ); |
517 | |
|
518 | 0 | return( -1 ); |
519 | 0 | } |
520 | 0 | if( data_size == NULL ) |
521 | 0 | { |
522 | 0 | libcerror_error_set( |
523 | 0 | error, |
524 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
525 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
526 | 0 | "%s: invalid data size.", |
527 | 0 | function ); |
528 | |
|
529 | 0 | return( -1 ); |
530 | 0 | } |
531 | 0 | *data = value_entry->data; |
532 | 0 | *data_size = (size_t) value_entry->data_size; |
533 | |
|
534 | 0 | return( 1 ); |
535 | 0 | } |
536 | | |
537 | | /* Compares the value name with UTF-8 string |
538 | | * Returns 1 if the names match, 0 if not or -1 on error |
539 | | */ |
540 | | int libcreg_value_entry_compare_name_with_utf8_string( |
541 | | libcreg_value_entry_t *value_entry, |
542 | | uint32_t name_hash, |
543 | | const uint8_t *utf8_string, |
544 | | size_t utf8_string_length, |
545 | | int ascii_codepage, |
546 | | libcerror_error_t **error ) |
547 | 0 | { |
548 | 0 | static char *function = "libcreg_value_entry_compare_name_with_utf8_string"; |
549 | 0 | libuna_unicode_character_t name_character = 0; |
550 | 0 | libuna_unicode_character_t string_character = 0; |
551 | 0 | size_t name_index = 0; |
552 | 0 | size_t utf8_string_index = 0; |
553 | |
|
554 | 0 | if( value_entry == NULL ) |
555 | 0 | { |
556 | 0 | libcerror_error_set( |
557 | 0 | error, |
558 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
559 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
560 | 0 | "%s: invalid value entry.", |
561 | 0 | function ); |
562 | |
|
563 | 0 | return( -1 ); |
564 | 0 | } |
565 | 0 | if( value_entry->name == NULL ) |
566 | 0 | { |
567 | 0 | libcerror_error_set( |
568 | 0 | error, |
569 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
570 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
571 | 0 | "%s: invalid value entry - missing name.", |
572 | 0 | function ); |
573 | |
|
574 | 0 | return( -1 ); |
575 | 0 | } |
576 | 0 | if( utf8_string == NULL ) |
577 | 0 | { |
578 | 0 | libcerror_error_set( |
579 | 0 | error, |
580 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
581 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
582 | 0 | "%s: invalid UTF-8 string.", |
583 | 0 | function ); |
584 | |
|
585 | 0 | return( -1 ); |
586 | 0 | } |
587 | 0 | if( utf8_string_length > (size_t) SSIZE_MAX ) |
588 | 0 | { |
589 | 0 | libcerror_error_set( |
590 | 0 | error, |
591 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
592 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, |
593 | 0 | "%s: invalid UTF-8 string length value exceeds maximum.", |
594 | 0 | function ); |
595 | |
|
596 | 0 | return( -1 ); |
597 | 0 | } |
598 | | /* Do a full compare if there no name hash was provided or the name hash matches |
599 | | */ |
600 | 0 | if( ( name_hash == 0 ) |
601 | 0 | || ( value_entry->name_hash == 0 ) |
602 | 0 | || ( value_entry->name_hash == name_hash ) ) |
603 | 0 | { |
604 | 0 | while( name_index < (size_t) value_entry->name_size ) |
605 | 0 | { |
606 | 0 | if( utf8_string_index >= utf8_string_length ) |
607 | 0 | { |
608 | 0 | break; |
609 | 0 | } |
610 | 0 | if( libuna_unicode_character_copy_from_byte_stream( |
611 | 0 | &name_character, |
612 | 0 | value_entry->name, |
613 | 0 | (size_t) value_entry->name_size, |
614 | 0 | &name_index, |
615 | 0 | ascii_codepage, |
616 | 0 | error ) != 1 ) |
617 | 0 | { |
618 | 0 | libcerror_error_set( |
619 | 0 | error, |
620 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
621 | 0 | LIBCERROR_RUNTIME_ERROR_COPY_FAILED, |
622 | 0 | "%s: unable to copy value name to Unicode character.", |
623 | 0 | function ); |
624 | |
|
625 | 0 | return( -1 ); |
626 | 0 | } |
627 | 0 | if( libuna_unicode_character_copy_from_utf8( |
628 | 0 | &string_character, |
629 | 0 | utf8_string, |
630 | 0 | utf8_string_length, |
631 | 0 | &utf8_string_index, |
632 | 0 | error ) != 1 ) |
633 | 0 | { |
634 | 0 | libcerror_error_set( |
635 | 0 | error, |
636 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
637 | 0 | LIBCERROR_RUNTIME_ERROR_COPY_FAILED, |
638 | 0 | "%s: unable to copy UTF-8 string to Unicode character.", |
639 | 0 | function ); |
640 | |
|
641 | 0 | return( -1 ); |
642 | 0 | } |
643 | 0 | if( towupper( (wint_t) name_character ) != towupper( (wint_t) string_character ) ) |
644 | 0 | { |
645 | 0 | break; |
646 | 0 | } |
647 | 0 | } |
648 | 0 | if( ( name_index == (size_t) value_entry->name_size ) |
649 | 0 | && ( utf8_string_index == utf8_string_length ) ) |
650 | 0 | { |
651 | 0 | return( 1 ); |
652 | 0 | } |
653 | 0 | } |
654 | 0 | return( 0 ); |
655 | 0 | } |
656 | | |
657 | | /* Compares the value name with UTF-16 string |
658 | | * Returns 1 if the names match, 0 if not or -1 on error |
659 | | */ |
660 | | int libcreg_value_entry_compare_name_with_utf16_string( |
661 | | libcreg_value_entry_t *value_entry, |
662 | | uint32_t name_hash, |
663 | | const uint16_t *utf16_string, |
664 | | size_t utf16_string_length, |
665 | | int ascii_codepage, |
666 | | libcerror_error_t **error ) |
667 | 0 | { |
668 | 0 | static char *function = "libcreg_value_entry_compare_name_with_utf16_string"; |
669 | 0 | libuna_unicode_character_t name_character = 0; |
670 | 0 | libuna_unicode_character_t string_character = 0; |
671 | 0 | size_t name_index = 0; |
672 | 0 | size_t utf16_string_index = 0; |
673 | |
|
674 | 0 | if( value_entry == NULL ) |
675 | 0 | { |
676 | 0 | libcerror_error_set( |
677 | 0 | error, |
678 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
679 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
680 | 0 | "%s: invalid value entry.", |
681 | 0 | function ); |
682 | |
|
683 | 0 | return( -1 ); |
684 | 0 | } |
685 | 0 | if( value_entry->name == NULL ) |
686 | 0 | { |
687 | 0 | libcerror_error_set( |
688 | 0 | error, |
689 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
690 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
691 | 0 | "%s: invalid value entry - missing name.", |
692 | 0 | function ); |
693 | |
|
694 | 0 | return( -1 ); |
695 | 0 | } |
696 | 0 | if( utf16_string == NULL ) |
697 | 0 | { |
698 | 0 | libcerror_error_set( |
699 | 0 | error, |
700 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
701 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
702 | 0 | "%s: invalid UTF-16 string.", |
703 | 0 | function ); |
704 | |
|
705 | 0 | return( -1 ); |
706 | 0 | } |
707 | 0 | if( utf16_string_length > (size_t) SSIZE_MAX ) |
708 | 0 | { |
709 | 0 | libcerror_error_set( |
710 | 0 | error, |
711 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
712 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, |
713 | 0 | "%s: invalid UTF-16 string length value exceeds maximum.", |
714 | 0 | function ); |
715 | |
|
716 | 0 | return( -1 ); |
717 | 0 | } |
718 | | /* Do a full compare if there no name hash was provided or the name hash matches |
719 | | */ |
720 | 0 | if( ( name_hash == 0 ) |
721 | 0 | || ( value_entry->name_hash == 0 ) |
722 | 0 | || ( value_entry->name_hash == name_hash ) ) |
723 | 0 | { |
724 | 0 | while( name_index < (size_t) value_entry->name_size ) |
725 | 0 | { |
726 | 0 | if( utf16_string_index >= utf16_string_length ) |
727 | 0 | { |
728 | 0 | break; |
729 | 0 | } |
730 | 0 | if( libuna_unicode_character_copy_from_byte_stream( |
731 | 0 | &name_character, |
732 | 0 | value_entry->name, |
733 | 0 | (size_t) value_entry->name_size, |
734 | 0 | &name_index, |
735 | 0 | ascii_codepage, |
736 | 0 | error ) != 1 ) |
737 | 0 | { |
738 | 0 | libcerror_error_set( |
739 | 0 | error, |
740 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
741 | 0 | LIBCERROR_RUNTIME_ERROR_COPY_FAILED, |
742 | 0 | "%s: unable to copy value name to Unicode character.", |
743 | 0 | function ); |
744 | |
|
745 | 0 | return( -1 ); |
746 | 0 | } |
747 | 0 | if( libuna_unicode_character_copy_from_utf16( |
748 | 0 | &string_character, |
749 | 0 | utf16_string, |
750 | 0 | utf16_string_length, |
751 | 0 | &utf16_string_index, |
752 | 0 | error ) != 1 ) |
753 | 0 | { |
754 | 0 | libcerror_error_set( |
755 | 0 | error, |
756 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
757 | 0 | LIBCERROR_RUNTIME_ERROR_COPY_FAILED, |
758 | 0 | "%s: unable to copy UTF-16 string to Unicode character.", |
759 | 0 | function ); |
760 | |
|
761 | 0 | return( -1 ); |
762 | 0 | } |
763 | 0 | if( towupper( (wint_t) name_character ) != towupper( (wint_t) string_character ) ) |
764 | 0 | { |
765 | 0 | break; |
766 | 0 | } |
767 | 0 | } |
768 | 0 | if( ( name_index == (size_t) value_entry->name_size ) |
769 | 0 | && ( utf16_string_index == utf16_string_length ) ) |
770 | 0 | { |
771 | 0 | return( 1 ); |
772 | 0 | } |
773 | 0 | } |
774 | 0 | return( 0 ); |
775 | 0 | } |
776 | | |